Bid Adjustments is a Prebid feature that automatically alters a bid using a specified formula. It can be set up for each bidder individually, or as a global default rule.
When bidding, some bidders may return a gross CPM, while others (like AdX) will return a net CPM. Bid Adjustments allow you to level the playing field and hold a fair auction.
Within an SSP’s bidResponse, the netRevenue attribute will be set to true if the bid’s CPM is net and false if it isn’t. Here is a small javascript script that will return the content of that field for each bidder that took part in the latest auction. Simply run it in the developer console, on one of your webpages:
Object.values( pbjs.getBidResponses() ).forEach(
response => response.bids.forEach(
bid => console.log(bid.bidder, ": Net =", bid.netRevenue)
)
);
However, keep in mind that this field is only declarative and not binding. If in doubt, ask your SSP directly, or compare your SSP’s reporting with another data source.
For example, at Pubstack, when starting to work with a new publisher, we will sometimes notice a steady discrepancy between our data and what an SSP will report. It usually means the SSP is bidding in gross and their bid’s CPM is not being adjusted.
Bid Adjustments are configured in Prebid’s bidderSettings.
To check your current adjustments, run the following piece of code in your dev console:
Object.entries(pbjs.bidderSettings).filter(
([,v]) => v.bidCpmAdjustment !== undefined
).forEach(
([k,v])=> console.log(k, ": CPM(1) => ", v.bidCpmAdjustment(1, {}))
);
To implement or update your bid adjustments, you need to edit your bidderSettings as explained in the Prebid documentation:
pbjs.bidderSettings = {
standard: { bidCpmAdjustment: cpm => cpm * 1.2 },
appnexus: { bidCpmAdjustment: cpm => cpm * 1.1 }
};
Use “standard” to create rules applied to all bidders.
Note that if you add a rule for a specific bidder (in our example, Appnexus), then it will override the “standard” rule. ⚠️
While you will usually apply a multiplier through the bid adjustment feature, note that it can also be used to apply any rule that you would like to your bid responses’ CPMs.
For example, the following rule will essentially apply a 0.20 floor except for Rubicon:
pbjs.bidderSettings = {
standard: {
bidCpmAdjustment: function(cpm, bid) {
if ( cpm < 0.2 && bid.bidderCode != 'rubicon' ) { cpm = 0 }
}
}
};
Alternatively, this next one will slightly increase all returned CPMs, giving Prebid an edge in the competition against GAM:
pbjs.bidderSettings = {
standard: { bidCpmAdjustment: cpm => cpm * 1.05 }
};
Another possibility is to create rules based on the mediaType:
pbjs.bidderSettings = {
standard: {
bidCpmAdjustment: function(cpm, bid) {
if ( bid.mediaType != 'banner' ) { cpm = cpm*1.1 }
}
}
};
Basically, any information contained in the bid can be used to define custom bid adjustments.
Find out more on Prebid’s documentation.
Now that you know how to manage bid adjustments on Prebid, we encourage you to look into price granularity, as your granularity rules could make or break your programmatic revenue ! If you’re not yet familiar with granularity, we’ve prepare an article to help you out : Price Granularity Unraveled: How to Retain Maximum Value.
In the quest to run fair auctions for every single user, things can actually easily go wrong during an update. The best option remains to continuously monitor your ad stack to track any dip in your key metrics, as detailed in our business case “Header Bidding Integration Issue”.