Build the Response

After your application processes the bid request from Google, it must build and send a response. This guide explains how to code your application to build the response.

Create Protobuf BidResponse message

Authorized Buyers sends out the BidRequest as the message body of an HTTP POST. If your bidding endpoint is configured to use the Protobuf format, your application must send a response with the Content-Type header set to application/octet-stream and a message body consisting of a serialized protocol buffer. The protocol buffer is a BidResponse message as defined in openrtb.proto. Your application must return a parsable BidResponse in response to every BidRequest. Timeouts and responses that cannot be parsed are considered errors and Google throttles bidders with high error rates.

If you don't want to bid on an impression, you can set the BidResponse.ext.processing_time_ms field alone, and leave all other fields empty. You can obtain openrtb.proto from the reference data page.

Creative ID

Your BidResponse specifies a creative through the BidResponse.seatbid.bid.crid field (64 byte limit). Even similar creatives must have unique values for this field if they differ in any notable characteristics, including but not limited to: size, declared URL, creative attributes, and vendor types. In other words, you must give different creative IDs to any two ads which:

  • Look or behave differently.
  • Render to different images.
  • Render by different means (for example, one ad consists of an image, while the other is a video).

As you design your application, you should decide on a systematic way of generating identifiers that makes sense for the kinds of creatives you plan to submit.

Ad attributes

Google recommends declaring creative attributes to describe your ad's characteristics and its targeting using either a combination of BidResponse.seatbid.bid.apis and BidResponse.seatbid.bid.attr, or the BidResponse.seatbid.bid.ext.attribute extension. The following describes how you can declare attributes:

  • VPAID
    Set BidResponse.seatbid.bid.apis to VPAID_1, or VPAID_2. For the JSON format, this can be set to 1 or 2 respectively.
  • MRAID
    Set BidResponse.seatbid.bid.apis to MRAID_1, or 3 for the JSON format.
  • SIZELESS
    Set BidResponse.seatbid.bid.attr to RESPONSIVE, or 18 for the JSON format.
  • PLAYABLE
    This is indicated by setting BidResponse.seatbid.bid.attr to USER_INTERACTIVE, or 13 for the JSON format.

See the Creatives resource for an explanation on how to get feedback regarding the detected properties of your creatives.

Open Bidding fields

Bid responses sent by exchange and network bidders participating in Open Bidding are similar to those of Authorized Buyers participating in standard real-time bidding. Open Bidding customers can specify a small number of additional fields, and a few existing fields may have alternative uses. These include the following:

OpenRTB Authorized Buyers Details
BidResponse.imp[].pmp.deals[].id BidResponse.ad[].adslot[].exchange_deal_id

The deal ID from the exchange's namespace that is associated with this bid and reported to publishers.

BidResponse.seatbid[].bid[].ext.exchange_deal_type BidResponse.ad[].adslot[].exchange_deal_type

The type of deal reported to publishers, affecting how the deal is treated in the auction.

BidResponse.seatbid[].bid[].ext.third_party_buyer_token BidResponse.ad[].adslot[].third_party_buyer_token Token used to identify end third-party buyer information if the exchange as an Open Bidder is an intermediary. This is obtained from the third-party buyer and must be passed to Google unaltered in the bid response.

Recommendations

  • Enable persistent HTTPS connections (also known as "keep-alive" or "connection reuse") on your servers. Set the timeout to 10 seconds at minimum—higher values are beneficial in many cases. Google verifies this during the initial latency tests of your application, because Authorized Buyers sends requests at a high rate and needs to avoid the latency overhead of establishing a separate TCP connection for each request.
  • Include the optional impression tracking URL to track when the impression renders rather than when the bidder wins. Because of the dropoff between wins and renderings, this yields more accurate tracking statistics.

  • Keep your bidder code free of dependencies on deprecated fields, which can cause your bids to fail with errors.
  • Include BidResponse.seatbid.bid.w and BidResponse.seatbid.bid.h in your BidResponse. A BidResponse to a request that includes multiple ad sizes must include these fields or it will be dropped from the auction.
  • Limit your response size to under 8K. Very large responses may increase network latency and cause timeouts.
  • Follow the guidelines for bids on iOS inventory that require SKAdNetwork attribution.

Example bid response

The following examples represent human-readable samples of the Protobuf and JSON requests.

OpenRTB Protobuf

OpenRTB JSON

Google

Important: The Protobuf messages depicted in the samples are represented here as human-readable text. However, that is not how the messages are sent over the wire. When using the Google or OpenRTB Protobuf format, only serialized BidResponse messages will be accepted.

You can create and serialize a BidResponse message using the following C++ code:

BidResponse bid_response;
// fill in bid response with bid information
string post_response;
if (bid_response.SerializeToString(&post_response)) {
  // respond to the POST with post_response as the content
} else {
  // return an error to the POST
}

Specify creative

Your bid response specifies the creative to serve if your bid wins. Your bid must include one of the supported ad formats (AMP, video, native). In this example, we specify the creative using the html_snippet field.

Alternatively, you can specify your creative using one of the following fields, based on ad format:

  • SDK rendered ad
    • BidResponse.seatbid.bid.ext.sdk_rendered_ad
  • AMP
    • BidResponse.seatbid.bid.amp_ad_url
  • Video
    • BidResponse.seatbid.bid.adm
  • Native
    • BidResponse.seatbid.bid.adm_native

Specify an ad that is hosted on your own server(s) using an HTML snippet in the BidResponse.seatbid.bid.adm field. The snippet is enclosed in an iFrame inserted in the web page, resulting in the ad being retrieved and rendered when the page is loaded. You must craft the HTML snippet so that the ad (banner or interstitial) renders correctly inside an iFrame, and at an appropriate size for the ad slot you are bidding on.

In addition, the ad size declared in the bid response must match exactly one of the size combinations in the bid request when:

  • An ad is a regular banner (not video, native, or interstitial).
  • The bidder has declared the size in the bid response. Size declaration is required whenever more than one size is present in the request.
  • An exception is made for interstitial ads. For interstitials the width must be at least 50% of the screen width and the height to at least 40% of the screen height.

You can specify an HTML snippet creative using any valid HTML code that renders properly, but keep in mind the restrictions on specifying the crid field in the Create BidResponse message section. One use for this is to put extra information into arguments of the URLs that are fetched from your servers as part of rendering the ad. This lets you pass arbitrary data about the impression back to your own servers.

Most policies for HTML snippets returned in bid responses are the same as for third-party ads. See Authorized Buyers Program Guidelines, Requirements for third-party ad serving, and Declare click-through URLs in ads for more information.

Specify macros

Macros are formatted text embedded into some bid response fields containing URLs that are replaced with a relevant value at ad serving time. For example, if your winning bid included the AUCTION_PRICE macro in the HTML snippet creative included with your bid, the macro would be replaced with a value you could decrypt to determine the amount you paid for the impression in the auction.

You can include macros in the following fields:

  • BidResponse.seatbid.bid.adm

    Macros are supported for HTML snippet, native, video URL, and video VAST XML formats.

  • BidResponse.seatbid.bid.adm_native.eventtrackers.url

  • BidResponse.seatbid.bid.adm_native.imptrackers

  • BidResponse.seatbid.bid.ext.amp_ad_url

    Only the Google-specific WINNING_PRICE and WINNING_PRICE_ESC macros are supported for AMP creatives.

  • BidResponse.seatbid.bid.burl

  • BidResponse.seatbid.bid.ext.impression_tracking_url

    Use this instead of BidResponse.seatbid.bid.burl if you require more than one billing URL.

As an example, you could include a macro as part of an HTML snippet by embedding ${MACRO} within the URL used to fetch the creative, where MACRO is one of the supported macros described in the OpenRTB specification.

Google RTB macros

Google supports additional macros aside from those found in the OpenRTB spec. These are formatted differently, and would appear as %%MACRO%% if embedded in a URL. The following table describes these macros:

Macro Description
ADVERTISING_IDENTIFIER Allows buyers to receive iOS IDFA or Android's Advertising ID on impression rendering. See Decrypting Advertiser Identifiers for details.
CACHEBUSTER A string representation of a random, unsigned, four-byte integer.
CLICK_URL_UNESC

The unescaped click URL for the ad. In the snippet, an escaped version of the third party click URL should directly follow the macro.

For example, if the third-party click URL is http://my.adserver.com/some/path/handleclick?click=clk, then the following code could be used with the single-escaped version of the third party click URL following the macro invocation:

<a href="%%CLICK_URL_UNESC%%http%3A%2F%2Fmy.adserver.com%2Fsome%2Fpath%2Fhandleclick%3Fclick%3Dclk"></a>

At ad serving time, this is expanded to:

<a href="http://google-click-url?...&ad_url=http%3A%2F%2Fmy.adserver.com%2Fsome%2Fpath%2Fhandleclick%3Fclick%3Dclk"></a>

The URL will first register the click with Google, and then redirect to the third party click URL.

CLICK_URL_ESC

The escaped click URL for the ad. Use this instead of CLICK_URL_UNESC if you need to first pass the value through another server that will then return a redirect.

For example, the following code could be used in an HTML snippet:

<a href="http://my.adserver.com/click?google_click_url=%%CLICK_URL_ESC%%"></a>

At ad serving time, this is expanded to:

<a href="http://my.adserver.com/click?google_click_url=http://google-click- url%3F...%26ad_url%3D"></a>

This will register the click with my.adserver.com which will then be responsible for redirecting to the URL passed in the google_click_url parameter. This assumes that my.adserver.com unescapes the google_click_url parameter.

You can append a double-escaped URL after %%CLICK_URL_ESC%%. After the unescaping is done by my.adserver.com, that leaves a single-escaped version of the URL appended to the google_click_url. When the google_click_url is fetched, it will unescape once more and then redirect.

CLICK_URL_ESC_ESC

The double-escaped URL for the ad. Use this instead of CLICK_URL_UNESC if you need to first pass the value through another server that will then return a redirect.

For example, the following code could be used in an HTML snippet:

<a href="http://my.adserver.com/click?google_click_url=%%CLICK_URL_ESC_ESC%%"></a>

At ad serving time, this is expanded to:

<a href="http://my.otheradserver.com/click?google_click_url=http%3A%2F%2Fmy.adserver.com%2Fclick%3Fgoogle_click_url%3Dhttp%3A%2F%2Fgoogle-click-%20url%253F...%2526ad_url%253D"></a>
SCHEME Expanded to http: if the bid request does not require SSL or to https: if the bid request requires SSL.
SITE The url-escaped domain of the content URL or the anonymous ID for anonymous inventory.
SITE_URL Deprecated. Replaced by the SITE macro which provides identical functionality.
TZ_OFFSET The time-zone offset.
VERIFICATION

The different values for production and when the creative is scanned in the verification pipeline. The format is: %%?VERIFICATION:true-val:false-val%% where any values except macros can be used for true-val and false-val, including empty strings. For Open Bidding, we recommend that exchanges use this macro; once they do so, demand-side platforms don't need to make changes.

For example if a creative were to include %%?VERIFICATION:-1:5000%% then the text replacement would be 5000 on serving and -1 in the verification pipeline. This is to help differentiate between these two sets of pings.

WINNING_PRICE

The encoded impression cost (that is, CPI rather than CPM) in micros of the account currency. For example, a winning CPM of $5 USD corresponds to 5,000,000 micros CPM, or 5,000 micros CPI. The decoded value of WINNING_PRICE in this case would be 5,000. The winning price is specified in CPI.

To parse this macro, you will need to implement an application that decrypts price confirmations. Refer to the Decrypting Price Confirmations page for more information.

WINNING_PRICE_ESC URL-escaped WINNING_PRICE.

Google requires that you use either the CLICK_URL_UNESC or CLICK_URL_ESC macro within the creative of the third-party served ad. Google uses the CLICK_URL macros for click tracking.

URL escaping in macros uses the following scheme:

  • The space character is replaced by a plus sign (+).
  • Alphanumeric characters (0-9, a-z, A-Z) and characters from the set !()*,-./:_~ remain unchanged.
  • All other characters are replaced by %XX, where XX is the hexadecimal number representing the character.

Publisher restrictions and requirements

The bid request includes information about the kinds of restrictions and requirements that publishers place on creatives in the auction.

  • BidRequest.bcat
    • You can compare blocked categories specified by this field to those detected for your submitted creatives using Real-time Bidding API's detectedCategories field.
  • BidRequest.imp.ext.allowed_vendor_type
  • BidRequest.imp.secure
    • In practice this will always be set true because Google requires SSL support for all creatives.
  • BidRequest.imp.{audio/banner/native/video}
  • BidRequest.imp.{audio/banner/native/video}.api
  • BidRequest.imp.{audio/banner/native/video}.battr
  • BidRequest.imp.{audio/banner/video}.mimes

Never bid with an ad containing a restricted feature. For allowed features such as vendor type, return an ad only if its vendor type is in the allowed_vendor_type list in the BidRequest. Only ad formats specified in the bid request by populating fields such as BidRequest.imp.banner should be included in your bid. See the comments for these fields in the BidRequest protocol buffer definition for more details.

If an ad is returned in BidResponse, you are required to accurately set BidResponse.seatbid.bid.attr, BidResponse.seatbid.bid.cat, and either BidResponse.seatbid.bid.adomain or BidResponse.seatbid.bid.adm_native.link.url fields in the BidResponse. If an ad has multiple applicable values for these fields, then you must include every value. See the comments for these fields in the BidResponse protocol buffer definition for more details. Responses that don't have these fields set are discarded.

Open Measurement

Open Measurement lets you specify third-party vendors that provide independent measurement and verification services for ads served to mobile app environments.

Supported ad formats include video, banner, and interstitial ads. For more information on how to use Open Measurement in a bid response containing these formats, refer to the Open Measurement SDK Help Center article.

Sample bid responses

The following sections show sample bid responses for different ad types.

App banner

OpenRTB Protobuf

OpenRTB JSON

Google

App Interstitial

OpenRTB Protobuf

OpenRTB JSON

Google

App interstitial video

OpenRTB Protobuf

Google

App native

OpenRTB Protobuf

OpenRTB JSON

Google

Web video

Google

Mobile web banner for exchange bidder

OpenRTB Protobuf