Stay organized with collections
Save and categorize content based on your preferences.
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 must return an empty HTTP
204 response. 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.
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.
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.
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.
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:
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:
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:
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.
id:"96Z599PGNvp7Mr99138Fm0"seatbid{bid{id:"NQb32Ge7Rtt84wFn2p8"impid:"1"price:0.153584adid:"test_creative_id_272596"adomain:"google.com"crid:"test_creative_id_272596"cat:"IAB13-7"burl:"https://test.com/imp?id=123456"adm_native{ver:"1.2"assets{id:1required:truetitle{text:"Luxury Mars Cruises"}}assets{id:2required:truedata{value:"Visit the planet in a luxury spaceship."}}assets{id:3required:falsedata{value:"Book today"}}assets{id:4required:truedata{value:"Galactic Luxury Cruises"}}assets{id:5required:trueimg{url:"https://native.test.com/image?id=123456"w:1200h:627}}link{url:"https://www.google.com"}eventtrackers{event:IMPRESSIONmethod:IMGurl:"https://test.com/event?id=123456"}privacy:"https://adssettings.google.com/whythisad?source=display&reasons=OMITTED"}[com.google.doubleclick.bid]{ad_choices_destination_url:"https://test.com/preferences"billing_id:29846056590dsa{behalf:"TEST_ADVERTISER"paid:"TEST_PAYING_ENTITY"adrender:false}}}bid{id:"4vwb23qm6iqU6w6G978"impid:"1"price:0.153584adid:"test_creative_id_272596"adomain:"google.com"crid:"test_creative_id_272596"cat:"IAB21"burl:"https://test.com/imp?id=123456"adm_native{ver:"1.2"assets{id:1required:truetitle{text:"Luxury Mars Cruises"}}assets{id:2required:truedata{value:"Visit the planet in a luxury spaceship."}}assets{id:3required:falsedata{value:"Book today"}}assets{id:4required:truedata{value:"Galactic Luxury Cruises"}}assets{id:5required:trueimg{url:"https://native.test.com/image?id=123456"w:1200h:627}}link{url:"https://www.google.com"}eventtrackers{event:IMPRESSIONmethod:IMGurl:"https://test.com/event?id=123456"}privacy:"https://adssettings.google.com/whythisad?source=display&reasons=OMITTED"}[com.google.doubleclick.bid]{ad_choices_destination_url:"https://test.com/preferences"dsa{behalf:"TEST_ADVERTISER"paid:"TEST_PAYING_ENTITY"adrender:false}}}seat:"4528:1161:591635"group:false}bidid:"hgu4ev7j-ZK929XM0-79f7-0A23O0VN2CFC"cur:"USD"
OpenRTB JSON
Show me the example
{"id":"96Z599PGNvp7Mr99138Fm0","seatbid":[{"bid":[{"id":"NQb32Ge7Rtt84wFn2p8","impid":"1","price":0.153584,"adid":"test_creative_id_272596","adomain":["google.com"],"crid":"test_creative_id_272596","cat":["IAB13-7"],"burl":"https://test.com/imp?id=123456","ext":{"ad_choices_destination_url":"https://test.com/preferences","billing_id":"29846056590","dsa":{"behalf":"TEST_ADVERTISER","paid":"TEST_PAYING_ENTITY","adrender":0}},"adm":"{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"text\":\"Luxury Mars Cruises\"}},{\"id\":2,\"required\":1,\"data\":{\"value\":\"Visit the planet in a luxury spaceship.\"}},{\"id\":3,\"required\":0,\"data\":{\"value\":\"Book today\"}},{\"id\":4,\"required\":1,\"data\":{\"value\":\"Galactic Luxury Cruises\"}},{\"id\":5,\"required\":1,\"img\":{\"url\":\"https://native.test.com/image?id=123456\",\"w\":1200,\"h\":627}}],\"link\":{\"url\":\"https://www.google.com\"},\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"https://test.com/event?id=123456\"}],\"privacy\":\"https://adssettings.google.com/whythisad?source=display&reasons=OMITTED\"}"},{"id":"4vwb23qm6iqU6w6G978","impid":"1","price":0.153584,"adid":"test_creative_id_272596","adomain":["google.com"],"crid":"test_creative_id_272596","cat":["IAB21"],"burl":"https://test.com/imp?id=123456","ext":{"ad_choices_destination_url":"https://test.com/preferences","dsa":{"behalf":"TEST_ADVERTISER","paid":"TEST_PAYING_ENTITY","adrender":0}},"adm":"{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"text\":\"Luxury Mars Cruises\"}},{\"id\":2,\"required\":1,\"data\":{\"value\":\"Visit the planet in a luxury spaceship.\"}},{\"id\":3,\"required\":0,\"data\":{\"value\":\"Book today\"}},{\"id\":4,\"required\":1,\"data\":{\"value\":\"Galactic Luxury Cruises\"}},{\"id\":5,\"required\":1,\"img\":{\"url\":\"https://native.test.com/image?id=123456\",\"w\":1200,\"h\":627}}],\"link\":{\"url\":\"https://www.google.com\"},\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"https://test.com/event?id=123456\"}],\"privacy\":\"https://adssettings.google.com/whythisad?source=display&reasons=OMITTED\"}"}],"seat":"4528:1161:591635","group":0}],"bidid":"hgu4ev7j-ZK929XM0-79f7-0A23O0VN2CFC","cur":"USD"}
ad{adslot{id:1max_cpm_micros:158000billing_id:41106584355deal_id:1}click_through_url:"google.com"attribute:70buyer_creative_id:"test_creative_id_251451"advertiser_name:"Google"native_ad{headline:"Luxury Mars Cruises"body:"Visit the planet in a luxury spaceship."call_to_action:"Book today"advertiser:"Galactic Luxury Cruises"image{url:"https://native.test.com/image?id=123456"width:1200height:222}app_icon{url:"https://native.test.com/icon?id=123456"width:512height:512}star_rating:4.300000190734863click_link_url:"https://www.google.com"}impression_tracking_url:"https://test.com/imp?id=123456"impression_tracking_url:"https://test.com/imp?id=123456"event_notification_token:"token"skadn{version:"4.0"network:"l6x39K4z"itunesitem:"731305960"sourceapp:"627009739"fidelities{fidelity_type:STOREKIT_RENDERED_ADSnonce:"9216faff-74a9-4b35-badc-66878c35f67c"timestamp:1728975919221signature:"b0USXkmg02Q3v6p301kYOHG36CCOWWdEo52RHRttB9t8PTNi79qL17E4D6h7UeUSuq479oTK13G2Ev34MJlU86C5vY1SMVw2"}fidelities{fidelity_type:VIEW_THROUGH_ADSnonce:"9216faff-74a9-4b35-badc-66878c35f67c"timestamp:1728975919221signature:"4Cf4NH6239z9f3wa8j6420Z7H0UISYxyxN5720444dkq6457I5FY0Jg8bk1xge2P8YgiDp74l2738136v2g1A8D50331IRm0"}source_identifier:1}click_tracking_urls:"https://google.com/rtb/click?imp_id=55d2112c-4947-4da5-bc37-b79ebf4577dd"advertised_app_id:"APP_ID_OMITTED"app_promotion_type:INSTALLS}processing_time_ms:63
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-02-10 UTC."],[[["Bid responses must be serialized `BidResponse` protocol buffers with the `Content-Type` header set to `application/octet-stream` for Protobuf, and a parsable `BidResponse` is required for each `BidRequest`, while an empty HTTP 204 response signals no bid."],["Each creative needs a unique `crid` (creative ID) limited to 64 bytes, and this ID must be unique across creatives if there are differences in size, declared URL, attributes, vendor types, appearance, behavior, or rendering method."],["Ad characteristics should be declared using `BidResponse.seatbid.bid.apis`, `BidResponse.seatbid.bid.attr`, or `BidResponse.seatbid.bid.ext.attribute`, with specific values indicating VPAID, MRAID, SIZELESS, or PLAYABLE attributes, respectively, and additional attributes from `buyer-declarable-creative-attributes.txt`."],["Responses should remain under 8KB, utilize persistent HTTPS connections with at least a 10-second timeout, and employ `BidResponse.seatbid.bid.burl` or `BidResponse.seatbid.bid.ext.impression_tracking_url` for tracking impressions."],["The `BidResponse` must accurately set creative attributes (`BidResponse.seatbid.bid.attr`), categories (`BidResponse.seatbid.bid.cat`), and advertiser domain (`BidResponse.seatbid.bid.adomain`) or native ad link (`BidResponse.seatbid.bid.adm_native.link.url`), as responses lacking these are discarded."]]],[]]