The point of header bidding is to supply bids into the regular ad server calls. Prebid.js provides many ways to do this. This document describes the controls for obtaining auction results.
Here’s the general way PBJS is integrated into the page:
This last step has historically been called “targeting” in Prebid.js, but really what’s sent to the adserver is a set of Key Value Pairs (KVPs) that serve several purposes:
How a publisher should configure Prebid.js to report auction results will depend on how the final ad decision will be made. These approaches need to be in sync.
There are four main scenarios, described in the following sections.
In order to have header bidding compete with direct-sold demand, a publisher can set up placeholder line items in their ad server.
Prebid.org recommends setting up separate line items for each bidder. Benefits to this approach include:
There are more details on this scenario in the Ad Ops section.
Once implemented in the ad server, setting this up in Prebid.js is simple, as it is the default Send All Bids mode. However to limit the number of values sent to the ad server, some flavor of this solution like the Top Two Bids and Deals may be of interest.
Note that enableSendAllBids
mode can send a lot of keys to your
ad server. Though we recommend this setting, we also recommend that
publishers monitor the key traffic and control as necessary.
There are reasons a publisher may not want to create separate line items for each bidder. For example:
So the other ad-server based solution is to create one set of line items that is used by all bidders.
Setting this mode up in Prebid.js is done by setting enableSendAllBids to false. See the Bare Minimum solution for reference.
See Send All Bids vs Top Price for ad ops details on this scenario.
Sometimes Prebid.js is used as a fallback. This mode is called PostBid
In this scenario, the ad server line item is scheduled as a low-priority ‘remnant’ and the auction takes place when there’s nothing else to serve. The Prebid.js code is in the ad server creative, which decides the overall winner itself. See the Post Bid Example.
Finally, a publisher may want a particular ad unit to be programmatic-only, which Prebid.js can support. Please see the No Ad Server Example.
In early versions of Prebid.js, there were a couple of basic functions publishers could use to get the auction results:
All of the other functions available in the publisher API for obtaining auction bids came later.
When there are a lot of adunits and bidders on a page, the number of KVPs being sent to the ad server can grow pretty large, so it quickly became apparent that many options were needed for controlling which KVPs these functions returned.
Note that in old versions of Prebid.js, native ad components were passed via ad server KVPs. That approach has been deprecated – all implementations should now use one of the recommended approaches for native.
Video’s always been a different implementation than banners because it’s the video player that controls the ad call, not in-page JavaScript like the GPT library. So the Google Ad Manager Video module includes the buildVideoUrl function.
Publishers using other ad servers need to integrate on their own using the pbjs.getAdserverTargetingForAdUnitCode function to build whatever needed to pass to the video player.
The Prebid SDK does not have a direct way to control what key-value pairs will be generated by Prebid Server. Instead, the top-level stored request stored in Prebid Server defines what should be produced.
That stored request will contain the ‘targeting’ options needed to match the line item setup. See the Prebid-Server-based targeting configuration, for more detail. The rest of this document is about Prebid.js.
Over the years, quite a few options have been added to to Prebid.js to adjust the number of bids and the exact set of KVPs sent to the ad server. This is an overlapping-but-powerful set of controls. There are often multiple ways to implement the same requirements, and there’s no “wrong” way to do it.
The list is ordered by those functions that Prebid recommends starting with:
Here are a few scenarios to give you a sense of the configurability.
If the number of KVPs sent to the ad server is not a concern, then the recommended approach is to Send All Bids and all deals:
pbjs.setConfig({
enableSendAllBids: true,
targetingControls: {
alwaysIncludeDeals: true
}
});
The opposite approach is to send only the winning set of KVPs directly needed for targeting line items and rendering.
pbjs.setConfig({
enableSendAllBids: false,
targetingControls: {
allowTargetingKeys: ['PRICE_BUCKET', 'AD_ID', 'SIZE']
}
});
Note: This example lacks video support, deal support, and doesn’t even tell you which bidder won.
pbjs.setConfig({
sendBidsControl: { bidLimit: 2 },
targetingControls: {
alwaysIncludeDeals: true,
allowTargetingKeys: ['BIDDER', 'AD_ID',
'PRICE_BUCKET', 'SIZE', 'UUID', 'FORMAT', 'DEAL'],
allowSendAllBidsTargetingKeys: ['AD_ID', 'PRICE_BUCKET', 'SIZE',
'FORMAT', 'DEAL']
}
});
Note: This assumes that video creatives are set up refering to HB_UUID rather than bidder-specific UUID values.
Publishers that don’t want to use KVPs prefixed with “hb_” can change them with bidderSettings:
pbjs.setConfig({
enableSendAllBids: false
});
pbjs.bidderSettings={
standard: {
adserverTargeting: [{
key: "pb_price",
// note the price granularity assumption below is Medium Granularity
// other options are pbAg (auto), pbCg (custom), pbDg (dense),
// pbHg (high), pbLg (low)
val: function(bidResponse) { return bidResponse.pbMg; }
},{
key: "pb_size",
val: function(bidResponse) { return bidResponse.size; }
},{
key: "pb_adid",
val: function(bidResponse) { return bidResponse.adId; }
},{
key: "pb_uuid",
val: function(bidResponse) { return bidResponse.videoCacheKey; }
},{
key: "pb_format",
val: function(bidResponse) { return bidResponse.mediaType; }
},{
key: "pb_bidder",
val: function(bidResponse) { return bidResponse.bidder; }
},{
key: "pb_deal",
val: function(bidResponse) { return bidResponse.dealId; }
}]
}
};