support Contact Support | system status System Status

Brightcove Live API: Server-Side Ad Insertion (SSAI)

This topic shows you how to set up server-side ad insertion (SSAI) for your live stream jobs.

Overview

SSAI allows you display ads during a live streaming event at specified times. The main features include:

  • Insert ads using cue points sent from your encoder or create an instant cue point using the Live API
  • Ingest "slate" assets to fill any unused ad time
  • Avoid ad blockers with ads that are stitched into the live stream on the server side

To create a Live stream with server-side ads, follow these steps:

  1. Review the general information about the Live API
  2. Create a live ad configuration. You can also do this in Video Cloud Studio. See the sections below for details about managing your ad configurations using the Live API.
  3. Create slate assets. If you prefer a UI, you can manage slates in Studio.
  4. Optional: Insert cue points and ad beacons.
  5. Now, you are ready to create a live stream using the Live API. If you prefer to use Studio, you can implement server-side ads in the Live module

See the rest of this document for details about custom headers, ad config variables, using DFP and ad macros.

General information

The following information pertains to all Live API with SSAI requests.

Base URL

The base URL for the Live API with SSAI is:

    https://api.bcovlive.io/v1/ssai

Authentication

Authentication for requests requires a header with an API key:

    X-API-KEY: your API KEY
    

Contact your account manager to get an API key associated with your account.

Create an ad configuration

To create a new ad configuration, send a POST request as follows:

Method POST
URL https://api.bcovlive.io/v1/ssai/applications
Header X-API-KEY: your API KEY

Sample request body

    {
      "application_ad_configuration": {
        "ad_configuration_description": "Human readable description of the configuration",
        "ad_configuration_expected_response_type": "Dfp, Vast or SmartXML",
        "ad_configuration_headers": {
        "X-Custom-Header-Rand": "{{random.int32}}",
        "X-VIDEOPLAZA-FORWARDED-FOR": "{{client.ipaddress}}"
        },
        "ad_configuration_headers_for_impressions": false,
        "ad_configuration_strategy": "SingleAdResponse or MultipleAdResponse",
        "ad_configuration_transforms": [
          {
          "xpath": "/",
          "xslt": "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:Det=\"http://Det.com\"><xsl:output omit-xml-declaration=\"yes\"/><xsl:template match=\"node()|@*\"><xsl:copy><xsl:apply-templates select=\"node()|@*\"/></xsl:copy></xsl:template></xsl:stylesheet>"
          }
        ],
        "ad_configuration_url_format": "https://ad-provider-host.com/path/to/ad-handler?ip={{client.ipaddress}}&num={{random.int32}}&ses={{session.session_id}}"
      },
      "application_description": "Human readable description of the ad application",
      "account_id": "User's Account ID [Optional]"
    }

Sample response

    {
      "application": {
        "account_id": "User Account ID",
        "application_description": "Human readable description of the ad application",
        "application_ad_configuration": {
          "ad_configuration_description": "Human readable description of the configuration",
          "ad_configuration_expected_response_type": "Dfp | Vast | SmartXML",
          "ad_configuration_headers": {
            "X-Custom-Header-Rand": "{{random.int32}}",
            "X-VIDEOPLAZA-FORWARDED-FOR": "{{client.ipaddress}}"
          },
          "ad_configuration_headers_for_impressions": false,
          "ad_configuration_strategy": "SingleAdResponse | MultipleAdResponse",
          "ad_configuration_transforms": [
            {
              "xpath": "/",
              "xslt": "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:Det=\"http://Det.com\"><xsl:output omit-xml-declaration=\"yes\"/><xsl:template match=\"node()|@*\"><xsl:copy><xsl:apply-templates select=\"node()|@*\"/></xsl:copy></xsl:template></xsl:stylesheet>"
            }
          ],
          "ad_configuration_url_format": "https://ad-provider-host.com/path/to/ad-handler?ip={{client.ipaddress}}&num={{random.int32}}&ses={{session.session_id}}"
        },
        "application_id": "Application ID"
      },
      "inserted": true
    }

Update an ad configuration

Updating an ad configuration is very similar to creating one. Make a PUT request as follows:

Method PUT
URL https://api.bcovlive.io/v1/ssai/applications/application/Application_ID
Header X-API-KEY: your API KEY

Sample request body

    {
      "application_ad_configuration": {
        "ad_configuration_description": "Some Updated Description Value",
        "ad_configuration_expected_response_type": "Dfp or Vast or SmartXML,
        "ad_configuration_headers": {
          "X-Custom-Header-Rand": "{{random.int32}}",
          "X-VIDEOPLAZA-FORWARDED-FOR": "{{client.ipaddress}}"
        },
        "ad_configuration_headers_for_impressions": false,
        "ad_configuration_strategy": "SingleAdResponse or MultipleAdResponse",
        "ad_configuration_transforms": [
          {
          "xpath": "/",
          "xslt": "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:Det=\"http://Det.com\"><xsl:output omit-xml-declaration=\"yes\"/><xsl:template match=\"node()|@*\"><xsl:copy><xsl:apply-templates select=\"node()|@*\"/></xsl:copy></xsl:template></xsl:stylesheet>"
          }
        ],
        "ad_configuration_url_format": "https://updated-ad-provider-host.com/path/to/ad-handler?ip={{client.ipaddress}}&num={{random.int32}}&ses={{session.session_id}}"
      },
      "application_description": "Human readable description of the ad application",
      "account_id": "User's Account ID [Optional]"
    }

Sample response

    {
      "account_id": "User Account ID",
      "application_description": "Human readable description of the ad application",
      "application_ad_configuration": {
        "ad_configuration_description": "Some Updated Description Value",
        "ad_configuration_expected_response_type": "Dfp | Vast | SmartXML",
        "ad_configuration_headers": {
        "X-Custom-Header-Rand": "{{random.int32}}",
        "X-VIDEOPLAZA-FORWARDED-FOR": "{{client.ipaddress}}"
        },
        "ad_configuration_headers_for_impressions": false,
        "ad_configuration_strategy": "SingleAdResponse | MultipleAdResponse",
        "ad_configuration_transforms": [
          {
          "xpath": "/",
          "xslt": "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:Det=\"http://Det.com\"><xsl:output omit-xml-declaration=\"yes\"/><xsl:template match=\"node()|@*\"><xsl:copy><xsl:apply-templates select=\"node()|@*\"/></xsl:copy></xsl:template></xsl:stylesheet>"
          }
        ],
        "ad_configuration_url_format": "https://updated-ad-provider-host.com/path/to/ad-handler?ip={{client.ipaddress}}&num={{random.int32}}&ses={{session.session_id}}"
      },
      "application_id": "Application ID"
    }

Get all ad configurations

To retrieve all the ad configurations for an account, submit a GET request as follows:

Method GET
URL https://api.bcovlive.io/v1/ssai/applications/account/Account_ID
Header X-API-KEY: your API KEY

Sample response

    [
      {
        "application_id": "Application_ID_1",
        "application_description": "DFP Single Midroll",
        "application_ad_configuration": {
        "ad_configuration_description": "DFP Test Config Single Midroll",
        "ad_configuration_strategy": "MultipleAdResponse",
        "ad_configuration_transforms": [],
        "ad_configuration_url_format": "https://ad-provider-host.com/path/to/ad-handler",
        "ad_configuration_expected_response_type": "Dfp"
        },
        "account_id": "Account_ID"
      },
      {
        "application_id": "Application_ID_2",
        "application_description": "Test DFP Single Midroll"
        "application_ad_configuration": {
        "ad_configuration_description": "DFP Test Config Single Midroll",
        "ad_configuration_strategy": "MultipleAdResponse",
        "ad_configuration_transforms": [
        {
          "xslt": "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:Det=\"http://Det.com\"><xsl:output omit-xml-declaration=\"yes\"/><xsl:template match=\"node()|@*\"><xsl:copy><xsl:apply-templates select=\"node()|@*\"/></xsl:copy></xsl:template></xsl:stylesheet>",
          "xpath": "/"
        }
        ],
        "ad_configuration_url_format": "https://ad-provider-host.com/path/to/ad-handler?ip={{client.ipaddress}}&num={{random.int32}}&ses={{session.session_id}}",
        "ad_configuration_expected_response_type": "Dfp"
        },
        "account_id": "Account_ID"
      }
    ]

Get an ad configuration

You can also retrieve a specific ad configuration by its application_id by sending a GET request as follows:

Method GET
URL https://api.bcovlive.io/v1/ssai/applications/application/Application_ID
Header X-API-KEY: your API KEY

Sample response

    {
      "application_id": "Application_ID",
      "application_description": "Test DFP Single Midroll",
      "application_ad_configuration": {
        "ad_configuration_description": "DFP Test Config Single Midroll",
        "ad_configuration_strategy": "MultipleAdResponse",
        "ad_configuration_transforms": [
          {
          "xslt": "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:Det=\"http://Det.com\"><xsl:output omit-xml-declaration=\"yes\"/><xsl:template match=\"node()|@*\"><xsl:copy><xsl:apply-templates select=\"node()|@*\"/></xsl:copy></xsl:template></xsl:stylesheet>",
          "xpath": "/"
          }
        ],
        "ad_configuration_url_format": "https://ad-provider-host.com/path/to/ad-handler?ip={{client.ipaddress}}&num={{random.int32}}&ses={{session.session_id}}",
        "ad_configuration_expected_response_type": "Dfp"
      },
      "account_id": "Account_ID"
    }

Delete an ad configuration

To delete an ad configuration, send a DELETE request as follows:

Method DELETE
URL https://api.bcovlive.io/v1/ssai/applications/application/APPLICATION_ID
Header X-API-KEY: your API KEY

Sample response

    {
    "application_id": "Application_ID",
    "deleted": true
    }

Managing slates

Slates are your own assets used to fill unused ad time. You can use slates to provide a "be right back" message or any content that you like.

Below are details for the API requests to add and manage slate assets.

Add slate asset

To ingest a new slate media source asset, submit a POST request:

Method POST
URL https://api.bcovlive.io/v1/ssai/slates
Header X-API-KEY: your API KEY

Sample request body

    {
      "source_url": "https://somesourceasset.com/slate-to-ingest.mp4",
      "account_id": "Account_ID [Optional]",
      "source_description": "User identifiable description for the slate  [Optional]"
    }
    
    

Sample response

    {
      "media_source_asset_id": "New_UUID",
      "account_id": "Account_ID",
      "media_source_asset_default": false,
      "media_source_asset_type": "slate",
      "media_source_asset_url": "https://somesourceasset.com/slate-to-ingest.mp4",
      "media_source_asset_status": "transcoding"
      "media_source_asset_description": "User identifiable description for the slate"
    }

Delete slate asset

To delete a slate media source asset, send a DELETE request:

Method DELETE
URL https://api.bcovlive.io/v1/ssai/slates/slate/Slate_MSA_ID
Header X-API-KEY: your API KEY

Sample response

    {
      "media_source_asset_id": "MSA_UUID",
      "media_source_asset_type": "slate",
      "media_source_asset_url": "http://someS3urlpath/media.mp4",
      "media_source_asset_default": false,
      "media_source_asset_status": "ready",
      "account_id": "ACCOUNT_ID"
    }

Get slate assets

You can retrieve an array of all the slate media source assets for an account by sending a GET request:

Method GET
URL https://api.bcovlive.io/v1/ssai/slates/account/Account_ID
Header X-API-KEY: your API KEY

Sample response

    [
      {
      "media_source_asset_id": "MSA_UUID_1",
      "media_source_asset_type": "slate",
      "media_source_asset_default": false,
      "media_source_asset_url": "http://someS3urlpath.com/media.mp4",
      "account_id": "ACCOUNT_ID",
      "media_source_asset_status": "ready"
      },
      {
      "media_source_asset_id": "MSA_UUID_2",
      "media_source_asset_type": "slate",
      "media_source_asset_default": true,
      "media_source_asset_url": "http://someS3urlpath.com/media.mp4",
      "account_id": "ACCOUNT_ID",
      "media_source_asset_status": "ready"
      }
    ]

Notes about DFP

If you are obtaining ads from DFP, here are some things to keep in mind to help prevent issues.

Ad tag

When you are creating an ad tag for Live, be sure you are following the proper guidelines and including /live . See the DFP document Create a master video tag manually for full details.

Concurrency

If you are expecting a high amount of concurrency we recommended that you talk to your DFP account team.

Single/multiple ad responses

The singleadresponse and multiadresponse parameters are not currently used by SSAI.

Live SSAI only makes a single ad server call and expects the response to contain all the ads for the break with the exception that it will follow any necessary ad wrappers with a limit of 5 redirects per ad. The following ad response formats are accepted and will be parsed as follows:

  • VAST - Single response or a pod of ads in a single response
  • DFP Ad Rules - Aggregates all available ads in the response including pre-, mid-, post-roll defined ads
  • Smart XML - Aggregates all available ads in the response including pre-, mid-, post-roll defined ads

Custom headers for ad requests

The SSAI platform can pass custom headers with the Ad calls and all beacons used by the backend platform. Some ad servers such as VideoPlaza require custom headers.

Custom headers are specified as a set of key-value pairs in an ad_configuration_headers object, which is part of the application_ad_configuration (see the Create an ad configuration section).

Notes

  • Standard headers are handled by default such as:
    • X-Forwarded-For
    • X-Device-User-Agent
  • Header values can use the ad configuration variables
  • Header values can also be static strings

Targeting ads using ad macros

When you create an ad configuration, your ad tag will typically look something like this:

      https://ad-provider-host.com/path/to/ad-handler?ip={{client.ipaddress}}&
      num={{random.int32}}&ses={{session.session_id}}&IDFA={{deviceid}}&
      sitesection={{sitesection}}&breakid={{breakid}}&breaktheme={{breaktheme}}

The items inside the double curly braces are variables, also called ad macros, which Brightcove Live will replace with values, if they exist, when it sends the ad request.

Ad macro values can be supplied in following ways:

Using header information

Header information, detailed in the Ad configuration variables section above, is available for any request. Simply specify the variables you want with the appropriate key names in your ad configuration.

Appending the URL

Additional session values can be appended to the URL for the live stream, like this:

      http://playback.bcovlive.io/e058d9f2737e18/us-west-2/NA/
      playlist.m3u8?deviceid=123456&sitesection=services"

Adding URLs dynamically

You can add URLs dynamically, using Javascript and the Brightcove Player API:

      <!DOCTYPE html>
      <body>
        <video
        id="myPlayerID"
        data-video-id="5975635167001"
        data-account="3737230870001"
        data-player="tIG7lVKBm"
        data-embed="default"
        data-application-id
        class="video-js"
        controls
        width="640"
        height="360"></video>
        <script src="//players.brightcove.net/3737230870001/tIG7lVKBm_default/index.min.js"></script>

        <script type="text/javascript">
        var player = videojs("myPlayerID");

        player.one("loadstart", function(){
          var sourceUrl = player.currentSource();
          console.log(sourceUrl);
          var liveUrlWithParams = sourceUrl.src + "?player_width={width}&player_height={height}&deviceid={deviceid}";

          player.src([{
            "type": "application/vnd.apple.mpegurl",
            "src": liveUrlWithParams
          }]);
        });
      </script>

      </body>

Note that the key names in this example correspond to the variable names in the ad tag shown above.

Ad configuration variables

Ad configuration variables, also known as beacons, can be used in requests to manage ad configurations. For details, see the Live API: Cue Points and Ad Beacons with SSAI document.

Using manual cue points

Values for specific ad breaks can be sent with the manual cue point insertion request. For details, see the Live API: Cue Points and Ad Beacons document.

Known issues

  • SSAI requires that the live streaming video have an audio track.
  • If the VAST returned has the same ad ID, then the server will not request the ad content, even though the ad URL uses dynamic variables to make it a unique URL. This does not apply if you are using DFP for ads.
  • With DFP, while you can use the same ad ID, there still needs to be a different creative ID - in other words, you can't do a simple swap of the MediaFile.
  • If an ad break has a duration less than the MAX duration of the ad URL (min_ad_duration=0&max_ad_duration=30000), if ad is returned longer than the ad break, the ad will not be played.

  • VPAID or clickable ads are not supported for Brightcove Live SSAI.

  • When an ad break has remaining time shorter than the segment seconds of the stream and a slate is displayed, the slate is displayed for its segment duration and the actual ad break will be longer than expected.

  • The first time the ad is seen by our system, it will not play until it is transcoded and ready to deliver.
  • VMAP for Live SSAI is not currently supported.

Page last updated on 18 May 2020