Skip to content

Latest commit

 

History

History
365 lines (202 loc) · 15.4 KB

component-seller.md

File metadata and controls

365 lines (202 loc) · 15.4 KB

Video Support for Component-seller Auction in Protected Audience API

Objective

We would like to outline how the Protected Audience API can be used to support video (instream audio/video advertising) when there are multiple sellers (i.e. exchanges).

Requirements

In the Protected Audience API, a top level seller can include other sellers in the Protected Audience auction as “component auctions” (or component sellers). These component sellers should be able to:

  • Run their own Protected Audience auction with their buyers, and submit their winning bid to the top-level auction.
  • Receive Fenced Frame Reporting tracking events about the Protected Audience auction.

Overview

Protected Audience API for Instream Video proposes the flow when there is only a single seller. This doc builds on that proposal to enable component sellers.

To collaboratively create a renderUrl that delivers a video ad and tracks video events, each participant in the auction should do the following:

  • Buyer
    • The buyer should join ad interest groups with renderUrl that contain seller macros and buyer’s ad URL. The seller macros allow sellers to insert seller’s VAST wrapper URLs. The buyer’s ad URL should return the VAST ad.
  • Component seller
    • A component seller should provide its component auction configuration to the top-level seller. This configuration should contain a macro replacement map that will be used to inject component seller’s wrapper VAST URL to the renderUrl.
  • Top-level seller
    • The top-level seller should construct the final auctionConfig, including any configuration provided by the component seller.
    • It should provide the top-level seller's wrapper VAST URL to the Protected Audience Integrator.

To pull this together, a component seller, a top-level seller, a publisher or a third-party video SDK provider, needs to perform the integration with Protected Audience on the publisher’s website. More specifically, this PA Integrator should:

  • Run a PA API auction using the auctionConfig provided by the top-level seller.
  • Coordinate video playback between the content video player and the winning PA ad.
    • This coordination is achieved through an HTML shim that will run inside the PA APIs rendering frame.
    • The HTML shim should:
      • Contain a video player to play VAST video ads.
      • Support a VAST extension for triggering Fenced Frame reporting APIs
      • Receive user interaction events (such as play, pause) from outside of the iframe as postMessages and play / pause the video ad accordingly.
      • Receive events (such as video progress events) from the video ad player and forward them outside of the iframe through postMessages
  • Perform macro expansion on the winning PA ad URN, in order to provide (1) the URL to its HTML shim and (2) the top-level sellers VAST URL.

Alternative Design Options

The following walkthrough is meant as an illustration of one possible flow that can be used to support component-seller in PA video. We would like industry’s feedback on the feasibility of this flow, as well as our alternatives explored below. Feel free to raise questions and suggestions as GitHub issues.

Walkthrough of constructing PAAPI video renderUrl

The following walkthrough illustrates a flow where the top-level seller fulfills the role of integrating Protected Audience API with the content video player.

Join Ad Interest Group

To store an interest group to a browser, a buyer should construct its Protected Audience video creatives’ renderUrls as follow:

  1. Buyer creates a Buyer Ad URL that would return a video ad as a VAST document. For example:
https://buyer.com/?video_ad=123
  1. Buyer creates a renderUrl using the following template. Buyer should replace [[URL_ENCODED_BUYER_AD_URL]] with a URL encoded Buyer Ad URL.
https://${seller_video_url}/?${seller_video_query_params}[[URL_ENCODED_BUYER_AD_URL]]

For example:

https://${seller_video_url}/?${seller_video_query_params}https%3A%2F%2Fbuyer.com%2F%3Fvideo_ad%3D123

HTML Shim URL

  1. Before ad serving, the top-level seller, who is acting as the PA Integrator, will host an endpoint for their HTML Shim.

    • If an independent video ad player provider is acting as the PA Integrator, it would need to host its own HTML Shim, since their requirements for coordination may be unique.

Component Seller Opt-in

  1. When a user visits the publisher page (and before ad request), a component seller would need to opt-in to the PAAPI auction to participate.

    1. The component seller can provide its componentAuction’s config to the top-level seller.
    2. Component seller’s componentAuction’s config should contain a deprecatedRenderURLReplacements that will be used to replace ${seller_video_query_params} with the following template:
    3. [[URL_ENCODED_COMPONENT_SELLER_URL]] is a URL-encoded URL pointing to the component seller’s VAST server. The component seller’s VAST server should return a VAST document that contains the Fenced Frame Reporting tracking events.
${wrapper_prefix}[[URL_ENCODED_COMPONENT_SELLER_URL]]${seller_video_query_params}

For example, component seller can pass the following componentAuction’s config:

// Example component seller's URL
//    https://component-seller-url/ad/vast.xml?ad_url=

// Example API:
adsRequest.setProtectedAudienceAuctionConfigValue({
  'componentAuctions': [{
    'seller': 'https://www.some-other-ssp-1.com',
    'deprecatedRenderURLReplacements': {
       "${seller_video_query_params}": "${wrapper_prefix}https%3A%2F%2Fcomponent-seller-url%2Fad%2Fvast.xml%3Fad_url%3D${seller_video_query_params}"
    }
  }]
});

Run Protected Audience Auction

  1. The top-level seller merges the component seller’s auction config into their own auctionConfig.
  2. The top-level seller, acting as the PA Integrator, uses this merged configuration when calling runAdAuction().
navigator.runAdAuction({
    ...
    'componentAuctions':  /* auctionConfig from component seller */
    ...
  ],
});
  1. If a video ad wins the component auction, the winning renderUrl may be the following:
https://${seller_video_url}/?${seller_video_query_params}https%3A%2F%2Fbuyer.com%2F%3Fvideo_ad%3D123
  1. With deprecatedRenderURLReplacements in the component seller’s auction config, the browser inserts the component seller’s render URL to the renderUrl by replacing the macro ${seller_video_query_params} with component seller’s macro. The effective URL from the runAdAuction() may look like the following:
https://${seller_video_url}/?
    ${wrapper_prefix}
        https%3A%2F%2Fcomponent-seller-url%2Fad%2Fvast.xml%3Fad_url%3D
    ${seller_video_query_params}https%3A%2F%2Fbuyer.com%2F%3Fvideo_ad%3D123

Top-Level Seller Macro Expansion

  1. The top-level seller, acting as the PA Integrator, expands the macro ${seller_video_query_params} by using deprecatedReplacedInURN() using the following template:

    ${wrapper_prefix}[[URL_ENCODED_TOP_LEVEL_SELLER_URL]]${seller_video_query_params}
    
    1. [[URL_ENCODED_TOP_LEVEL_SELLER_URL]] is a URL-encoded URL pointing to the top-level seller’s VAST server. The top-level seller’s VAST server should return a VAST document that contains the Fenced Frame Reporting tracking events. For example, the top-level seller may have a URL like:
    https://top-level-seller-url.com/wrapper.xml?adTag=123
    
    1. After URL encoding, it becomes:
    https%3A%2F%2Ftop-level-seller-url.com%2Fwrapper.xml%3FadTag%3D123
    
    1. After performing the macro expansion, the URN may now reference a URL that looks like:
    https://${seller_video_url}?
        ${wrapper_prefix}
            https%3A%2F%2Fcomponent-seller-url-1%2Fad%2Fvast.xml%3FadTag%3D
        ${wrapper_prefix}
            https%3A%2F%2Ftop-level-seller-url.com%2Fwrapper.xml%3FadTag%3D123
        ${seller_video_query_params}https%3A%2F%2Fbuyer.com%2F%3Fvideo_ad%3D123
    

Video Ad Player Macro Expansion

  1. The top-level seller, acting as the PA Integrator, uses deprecatedReplacedInURN() to replace the macros:

    1. ${seller_video_url}
      • The URL for the Video Ad Player’s HTML shim. For example, video-ad-player.net/td/vast.html
    2. ${wrapper_prefix}
      • A query parameter that HTML shim will use to read wrapper VAST URIs from its document.location. For example &wrapper=
    3. ${seller_video_query_params}
      • A query parameter that HTML shim will use to read the buyers VAST ad URI from its document.location. For example &adTag=

After this final round of macro expansion, the URN may now reference a URL that looks like:

https://video-ad-player.net/td/vast.html?
    &wrapper=https%3A%2F%2Fcomponent-seller-url-1%2Fad%2Fvast.xml%3FadTag%3D
    &wrapper=https%3A%2F%2Ftop-level-seller-url.com%2Fwrapper.xml%3FadTag%3D123
    &adTag=https%3A%2F%2Fbuyer.com%2F%3Fvideo_ad%3D123

Diagram of macro expansion

Simple prepending - Video renderUrl macro replacement flow

Walkthrough of Rendering VAST Ad Tag URL

Loading of HTML Shim

  1. The top-level seller, acting as the PA Integrator, takes the URN from the previous phase and sets it as the source of an iframe.
  2. The HTML shim should read the encoded URLs from the top-level seller, component seller, and buyer from its query parameters and construct VAST ad tag URL.

For example:

// Within Video Ad HTML Shim
function main() {
  const params = new URLSearchParams(document.location.search);
  const [wrapper1, wrapper2] = params.getAll('wrapper').map(decodeURIComponent);
  const inlineAdTag = decodeURIComponent(params.get('adTag');
  // ... continued
}

Constructing Ad Tag URI

  1. The HTML shim should construct a VAST ad tag URI by combining the URLs from top-level seller, component seller, and buyer. For example:
function main() {
  // ... continued

  function constructWrapper(wrapper, destinationAd) {
    return ${wrapper}${encodeURIComponent(destinationAd)};
  }

  // Note that the inlineAd tag will be double encoded.
  return constructWrapper(wrapper2, constructWrapper(wrapper1, inlineAd));
}

Diagram of Ad Tag URI created by HTML shim

Diagram of Ad Tag URL

Note: the above example shows that the first domain is the top-level seller. However, the first domain can also be the component seller.

Resolving Ad Tag URL

Diagram of Ad Tag URL

  1. After constructing the VAST Ad Tag URI, the video ad player's HTML shim feeds the constructed VAST ad tag URI into a VAST player for resolution.
  2. The VAST player should resolve each VAST response in sequence, following wrapper tags. For example, the VAST player makes an initial HTTP request, fetching a VAST wrapper from the first endpoint. This may look like:
http://top-level-seller.com/wrapper.xml/
    ?adTag=https%3A%2F%2Fcomponent_seller.com%2Fwrapper.xml%26adTag%3D=
                  https%253A%252F%252Fbuyer.com%253Fvideo_ad%253D123
  1. The endpoint (the top-level seller in this example) should return a wrapper VAST with its tracking tags and <VASTAdTagUri> pointing to the next endpoint, provided on the URL with &adTag= query parameter. For example, the <VASTAdTagUri> in the wrapper VAST should be:
https://component-seller.com/wrapper.xml/
    ?&adTag=https%3A%2F%2Fbuyer.com%3Fvideo_ad%3D123
  1. The VAST player makes another HTTP request, fetching a VAST wrapper from the next endpoint.
  2. The next endpoint (component seller in this example) should also return a wrapper VAST with its tracking tags and <VASTAdTagUri> pointing to the next endpoint, provided on the URL with &adTag= query parameter. For example, the <VASTAdTagUri> in the wrapper VAST should be:
https://buyer.com?video_ad=123
  1. The VAST player makes a final request to the buyer, who returns an inline VAST ad.

VAST video playback

  1. Video playback starts as soon as the inline VAST ad is loaded.

  2. When the user clicks on the pause button on the publisher page:

    1. The publisher page should send a postMessage event to the HTML Shim.
    2. HTML Shim should pre-register a callback to receive this event. HTML Shim can respond by pausing the ad.
  3. When an event needs to be communicated outside of the video playback:

    1. The HTML Shim should send a postMessage to outside the iframe.
    2. The publisher page should pre-register a callback to receive this event.

Limitations

Similar to the Protected Audience API for Instream Video proposal, this proposal requires iframes.

Design Alternatives

1) Parallelization of VAST wrapper ad requests

It is possible to optimize the rendering flow by parallelizing VAST document requests. The URL sent to the ad video player contains URLs for the top-level seller, component seller, and the buyer as separate query parameters. For example:

https://video-ad-player.net/td/vast.html?
    &wrapper=https%3A%2F%2Fcomponent-seller-url-1%2Fad%2Fvast.xml%3FadTag%3D
    &wrapper=https%3A%2F%2Ftop-level-seller-url.com%2Fwrapper.xml%3FadTag%3D123
    &adTag=https%3A%2F%2Fbuyer.com%2F%3Fvideo_ad%3D123

Instead of chaining these URLs in a series of VAST wrapper redirects, the video ad player can send requests to these URLs in parallel. This can improve rendering latencies.

2) Removal of VAST wrapper ad requests

As an alternative rendering flow, the renderURL could contain only the HTML Shim requirements and buyers ad tag URL. In this way, the video ad player can skip calling out to the sellers and the component seller for VAST responses. To enable event tracking for sellers, the PA Integrator would trigger a set of predefined Fenced Frame reporting API events. The PA Integrator can publish a list of Fenced Frame reporting API eventNames for each event that the video ad player will call reportEvent() on. If an event carries additional metadata (such as the playhead position), it could potentially be communicated through eventData. Further, this set of eventNames can be standardized for all VAST players supporting PA API. The top level seller and component seller can pre-register beacons for these events using the Fenced Frame Reporting API within its reportResult().