OpenRTB Extensions

Conventions

OpenRTB 2.5 permits exchanges to define their own extensions to any object from the spec.
These fall under the ext property of JSON objects.

If ext is defined on an object, Prebid Server uses the following conventions:

ext in “Request objects” uses ext.prebid and/or ext.{anyBidderCode}.

ext on “Response objects” uses ext.prebid and/or ext.bidder.
The only exception here is the top-level BidResponse, because it’s bidder-independent.

ext.{anyBidderCode} and ext.bidder extensions are defined by bidders.
ext.prebid extensions are defined by Prebid Server.

Exceptions are made for DigiTrust and GDPR, so that we define ext according to the official recommendations.

Bid Adjustments

Bidders are encouraged to make Net bids. However, there’s no way for Prebid to enforce this.
If you find that some bidders use Gross bids, publishers can adjust for it with request.ext.prebid.bidadjustmentfactors:

{
"appnexus: 0.8,
"rubicon": 0.7
}

This may also be useful for publishers who want to account for different discrepancies with different bidders.

The list of price granularity ranges must be given in order of increasing max values. If precision is omitted, it will default to 2. The minimum of a range will be 0 or the previous max. Any cmp above the largest max will go in the max pricebucket.

For backwards compatibility the following strings will also be allowed as price granularity definitions. There is no guarantee that these will be honored in the future. “One of [‘low’, ‘med’, ‘high’, ‘auto’, ‘dense’]” See price granularity definitions

One of “includewinners” or “includebidderkeys” must be true (both default to true if unset). If both were false, then no targeting keys would be set, which is better configured by omitting targeting altogether.

Response format (returned in bid.ext.prebid.targeting)

{
"hb_bidder_{bidderName}": "The seatbid.seat which contains this bid",
"hb_size_{bidderName}": "A string like '300x250' using bid.w and bid.h for this bid",
"hb_pb_{bidderName}": "The bid.cpm, rounded down based on the price granularity."
}

The winning bid for each request.imp[i] will also contain hb_bidder, hb_size, and hb_pb
(with no {bidderName} suffix). To prevent these keys, set request.ext.prebid.targeting.includeWinners to false.

NOTE: Targeting keys are limited to 20 characters. If {bidderName} is too long, the returned key
will be truncated to only include the first 20 characters.

Cookie syncs

Each Bidder should receive their own ID in the request.user.buyeruid property.
Prebid Server has three ways to popualte this field. In order of priority:

If the request payload contains request.user.buyeruid, then that value will be sent to all Bidders.
In most cases, this is probably a bad idea.

The request payload can store a buyeruid for each Bidder by defining request.user.ext.prebid.buyeruids like so:

{
"appnexus": "some-appnexus-id",
"rubicon": "some-rubicon-id"
}

Prebid Server’s core logic will preprocess the request so that each Bidder sees their own value in the request.user.buyeruid field.

If you’re using another client, you can populate the Cookie of the Prebid Server host with User IDs
for each Bidder by using the /cookie_sync endpoint, and calling the URLs that it returns in the response.

Native Request

For each native request, the assets objects’s id field must not be defined. Prebid Server will set this automatically, using the index of the asset in the array as the ID.

Bidder Aliases

Requests can define Bidder aliases if they want to refer to a Bidder by a separate name.
This can be used to request bids from the same Bidder with different params. For example:

For all intents and purposes, the alias will be treated as another Bidder. This new Bidder will behave exactly
like the original, except that the Response will contain seprate SeatBids, and any Targeting keys
will be formed using the alias’ name.

If an alias overlaps with a core Bidder’s name, then the alias will take precedence.
This prevents breaking API changes as new Bidders are added to the project.

For example, if the Request defines an alias like this:

{
"aliases": {
"appnexus": "rubicon"
}
}

then any imp.ext.appnexus params will actually go to the rubicon adapter.
It will become impossible to fetch bids from Appnexus within that Request.

Bidder Response Times

response.ext.responsetimemillis.{bidderName} tells how long each bidder took to respond.
These can help quantify the performance impact of “the slowest bidder.”

Bidder Errors

response.ext.errors.{bidderName} contains messages which describe why a request may be “suboptimal”.
For example, suppose a banner and a video impression are offered to a bidder
which only supports banner.

In cases like these, the bidder can ignore the video impression and bid on the banner one.
However, the publisher can improve performance by only offering impressions which the bidder supports.

Cache bids

Bids can be temporarily cached on the server by sending the following data as request.ext.prebid.cache:

{
"bids": {},
"vastxml": {}
}

Both bids and vastxml are optional, but one of the two is required. Thils property will have no effect
unless request.ext.prebid.targeting is also set in the request.

If bids is present, Prebid Server will make a best effort to include these extra
bid.ext.prebid.targeting keys:

hb_cache_id: On the highest overall Bid in each Imp.

hb_cache_id_{bidderName}: On the highest Bid from {bidderName} in each Imp.

Clients should not assume that these keys will exist, just because they were requested, though.
If they exist, the value will be a UUID which can be used to fetch Bid JSON from Prebid Cache.
They may not exist if the host company’s cache is full, having connection problems, or other issues like that.

If vastxml is present, PBS will try to add analogous keys hb_uuid and hb_uuid_{bidderName}.
In addition to the caveats above, these will exist only if the relevant Bids are for Video.
If they exist, the values can be used to fetch the bid’s VAST XML from Prebid Cache directly.

Deprecated Properties

The error message in the response should describe how to “fix” the request to make it legal.
If the message is unclear, please log an issue
or submit a pull request to improve it.

Determining Bid Security (http/https)

In the OpenRTB spec, request.imp[i].secure says:

Flag to indicate if the impression requires secure HTTPS URL creative assets and markup,
where 0 = non-secure, 1 = secure. If omitted, the secure state is unknown, but non-secure
HTTP support can be assumed.

In Prebid Server, an https request which does not define secure will be forwarded to Bidders with a 1.
Publishers who run https sites and want insecure ads can still set this to 0 explicitly.