Overview

Background

The Google RTB protocol is deprecated, and will sunset on February 15th, 2025. If you have not already done so, we recommend that you migrate to the OpenRTB protocol to avoid an interruption to your Real-time Bidding integration on the sunset date.

This guide is intended to aid you in your migration. It describes every field and concept in the Google RTB protocol and identifies the equivalent field or concept in OpenRTB.

How to use this guide

The BidRequest and BidResponse references included in this guide map individual fields of Google RTB protocol messages to their OpenRTB equivalents if they exist, and provide any additional migration instructions in the Notes column.

The majority of Google RTB protocol fields have a simple mapping to OpenRTB–meaning that you can read the corresponding OpenRTB field equivalently, or with a minor adjustment such as modifying the data type. For more complex mappings, the notes will include a link that you can follow to learn more.

There are some Google RTB protocol fields that have no equivalent in OpenRTB. Google is investigating these gaps and will adjust this guide to reflect their status in a future update. We encourage you to contact our support team and provide feedback if the lack of a mapping for an affected field would hinder your migration.

Migration support

You can reach out to the following support channels if you have questions or need help with your migration:

  • Authorized Buyers support forum
    • Get answers to public technical questions about the RTB protocols or APIs. This is a public forum. You can search for related questions submitted to this forum to find answers. Don't include any private information in your posts to this forum.
  • Technical API support alias: adxbuyerapi-support@google.com
    • Get answers to private questions about the RTB protocols or APIs. Unlike the support forum, questions here are private and can include details about your account that may be needed to investigate your question or issue.
  • Your Technical Account Manager (TAM)
    • If you have an assigned TAM, they can help with account configuration, product and UI questions, and some technical support.
  • Help Center Contact Us form
    • If you don't have an assigned TAM, you can use this form to get help with account configuration, product and UI questions, and some technical support.

Protocol representation

OpenRTB Protobuf versus JSON Serialization

Google's OpenRTB implementation supports both JSON and Protobuf formats, which have similar representations with minor differences to accommodate the format. The bid request and response references in this guide refer to the Protobuf format unless stated otherwise, but you can refer to the OpenRTB spec for JSON-specific information. We recommend using the Protobuf format because it has reduced CPU costs for serialization and deserialization, and reduced network costs due to smaller wire size.

Differences between these formats include:

  • Boolean (Protobuf) versus integer (JSON) data types: Boolean types defined in the Protobuf implementation are integers in the JSON format, where 0 is False, and 1 is True.
  • Enumeration (Protobuf) versus integer (JSON) data types: Enumeration fields in the Protobuf format are represented as integers in the JSON format, where the JSON value directly corresponds to Protobuf's enum integer value. These are also equivalent to the set of integer values defined for these fields if they exist in the OpenRTB spec.
  • Representation of int64 and fixed64 in JSON: The int64 and fixed64 types defined in the Protobuf implementation are represented as strings in JSON.
  • Native request and response message (Protobuf) versus JSON string: The JSON format uses a serialized JSON string defined in the OpenRTB spec to represent native request and response information, whereas the Protobuf format defines equivalent fields and messages that must be used instead. See native ads migration notes for more information.
  • Accessing extension fields: For brevity, extension fields described in the bid request and response references use the JSON field path, where ext denotes a Google-specific extension to the parent message. See Extensions for additional information about accessing extension fields with the Protobuf format.

Extensions

Extensions define Google-specific components of the protocol. In the bid request and response references, ext included in a field path indicates that the child field is an extension to the parent field's message. These field paths are representative of how the extensions are accessed in the JSON format, but the Protobuf format uses extensions as described in the Protobuf documentation, where accessing extension fields differs depending on the language of the generated proto libraries. We recommend reading through the Protobuf documentation's tutorial for your preferred language, along with its generated code guide (see: C++, Java).

As an example, printing the first element of BidRequest.imp.ext.billing_id could look like the following:

C++

Java

Eligible Buyers and Deals

In Google RTB, BidRequest.adslot.matching_ad_data indicates the bidder's matched pretargeting configs and eligible child seats (see the billing_id field), eligible deals, and bid floors. In Google RTB, billing IDs are grouped by floor and deals, but no such grouping exists in OpenRTB.

Here is an example to illustrate how this works. See inline comments for more details.

// Google RTB bid request
adslot {
  matching_ad_data {
    // Suppose that a bidder has two pretargeting configs with billing IDs 123 and 234
    // and suppose that they both match. Also suppose this bidder uses GBP as its
    // currency.
    billing_id: 123
    billing_id: 456
    // The bid floor, as indicated by this field, is in micro units of the currency used
    // by the buyer indicated by the billing IDs. In this case, suppose the buyer uses
    // GBP. Then this field represents an £8 CPM floor.
    minimum_cpm_micros: 8000000
    direct_deal {
      direct_deal_id: 2000
      // In Google RTB, the deal price is indicated in CPM micros of the buyer's
      // currency.
      fixed_cpm_micros: 20000000
      ...
    }
  }
  matching_ad_data {
    // Suppose that the bidder has a child seat with billing ID 789. Also suppose the
    // child seat has billing ID 789 and uses USD as its currency.
    billing_id: 789
    // All MatchingAdData.minimum_cpm_micros in a given bid request represent the same
    // monetary value. In this case, suppose that the buyer uses USD and that the
    // conversion rate from GBP to USD is 1.25. Then this field represents a $10 CPM
    // floor, which is the same monetary value as the above £8 CPM floor.
    minimum_cpm_micros: 10000000
    direct_deal {
      direct_deal_id: 1000
      ...
    }
  }
}
    

While the OpenRTB bid request contains similar information, it stores billing IDs and deals in separate flat lists, so it is no longer possible to determine which billing IDs are associated with a given deal ID based solely on the bid request. We recommend storing the billing IDs associated with deals in order to determine which are applicable for a given deal at bidding time.

// OpenRTB bid request
imp {
  // In OpenRTB, the bid floor is in CPM, rather than CPM micros. It is in units of the
  // currency indicated by `bidfloorcur`.
  bidfloor: 10
  bidfloorcur: "USD"
  ext {
    // The billing IDs of all of the bidder's matching pretargeting configs and all of
    // its eligible child seats are stored in a flat list here.
    billing_id: 123
    billing_id: 456
    billing_id: 789
  }
  pmp {
    // All eligible deals are stored in a single flat list.
    deal {
      id: 1000
      // In OpenRTB, the deal floor is in CPM, not CPM micros.
      bidfloor: 20
      // In OpenRTB, all deals use the same currency. This currency is indicated by
      // the `Deal.bidfloorcur` field.
      bidfloorcur: "USD"
      ...
    }
    deal {
      id: 2000
      ...
    }
  }
}
    

Ad Categories

Ad categories describe the content of an ad, and are used by publishers to describe types of ads that are blocked when bidding on their inventory. Both Google RTB and OpenRTB support communicating blocked categories in the bid request, and declaring categories for ads returned in the bid response. However, they use different fields and taxonomies to define those categories.

Blocked Categories

When you place a bid, the included creative must not have detected categories that were blocked by the publisher, otherwise the bid will be filtered from the auction.

OpenRTB doesn't distinguish between "product" and "sensitive" categories, so it doesn't use distinct fields like Google RTB's BidRequest.adslot.excluded_product_category and BidRequest.adslot.excluded_sensitive_categories to describe blocked categories. Instead, it uses the BidRequest.bcat to identify all blocked categories, using IAB Content 1.0 taxonomy rather than Google's taxonomy defined in the ad-product-categories.txt and ad-sensitive-categories.txt reference files.

// Bid request
{
  // Indicates the blocked categories using IAB Content 1.0 Taxonomy.
  "bcat": [
    "IAB8-18",  // Wine
    "IAB9-9"    // Cigars
  ]
  "imp": {
    ...
  }
}
    

Detected Categories

Google detects categories for ads when they are submitted for review. In order to submit your ads and identify the categories associated with them, Google recommends that you use the creatives resource from the Real-time Bidding API. You can use the detectedCategories field to find the detected categories for a creative in IAB Content 1.0 taxonomy. You can reduce bid filtering by not bidding with creatives with detected categories that appear in BidRequest.bcat.

Declare Categories

When submitting a creative for review with a bid, you can declare its categories with OpenRTB in IAB Content 1.0 taxonomy using the BidResponse.seatbid.bid.cat field. This lets you declare any category, whereas Google RTB only supports the declaration of sensitive categories with the BidResponse.ad.category field.

Macros

Google continues to support existing macros on the creative and in impression tracking URLs. These macros will be expanded within creatives and impression tracking URLs submitted on the OpenRTB protocol.

In addition, Google will also support the following macros from the OpenRTB standard:

OpenRTB macro Description
${AUCTION_ID} ID of the bid request; from OpenRTB's BidRequest.id field.
${AUCTION_BID_ID} ID of the bid; from OpenRTB's BidResponse.bid.id field.
${AUCTION_IMP_ID} ID of the impression just won; from OpenRTB's BidRequest.imp.id attribute.
${AUCTION_SEAT_ID} ID of the bidder seat for whom the bid was made.
${AUCTION_AD_ID} ID of the ad markup the bidder wishes to serve; from OpenRTB's BidResponse.seatbid.bid.adid attribute.
${AUCTION_PRICE} Encoded impression cost in CPI micros of the buyer account currency. This is different from what is specified in the OpenRTB Standard. The macro will have the exact same behavior as Google's %%WINNING_PRICE%% macro.

Native Ads

Access NativeRequest and NativeResponse based on OpenRTB format

If you have configured a bidding endpoint to use OpenRTB in the JSON format, incoming bid requests can include a serialized JSON native markup request object passed in the BidRequest.imp.native.request field to represent native ad inventory, which is comparable to Google RTB protocol's NativeAdTemplate. In order for your bidding endpoint to respond with a bid containing a native ad, it must populate BidResponse.seatbid.bid.adm with a serialized JSON native markup response object, which is comparable to Google RTB protocol's NativeAd message. These native markup objects can be found in the OpenRTB Native Ads Specification, and will be referred to as NativeRequest and NativeResponse throughout the documentation.

Google's OpenRTB protobuf format uses NativeRequest and NativeResponse protocol buffer messages that correspond to OpenRTB's native markup objects, and can appear directly as fields in bid requests and bid responses, respectively. If your bidding endpoint is configured to use OpenRTB in the Protobuf format, incoming bid requests can include the BidRequest.imp.native.request_native field to represent native ad inventory, which is the NativeRequest message defined in the proto rather than a serialized JSON object. Similarly, your bidding endpoint must populate BidResponse.seatbid.bid.adm_native to respond with a bid containing a native ad, which also uses the NativeResponse defined in the proto rather than a serialized JSON object.

The NativeRequest and NativeResponse objects or messages contain identical fields in both formats, so to simplify mapped field paths seen in the migration content for NativeAdTemplate and NativeAd, we will use {request/request_native} and {adm/adm_native} to indicate portions of the field path that are dependent on the format. For example, the full field path for NativeRequest.assets would be represented as BidRequest.imp.native.{request/request_native}.assets.

Representation of native ad templates in OpenRTB

In a bid request including native inventory, the Google RTB Protocol describes the native ad template with a static set of attributes, whereas OpenRTB represents most of these in BidRequest.imp.native.{request/request_native}.assets, which is a list of Asset that describes components of the native ad–such as the headline, body, or logo. Each asset included in the request has a unique id value.

When placing a bid including a native ad, your bidding endpoint must specify the required assets and any optional assets you choose to include in the BidResponse.seatbid.bid.{adm/adm_native}.assets field. Assets sent in the response must include the corresponding id value specified in the bid request—this is used to structure the template and distinguish similar kinds of assets such as logos and icons. Here's an example demonstrating how NativeRequest is populated and its corresponding NativeResponse:

OpenRTB JSON (parsed)

OpenRTB Protobuf