AMPHTML ads over RTB

This page describes how to get started using AMPHTML ads with RTB. Check out the Resources below for additional info about AMPHTML ads and tools to help you get started.

High-level approach

RTB bid request

The RTB bid request indicates whether the request is coming from an AMP page and the requirements for AMPHTML ads.

OpenRTB

AMP page

message SiteExt {
  enum AmpPage {
    // This is not an AMP page.
    DIALECT_HTML = 0;

    // This is an Amp page.
    DIALECT_HTML_AMP = 1;
  }

  // Whether this is an AMP page or not. Omitted if unknown.
  optional AmpPage amp = 1;
  enum VisibilityState {
    VISIBILITY_STATE_UNKNOWN = 0;

    // The page is at least partially visible. For example, in the foreground
    // tab of a non-minimized window.
    VISIBILITY_STATE_VISIBLE = 1;

    // The page is not visible to users. For example, when the page is in a
    // background browser tab, or in a minimized window.
    VISIBILITY_STATE_HIDDEN = 2;
  }

  // The visibility state of the web page containing the ad slot.
  // See https://www.w3.org/TR/page-visibility/.
  // [AdX: BidRequest.page_visibility]
  optional VisibilityState page_visibility = 2 [default =
    VISIBILITY_STATE_UNKNOWN];

  // Information about a browser window's user activation state. See
  // https://html.spec.whatwg.org/multipage/interaction.html#the-useractivation-interface.
  message UserActivation {
    // Indicates whether a user has completed an interaction since page load.
    optional bool wasact = 1;

    // Indicates whether a user is currently interacting with the page.
    optional bool isact = 2;
  }

  // User activation information from the browser for the current request, if
  // the request is for a web page.
  optional UserActivation uact = 5;

  // The set of possible web navigation types that predicate a page load. Each
  // of these types may have different performance characteristics. For example,
  // users going back and forth might experience a faster site than users
  // performing navigation for the first time or submitting forms. See
  // https://w3c.github.io/navigation-timing/#dom-performancenavigationtiming-type.
  enum NavigationType {
    NAVIGATION_TYPE_UNKNOWN = 0;

    // Navigation started by clicking a link, entering the URL in the browser's
    // address bar, form submission, or initializing through a script operation
    // other than reload and back_forward.
    NAVIGATION_TYPE_NAVIGATE = 1;

    // Navigation is through the browser's reload operation, location.reload(),
    // or a Refresh pragma directive like
    // <meta http-equiv="refresh" content="300">.
    NAVIGATION_TYPE_RELOAD = 2;

    // Navigation is through the browser's history traversal operation.
    NAVIGATION_TYPE_BACK_FORWARD = 3;

    // Navigation is initiated by a prerender hint (deprecated). See
    // https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/prerender.
    NAVIGATION_TYPE_PRERENDER = 4;
  }

  // The type of browser navigation that led to the current page. Unset for
  // non-web ad requests.
  optional NavigationType ntype = 6;

  // Indicates that the request is using semi-transparent branding,
  // which means only a truncated version of the request URL will
  // be provided. This decision is made by the publisher, see
  // https://support.google.com/admanager/answer/4584891#urls for context.
  optional bool is_semi_transparent_request = 3;

  // The domain of the partner (of the site owner) with ownership
  // of some portion of ad inventory on the site. The partner's ads.txt file
  // will be hosted here. More detail at
  // http://iabtechlab.com/wp-content/uploads/2021/03/ctv-app-ads-explainer-guide.pdf
  optional string inventorypartnerdomain = 4;
}

AMPHTML ad requirements

// Ad Exchange extensions for the Imp object.
message ImpExt {
...
  // Possible requirement types for AMP ads.
  enum AmpAdRequirementType {
    // AMP ad requirements unknown.
    UNKNOWN_AMP_AD_REQUIREMENT_TYPE = 1;
    // AMP ads are not allowed.
    AMP_AD_NOT_ALLOWED = 2;
    // Either AMP ads or non-AMP ads are allowed;
    // AMP ads are not early rendered.
    AMP_AD_ALLOWED_AND_NOT_EARLY_RENDERED = 3;
    // Either AMP ads or non-AMP ads are allowed;
    // AMP ads are early rendered.
    AMP_AD_ALLOWED_AND_EARLY_RENDERED = 4;
    // AMP ads are required.
    // Ads that are non-AMP may be rejected by the publisher.
    AMP_AD_REQUIRED = 5;
    // Exchange-specific values above 500.
  }
  optional AmpAdRequirementType ampad = 8
    [default = UNKNOWN_AMP_AD_REQUIREMENT_TYPE];
}

Authorized Buyers RTB

AMP page

// Whether this is an AMP page or not.
enum AmpPage {
  // AMP page status unknown.
  UNKNOWN_AMP_PAGE = 0;

AMPHTML ad requirements

// Possible requirement types for AMP ads.
enum AmpAdRequirementType {
  // AMP ad requirements unknown.
  UNKNOWN_AMP_AD_REQUIREMENT_TYPE = 0;

RTB bid response

OpenRTB

In OpenRTB 3.0 and the accompanying Advertising Common Model several additions to support AMPHTML ads are included in the most recent draft specs by the IAB, including the following.

Bid Field Attr Type Description
Request Site.amp amp integer The Site.amp field indicates whether the page is rendered in AMP, omitted if unknown:
0 = page is non-AMP
1 = page is built with AMP HTML
Request ampformat rend integer The AMP Format Specification indicates the requirements and rendering behavior for AMPHTML ads:
1 = AMP ad requirements are unknown
2 = AMP ads are not allowed
3 = Either AMP ads or non-AMP ads are allowed; AMP ads are not early rendered
4 = Either AMP ads or non-AMP ads are allowed, and AMP ads are early rendered
5 = AMP ads are required. Ads that are non-AMP may be rejected by the publisher
500+ = Exchange-specific values; should be communicated to bidders a priori
Response display curl string In the bid response, display.curl has been added to be able to submit creatives through a URL, including support for AMPHTML ads.
This is the URL at which the creative markup will be found. Applicable to creatives types such as: AMP Ads, VAST, and DAAST and Native. Normally only one of adm or curl is valid in a given ad.

Authorized Buyers RTB

The BidResponse.Ad.amp_ad_url field in Authorized Buyers bid responses accepts a URL pointing to AMPHTML ad content. The same field exists as an extension in the Bid object in Google's OpenRTB implementation.

// The URL to fetch an AMPHTML ad. Only one of the following should be set:
// html_snippet, video_url, amp_ad_url, native_ad.
optional string amp_ad_url = 23;

Verification of valid AMPHTML

For AMPHTML ads to be early rendered, the exchange is required to verify and sign them, indicating that the ad is written in amp4ads <html amp4ads> creative format.

Ads that are valid AMPHTML will be allowed to render early by AMP pages. Ads that are not verified as valid AMPHTML will render at the same speed as non-AMPHTML ads.

Only AMPHTML ads should be returned in the amp_ad_url.

In the future, if a publisher requires AMPHTML ads only, ads not signed as AMPHTML will not be rendered.

With Authorized Buyers, bidders will still be charged if they return a non-AMPHTML Ad to an AMPHTML ad-required adslot.

Server-side fetch

For AMPHTML ads to be early rendered, AMPHTML ad content must be rendered without requiring additional hops from the client. This is designed to avoid poor user experiences due to ad latency and extra client-side calls.

After a bidder wins the auction, the exchange will perform a server-to-server request to retrieve the AMPHTML ad content located at the URL provided in amp_ad_url. Creative servers must respond and return content within 300 ms.

The AMPHTML ad returned from the creative server will be injected into the adslot and subsequently rendered. Note that a valid AMPHTML ad cannot contain iframes or other <amp-ad> tags. See the AMPHTML ads spec for more details.

Beta only feature: Contact your account team if you require this

During server-to-server retrieval of the AMPHTML ad (specified in amp_ad_url), Authorized Buyers may pass the HTTP header and IP from the user's browser to the creative server. This ensures the creative server receives information similar to that sent from a standard client-side fetch. In some cases, the IP address may be truncated to only the first 3 bytes (IPv4) or first 6 bytes (IPv6). Contact your account team if you require this feature. Here is a sample HTTP header:

Impression tracking URLs and click macros

RTB buyers often include impression trackers as a structured field in the bid response (this is Bid.burl, the "billing notice URL" in OpenRTB 2.5).

With Authorized Buyers, these will be fired client-side; amp-pixel fires tracking URLs when the creative is rendered. amp-analytics can handle more advanced tracking use cases beyond rendering.

AMPHTML ads are required to contain a valid click macro in the AMPHTML. This will typically take the form of something like this:

<a href="%%CLICK_URL_UNESC%%http%3A%2F%2my.adserver.com%2Fsome%2Fpath%2Fhandleclick%3Fclick%3Dclk"></a>
<a href=”https://my.adserver.com/click?google_click_url=%%CLICK_URL_ESC%%”></a>

Creatives often include cookie matching pixels within the creative code. AMPHTML ads can use the amp-pixel and amp-analytics components for this use case. If your use case cannot be accommodated by using amp-analytics or amp-pixel, open a GitHub issue to discuss alternate options. We welcome new extensions that can be broadly used by a number of different companies. See detailed guidelines or a technical guide to building a new extension.

Sample AMP Ad URLs for testing

You can use the following sample AMPHTML ad content for testing:

Resources

The AMP Project and Google have released a number of resources to help you get started:

Building ads in AMP
RTB-specific proposals to IAB / OpenRTB Group