Tutorial: Create a Campaign

In Pulse, a campaign is the general component for which you set specific goals that need to be realised in a given period of time. Each campaign consists of goals, and each goal consists of ads, to which you upload assets. Creating a complete campaign requires adding at least one goal in a campaign, and one ad in a goal. This is an example of a campaign structure:

Pulse Campaign structure

In order to launch a campaign, you need to use the different Campaign Management APIs described below, which have different base URLs and communication formats, as noted in each step.

Step 1: Create a Campaign

To create a campaign, you need to supply a body to the request with the following format:
Note: Only the name parameter is required. All other parameters are optional.
<campaignBean>
    <advertiserId>string</advertiserId>    <!-- (Required) -->
    <agencyId>string</agencyId>
    <brandId>string</brandId>
    <budget>
        <value>number</value>
    </budget>
     <!-- <cpmHigh> (Setting this value is ignored)
        <value>number</value>
    </cpmHigh> -->
   <!-- <cpmLow> (Setting this value is ignored) 
        <value>number</value>
    </cpmLow> -->
    <customId>string</customId>
    <description>string</description>
    <enabled>boolean</enabled>    <!-- (Defaults to false) -->
    <!-- <end>2016-10-26T08:36:28</end> (Setting this value is ignored) -->
    <exclusive>boolean</exclusive>    <!-- (Defaults to false) -->
    <frontLoadFactor>0|10|20|30|40|50|60|70|80|90|100</frontLoadFactor>    <!-- (Defaults to match the global frontload setting) -->
    <goalTotal>number</goalTotal>
    <goalType>IMPRESSION|MIXED|SHARE_OF_VOICE</goalType>
    <id>string</id>    <!-- (Set only when updating a campaign) -->
    <includeInForecast>boolean</includeInForecast>    <!-- (Defaults to true) -->
    <name>string</name>    <!-- (Required, use up to 250 characters) -->
    <priority>integer</priority>    <!-- (1-10; defaults to match the global priority setting) -->
    <!-- <start>2016-10-01T06:36:46+01:00</start> (Setting this value is ignored) -->
    <status>ACTIVE|RECENT|UPCOMING|ARCHIVED</status>    <!-- (The only valid value that can be set is ARCHIVED) -->
    <vastEnabled>boolean</vastEnabled>    <!-- (Defaults to false) -->
</campaignBean>
Method POST
URL https://api.videoplaza.com/api/1.0/campaign
Header Authentication header (x-o-api-key)
Content type application/xml
Matrix params -
Query params -
Body Request Body Format
Success response

HTTP status: 200 OK

Header: -

Body: campaign ID

Example:

Request header:

POST /api/1.0/campaign HTTP/1.1
Host: api.videoplaza.com
Content-type: application/xml
x-o-api-key="<your key>"

Request body:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<campaignBean>
    <advertiserId>2c3364bb-5fb6-4bab-b327-ecaddc08a0ae</advertiserId>
    <description>API test campaign</description>
    <enabled>true</enabled>
    <exclusive>false</exclusive>
    <frontLoadFactor>40</frontLoadFactor>
    <includeInForecast>true</includeInForecast>
    <name>Pulse Test Campaign</name>
    <priority>3</priority>
    <vastEnabled>true</vastEnabled>
</campaignBean>

Success response:

HTTP status:
  200 (OK)

Body:
62287794-4458-4ff4-b062-80caeee130c6

Step 2: Create a Goal

Note: There are two available endpoints for creating goals, depending on which goal types you use. This example covers creating all existing goal types using the https://api.videoplaza.com/api/1.0.cpvext/goal. For more information, see Goal Requests.
To create a goal, you need to supply a body to the request with the following format:
Note: All parameters are optional unless explicitly stated.
<goalBean>
    <pricingModel>NO_PRICING|BUDGET|CPM|CPMV_25|CPMV_50|CPMV_75|CPMV_100|CPC</pricingModel>  <!-- See below for more information -->
    <pricingValue>
        <value>number</value>
    </pricingValue>
    <campaignId>string</campaignId>    <!-- Required -->
    <!-- <cpm> (Setting this value is ignored)
        <value>number</value>
    </cpm> -->
    <customId>string</customId>
    <description>string</description>
    <end>2016-09-29T03:49:45</end>    <!-- End date and time must be after start date and time -->
    <frontLoadFactor>0|10|20|30|40|50|60|70|80|90|100</frontLoadFactor>    <!-- Defaults to match the global frontload setting or the campaign frontload setting if it overrides the global one -->
    <goalValue>number</goalValue>  <!-- Required; see below for more information -->
    <caps> 
        <cap>
            <type>totalCap|dailyCap|hourlyCap|dailyEventCap|hourlyEventCap</type>    <!-- See below for more information -->
            <value>number</value>
        </cap>
    </caps>
    <midrollBreakTargeting>    <!–- You can pass in a maximum of ten mid-roll break numbers; see below for more information –-!>
        <midrollBreakNumber>positive integer</midrollBreakNumber>
        <midrollBreakNumber>positive integer</midrollBreakNumber>
    </midrollBreakTargeting>
    <id>string</id>    <!-- This should only be set when updating a goal -->
    <name>string</name>    <!-- Use up to 255 characters -->
    <priority>integer</priority>    <!-- 1-10; defaults to match the global priority setting or the campaign priority setting if it overrides the global one -->
    <start>2016-09-01T19:44:14</start>   <!-- Required; start date and time cannot be in the past and if you pass in a past date and time, it gets set to the date and time of creation -->
    <type>SHARE_OF_VOICE|IMPRESSION|UNLIMITED_IMPRESSION|RTB|FIRST_QUARTILE|SECOND_QUARTILE|THIRD_QUARTILE|COMPLETE|CLICK_THROUGH</type>  <!-- Required; see below for more information -->
    <unlimitedImpressions>boolean</unlimitedImpressions>
    <variant>NORMAL|BUMPER</variant>    <!-- Required, "BUMPER" corresponds to sponsor goal mode in the Pulse UI --> 
</goalBean>
  • The pricing models CPMV_25, CPMV_50, CPMV_75, and CPMV_100 correspond to the following Pulse UI pricing options:
    • CPMV_25: CPM 25% Ad Completion
    • CPMV_50: CPM 50% Ad Completion
    • CPMV_75: CPM 75% Ad Completion
    • CPMV_100: CPM 100% Ad Completion
  • Setting the goalValue parameter for UNLIMITED_IMPRESSION and RTB goals is ignored. Valid values for goal types:
    • SHARE_OF_VOICE: 0.01-1.0
    • IMPRESSION|FIRST_QUARTILE|SECOND_QUARTILE|THIRD_QUARTILE|COMPLETE|CLICK_THROUGH: any positive number
  • You can combine the different impression and event (% ad completion or click through) caps where applicable. For more information, see Daily and Hourly Goal Caps vs Pulse Dynamic Design. The valid cap types for different goals are:
    • totalCap: total impression cap, available for SHARE_OF_VOICE, FIRST_QUARTILE, SECOND_QUARTILE, THIRD_QUARTILE, COMPLETE, and CLICK_THROUGH goals
    • dailyCap: daily impression cap, available for IMPRESSION, SHARE_OF_VOICE, UNLIMITED_IMPRESSION, and RTB goals
    • hourlyCap: hourly impression cap, available for IMPRESSION, SHARE_OF_VOICE, UNLIMITED_IMPRESSION, and RTB goals
    • dailyEventCap: daily 25%, 50%, 75%, or 100% ad completion or click through cap, available for FIRST_QUARTILE, SECOND_QUARTILE, THIRD_QUARTILE, COMPLETE, and CLICK_THROUGH goals
    • hourlyEventCap: hourly 25%, 50%, 75%, or 100% ad completion or click through cap, available for FIRST_QUARTILE, SECOND_QUARTILE, THIRD_QUARTILE, COMPLETE, and CLICK_THROUGH goals
  • Use mid-roll break targeting to target the mid-roll ads from the goal to one or more specific mid-roll ad breaks. You can pass in a maximum of ten mid-roll break numbers, where 1 marks the first mid-roll ad break. For more information, see Mid-roll Break Targeting.
  • The types FIRST_QUARTILE, SECOND_QUARTILE, THIRD_QUARTILE, and COMPLETE correspond to the following Pulse UI goal types:
    • FIRST_QUARTILE: 25% Ad Completion
    • SECOND_QUARTILE: 50% Ad Completion
    • THIRD_QUARTILE: 75% Ad Completion
    • COMPLETE: 100% Ad Completion
Method POST
URL https://api.videoplaza.com/api/1.0.cpvext/goal
Header Authentication header (x-o-api-key)
Content type application/xml
Matrix params -
Query params -
Body Request Body Format
Success response

HTTP status: 200 OK

Header: -

Body: goal ID

Example:

Request header:

POST /api/1.0.cpvext/goal HTTP/1.1
Host: api.videoplaza.com
Content-­type: application/xml
x-o-api-key="<your key>"

Request body:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<goalBean>
        <campaignId>62287794-4458-4ff4-b062-80caeee130c6</campaignId>
        <description>API test goal.</description>
        <end>2017-07-10T00:00:00+02:00</end>
        <formatType>MIDROLL</formatType>
        <goalValue>12000.0</goalValue>
        <name>Test Goal</name>
        <pricingModel>CPM</pricingModel>
        <pricingValue>
            <value>15.0</value>
        </pricingValue>
        <start>2017-07-03T00:00:00+02:00</start>
        <type>IMPRESSION</type>
        <unlimitedImpressions>false</unlimitedImpressions>
        <variant>NORMAL</variant>
    </goalBean>

Success response:

HTTP status:
  200 (OK)

Body:
a7b037d4-55da-4923-8049-be36c604c59e

Step 3: Upload a Video Asset

Note: You cannot upload pre-transcoded assets through the API, which is possible if you upload them through Pulse.
You can upload video assets by providing, in the request body, either:
  • a URL to the video asset (covered in the following example)
  • the video asset itself as an octet-stream.
For more information, see Asset API.

Uploaded video assets are only transcoded after they have been associated with at least one ad, as explained in Step 4: Create an Ad. For assets uploaded through a URL, the download needs to be successful as well in order for the transcoding to happen. The progress of transcoding can be followed in the asset factory in Pulse.

Note: Uploaded assets that have not been linked to an ad expire after 24 hours. Querying for expired assets returns a 404 (Not found) error.

Upload a video asset by providing a URL

Method POST
URL https://api.videoplaza.com/v1/assets/video
Header Authentication header (x-o-api-key)
Content type application/json
URL params -
Query params -
Body
{
  "name":"<string>",
  "downloadUri":"<string>"
}
Note: The name parameter in the body needs to contain the correct file extension for the asset.
Success response

HTTP status: 201 Created

Header: Location: URI to the location of your asset

Body: -

Example:

Request header:

POST v1/assets/video HTTP/1.1
Host: api.videoplaza.com
Content-type: application/json
x-o-api-key="<your key>"

Request body:

{
  "name":"videoname.mp4",
  "downloadUri":"http://example.com/video/1234"
}

Success response:

HTTP status:
  201 (Created)

Header:
  Location: <URI with the location of your asset>

Step 4: Create an Ad

Note: Uploaded assets that have not been linked to an ad expire after 24 hours. Querying for expired assets returns a 404 (Not found) error.
To create an ad, you need to supply a body to the request with the following format:
Note: All parameters are optional unless explicitly stated.
{
  "id": "<string>", (id of the ad, required only for the update request)
  "name": "<string>", (Required, use up to 250 characters)
  "goalId": "<string>", (Required, valid goal UUID)
  "customId": "<string>",
  "description": "<string>",
  "enabled": "<boolean>", (Defaults to false)
  "weight": "<number from 0.01 to 100>", (Defaults to proportional split between ads in a goal, see below for more information)
  "creative": { (Required, fields under the creative field depend on the type of creative)
    "type": "standard", (Required)
    "insertionPoint": "<preroll|midroll|postroll>", (Required)
    "assetId": "<string>", (Required, file ID from /v1/assets)
    "clickDestinationUri": "<string>"
  },
  "start": "<ISO-8601 formatted date-time string>", (Inherits from goal if not supplied; ad start date and time cannot be before goal start date and time)
  "end": "<ISO-8601 formatted date-time string>", (Inherits from goal if not supplied; ad end date and time cannot be after goal end date and time)
  "externalTrackers": [ (You can provide multiple external trackers for an ad)
    {
      "url": "<string>",
      "event" : "<string>"
    },
    {
      "url": "<string>",
      "event" : "<string>"
    }
  ],
  "deviceContainers": [ (Valid device container UUID, defaults to all available device containers. You can target multiple device containers.)
    "string",
    "string"
  ]
}

Ad Weight

Ad weight is used to choose how often to pick a specific ad after the goal has already been picked. Weight is applied within individual ad formats on a single goal. Ads have two kinds of weights: explicit weights and proportional split (no weight set). If there are multiple ads of the same ad format in one goal, they take an even share of the impressions by default, meaning they split the weight proportionally and have an equal chance of getting selected. If you assign an explicit weight to one of the ads because it needs to run more frequently, then that ad has a better chance of getting selected.

All ads with proportional split share the remaining weight (100% - explicit weights). This means that explicitly setting the weight of an ad affects the weight of other ads that have proportional split.

Example: You have 2 pre-roll ads with no weight set. You add a third pre-roll ad with weight 50%. The two previously added ads will now have 25% weight each (they automatically split the remaining 50%).

Creative Types

We currently support the following creative types:
  • Standard spot ads (pre-, mid-, and post-rolls): pass in the type of ad, the insertion point, and the asset id:
    "creative": {
      "type": "standard",
      "insertionPoint": "<preroll|midroll|postroll>",
      "assetId": "<string>",
      "clickDestionationUri": "<string>" (Optional, to set the clickthrough URI)
    }
  • Pause ads: pass in the type of ad and the asset id:
    "creative": {
      "type": "pause",
      "assetId": "<string>",
      "clickDestionationUri": "<string>" (Optional, to set the clickthrough URI)
    }
  • IPTV ads: pass in the type of ad, the insertion point, and the video creative ID:
    "creative": {
      "type": "iptv",
      "insertionPoint": "<preroll|midroll|postroll>",
      "videoCreativeId": "<string>",
      "clickDestionationUri": "<string>", (Optional, to set the clickthrough URI)
      "estimatedAdDuration": "<positive integer from 1 to 9999>"  (Optional, duration of the IPTV ad in seconds) 
    }
    Note: If you are using Time Based Breaks, you have to estimate the duration of the IPTV ad. If the ad does not have an estimated duration, or exceeds the time based break duration, it will not get selected.
  • Standard third-party ads: the asset is not stored in Pulse, so you need to provide a URI for the location of the VAST ticket:
    "creative": {
      "type": "thirdparty",
      "insertionPoint": "<preroll|midroll|postroll>",
      "vastUri": "<string>",
      "vpaidStrict": "<boolean>", (Optional, indicates the allowed behaviour of VPAID ads. Set to true to allow only linear ads, or  set to false to allow non-linear ads as well)
      "vpaidCountdown": "<boolean>", (Optional, indicates if you want the standard Pulse countdown text visible on the third-party VPAID ad)
      "estimatedAdDuration": "<positive integer from 1 to 9999>"  (Optional, duration of the third-party ad in seconds) 
    }
    Note: If you are using Time Based Breaks, you have to estimate the duration of the third-party ad. If the ad does not have an estimated duration, or exceeds the time based break duration, it will not get selected.
  • Generic placeholder ads, where you do not specify the type of ad yet:
    "creative": {
      "type": "placeholder"
    }
  • Standard spot placeholder ads (pre-, mid-, and post-rolls): pass in the type of insertion point, but you pass in the asset later:
    "creative": {
      "type": "spotPlaceholder",
      "insertionPoint": "<preroll|midroll|postroll>",
      "clickDestionationUri": "<string>" (Optional, to set the clickthrough URI)
    }
  • Pause placeholder ads, where you specify the type of placeholder ad, but you pass in the asset later:
    "creative": {
      "type": "pausePlaceholder",
      "clickDestionationUri": "<string>" (Optional, to set the clickthrough URI)
    }
  • IPTV placeholder ads: pass in the type of insertion point, but you pass in the video creative ID later:
    "creative": {
      "type": "iptvPlaceholder",
      "insertionPoint": "<preroll|midroll|postroll>",
      "clickDestionationUri": "<string>" (Optional, to set the clickthrough URI)
    }

External Tracking

Ads can have multiple external trackers. The following tracking events are available:

IMPRESSION, CLICK_THROUGH, AD_START, AD_FIRST_QUARTILE, AD_MIDPOINT, AD_THIRD_QUARTILE, AD_COMPLETE, CLOSE, MUTE, UNMUTE, PAUSE, RESUME, REWIND, FULLSCREEN, EXPAND
Method POST
URL https://api.videoplaza.com/v1/ads
Header Authentication header (x-o-api-key)
Content type application/json
URL params -
Query params -
Body Request Body Format
Success response

HTTP status: 201 Created

Header: Location: URI to the location of the ad

Body: ad object including the ad ID

Example: Create a mid-roll ad

Request header:

POST /v1/ads HTTP/1.1
Host: api.videoplaza.com
Content-type: application/json
x-o-api-key="<your key>"

Request body:

{
  "name": "Test mid-roll ad with asset",
  "goalId": "a7b037d4-55da-4923-8049-be36c604c59e",
  "description": "Test mid-roll ad.",
  "enabled": "true",
  "creative": {
    "type": "standard",
    "insertionPoint": "midroll",
    "assetId": "6186353d-6aca-4eca-9a2b-6935d406f29a",
    "clickDestinationUri": "http://example.com"
  },
  "start": "2017-07-03T00:00:00+02:00",
  "end": "2017-07-10T00:00:00+02:00",
  "weight": 50,
  "externalTrackers": [
    {
      "url": "http://externaltracker.com",
      "event": "IMPRESSION"
    }
  ],
  "deviceContainers": [
    "6b79564c-8a8c-102f-9f01-001e4f3cd645",
    "86d28d24-d025-4633-a081-bea93de04dc3",
    "27375d12-e3ad-46ce-ad78-eece92928c90",
    "a6b5b571-c517-4597-861b-24d2d190d642",
    "145299c6-ba02-45de-9995-c2dfaba44c8c"
  ]
}

Success response:

HTTP status:
  201 (Created)

Header:
  Location: <URI to the location of the ad>

Body:
{
    "id": "0fb4dbdb-d90e-4109-b5ec-20c4f5beb156",
    "name": "Test mid-roll ad with asset",
    "goalId": "a7b037d4-55da-4923-8049-be36c604c59e",
    "description": "Test mid-roll ad.",
    "enabled": true,
    "creative": {
        "type": "standard",
        "insertionPoint": "midroll",
        "assetId": "6186353d-6aca-4eca-9a2b-6935d406f29a",
        "clickDestinationUri": "http://example.com"
    },
    "start": "2017-07-02T22:00:00Z",
    "end": "2017-07-09T22:00:00Z",
    "weight": 50,
    "externalTrackers": [
        {
            "url": "http://externaltracker.com",
            "event": "IMPRESSION"
        }
    ],
    "deviceContainers": [
        "145299c6-ba02-45de-9995-c2dfaba44c8c",
        "27375d12-e3ad-46ce-ad78-eece92928c90",
        "6b79564c-8a8c-102f-9f01-001e4f3cd645",
        "a6b5b571-c517-4597-861b-24d2d190d642",
        "86d28d24-d025-4633-a081-bea93de04dc3"
    ]
}

Result

After following these 4 steps, you have successfully booked and enabled a campaign with one goal and one active ad, as seen in the Pulse UI:

Campaign result in Pulse UI