
Over six articles we have now taken the bid request apart field by field. The impression. The user. The device. The consent string. Each in its own drawer of the same cabinet.
But I have quietly skipped the most obvious question of all. Why does any of it mean anything to the buyer at the other end?
When your SSP sends "w": 300, "h": 250, why does a DSP three milliseconds and two thousand kilometers away know that it is a medium rectangle – and not, say, a price in kroner? No one called ahead. There is no per-buyer translation layer. The two systems have in all likelihood never met.
They agree because of OpenRTB. And here is what most people get slightly wrong:
OpenRTB is not a spec you implement. It is a contract you sign – and half of it is deliberately left blank.
Three terms, quickly:
*It saw the light of day inside the IAB back in 2010, built by a coalition of early SSPs and DSPs tired of integrating with each other one custom API at a time. The whole point was to stop doing that.
That last term – ext – is what this article is really about. But let's take the contract in three clauses.
The first job OpenRTB performs is boring and utterly essential: It gives everyone the same nouns.
A site object means a website. A user object means the audience. device.geo means where they are. Those are not your SSP's private definitions, or Google's – they belong to the standard. And that is exactly why your bid request is readable to a buyer who has never once heard of your site.
If you run Prebid, you already speak this vocabulary – perhaps without noticing. When you set first-party data, you are not inventing a format. You are filling in OpenRTB objects:
pbjs.setConfig({
ortb2: {
site: { name: 'domain.dk', cat: ['IAB12'], keywords: 'news,sport' },
user: { yob: 1985, gender: 'M' },
device: { ua: navigator.userAgent }
}
});
That ortb2 key is not subtle naming. It is literally "OpenRTB 2.x". Prebid never invented its own request format – it speaks OpenRTB under the hood and maps your config directly into the objects above.* Each adapter then translates it into exactly the dialect its SSP expects.
*Prebid Server does the same on the server side, firing real OpenRTB 2.x requests off to each bidder.
That is the grammar sitting quietly beneath every object we have discussed since part 0. Same nouns, same meanings – a thousand different buyers.
Here is where it gets interesting, and where "contract, not spec" earns its place.
A spec in the rigid sense says: Here are the fields, that is all there is, come back for the next version. OpenRTB refuses that. Almost every object carries an ext – an explicitly blank field where you are allowed to write in things the standard never defined.
Visualization generated with claude.ai
Need to send a Prebid-specific instruction to one bidder? imp.ext.prebid. Want to attach a signal about the page that no standard field captures? site.ext. Does a vendor have a clever new identifier? Into an ext it goes:
"imp": [{
"id": "1",
"banner": {
"w": 300,
"h": 250
},
"ext": {
"prebid": {
"bidder": {
"rubicon": {
"zoneId": "91011"
}
}
}
}
}],
"site": {
"domain": "fyens.dk",
"ext": {
"data": {
"section": "sport"
}
}
}
Note the two levels. imp.ext is about this specific ad slot. site.ext is about the whole page. Same escape-hatch idea, different scope – and getting that scope right is half the craft.
Why design a standard with deliberate blank fields? Because the alternative is worse. Without ext, every genuinely new idea – a new ID, a new privacy signal, a new format hint – would have to wait for a whole new version of the protocol, which the entire market would then have to adopt in unison. Markets do not move at committee pace.
ext is the pressure valve. It is what lets a fifteen-year-old standard absorb things its authors never imagined – without breaking a single running auction.
The standard is deliberately incomplete. That is not a flaw. It is the feature itself.
So if ext is where new ideas live, what happens when an idea actually wins? It gets promoted.
A signal starts in ext – non-standardized, a little fragmented, with each vendor doing it slightly differently. If a large enough share of the market finds it useful, the IAB eventually promotes it to the core spec with a real, named field. The blank field becomes pre-printed in the next version of the contract.
Visualization generated with claude.ai
This is not theoretical. It is most of how OpenRTB has actually evolved:
user.ext.eids for years. OpenRTB 2.6 promoted them to a fully fledged user.eids.source.ext.schain. It is now core, as source.schain.device.sua to carry that signal in a future-proof way – side by side with the old device.ua.
Each of them: born in ext, moved up to core. The contract gets amendments – it does not get torn up.
And we know exactly what tearing it up looks like, because someone tried. OpenRTB 3.0, back in 2017, was a near-total rewrite – cleaner, stricter, more secure. The industry looked at the migration costs and quietly declined. Almost no one adopted it. 2.x was good enough, and "good enough and already in production" beats "better but disruptive" every single time in this industry.
That inertia is the price of a shared contract. The very stability that makes OpenRTB trustworthy also makes it slow to fix its rough edges – it is verbose, it is chatty, and it was designed for a world with far more stable identifiers than we have today. You take the rigidity along with the reliability.
Two of the promoted signals are big enough to deserve their own articles – the supply chain object is part 8, and publisher-defined first-party data is part 9. For now, just hold on to the pattern: ext today, core tomorrow.
You did not write this contract. You cannot. The IAB drafts it, and the market ratifies it through adoption. But you decide how completely you fill it in.
A bid request with rich site data, a populated user.eids and clean first-party signals in ext – that is a buyer who knows exactly what they are bidding on. A half-empty request is a buyer squinting in the dark. And a buyer squinting in the dark bids low – if they bid at all. The fields are free. The standard hands you the form. Leaving it blank is leaving money on the table.
That is the quiet power of a standard. It turns "describe your inventory" from a bespoke negotiation with every single buyer into one form – filled in once, understood everywhere.
OpenRTB is a contract, not a spec.
The value was never any single field. It was the agreement that a field means the same thing at both ends of the wire.
This is the seventh article in the nine-part series What is actually hiding in a bid request?
Next time, part 8: Trust & transparency in the supply chain. We have now established that everyone speaks the same language – so the next question is whether you can trust who is actually in the conversation. That is where schain, ads.txt and sellers.json come in: the part of the request that proves the path back to you is real.
Next: Part 8 of 9: Trust & transparency in the supply chain →
Let us help you get the most out of your display campaigns.