RTB Architecture
OpenRTB 2.6 explained: a bid request example, field by field
Published · Last updated
Next scheduled review:
OpenRTB 2.6 is the IAB Tech Lab protocol that exchanges and bidders use to trade one ad impression in real time. An OpenRTB bid request is a JSON object describing the impression, the page or app, the device, the user and the privacy rules. Below are two complete, valid examples, display and CTV, with every field explained.
Contents
Key facts
- 2.6 is a living version. OpenRTB 2.6 was first published in April 2022 and moved to GitHub as baseline release 2.6-202210 on 3 November 2022 (openrtb2.x releases). The latest snapshot is 2.6-202606 of 11 June 2026, which added
realtime,firstbroadcastand two discount macros (2.6-202606 release notes, 11 June 2026). - The version number only moves on breaking changes. Since 2.6-202211, IAB Tech Lab ships additive changes as dated releases of 2.6 and expects bidders to ignore fields they do not know (OpenRTB 2.6, section 2.6).
- Ad pods are the headline feature. The 2.5 to 2.6 change log adds
podid,podseq,slotinpod,poddur,maxseq,mincpmpersecandrqddursfor video and audio, plusmtypeon the bid (OpenRTB 2.6, Appendix B). The bid object also carriesdurandslotinpodso a buyer can state creative length and slot (OpenRTB 2.6, Object: Bid). - Privacy moved into core fields.
regs.gdpranduser.consentleftextin 2.6, andregs.gppplusregs.gpp_sidarrived in release 2.6-202211 on 17 November 2022 (2.6-202211 release notes). - Enumerations live in AdCOM. OpenRTB 2.6 removed its own enumerated lists and points to AdCOM 1.0, where content taxonomy values 1 and 2 are now marked deprecated (AdCOM 1.0, List: Category Taxonomies).
Definition
OpenRTB 2.6: version 2.6 of IAB Tech Lab's Real-Time Bidding API. It defines the JSON bid request an exchange posts to bidders and the bid response they return, with enumerated values kept in AdCOM 1.0. See the glossary entries for OpenRTB, bid request and bid response.
If you need the auction itself explained first, read how real-time bidding works. This page assumes you know that an exchange sends a request, bidders answer within a time limit, and one bid wins.
How an OpenRTB 2.6 bid request is structured
A request is one top-level BidRequest object. It holds an array of Imp objects, one per impression on offer. Each Imp carries exactly the media objects it allows: banner, video, audio or native. Around the impressions sit context objects: site or app (or dooh for screens), device, user, source and regs. The full object model is in section 3.1 of the OpenRTB 2.6 specification.
The transport rules are short. The exchange sends the request as HTTP POST with Content-Type: application/json and a version header. A bidder that does not want to bid returns HTTP 204 with no body, the cheapest option (OpenRTB 2.6, sections 2.1 and 2.5). The header looks like this:
POST /bid HTTP/1.1
Content-Type: application/json
x-openrtb-version: 2.6A no-bid with a reason code is also valid. Reason code 2 means "Invalid Request" in the OpenRTB 3.0 list of no-bid reason codes, which OpenRTB 2.6 reuses:
{ "id": "b7e1c0a2-5f3d-4e8a-9c41-2d6f8a0b9e17", "seatbid": [], "nbr": 2 }OpenRTB bid request example: a display impression
The first example is a desktop visit to a German news article with one medium rectangle slot. The site runs header bidding, so the ad server makes the final call. GDPR applies, and the request also carries a private deal. All domains use the reserved .example and example.com names, IP addresses come from documentation ranges, and IDs are invented. Taxonomy IDs, enumerated values and the privacy strings are real values taken from the IAB Tech Lab repositories.
{
"id": "b7e1c0a2-5f3d-4e8a-9c41-2d6f8a0b9e17",
"imp": [
{
"id": "1",
"tagid": "article-mpu-1",
"banner": {
"format": [
{ "w": 300, "h": 250 },
{ "w": 300, "h": 600 }
],
"pos": 1,
"battr": [3, 8]
},
"bidfloor": 0.85,
"bidfloorcur": "EUR",
"secure": 1,
"metric": [
{ "type": "viewability", "value": 0.72, "vendor": "EXCHANGE" }
],
"pmp": {
"private_auction": 0,
"deals": [
{
"id": "DEAL-NEWS-DE-001",
"bidfloor": 3.5,
"bidfloorcur": "EUR",
"at": 1,
"wseat": ["seat-123"]
}
]
}
}
],
"site": {
"id": "site-4821",
"name": "Example News",
"domain": "example.com",
"page": "https://www.example.com/wirtschaft/zinsen-bleiben-stabil",
"ref": "https://www.example.com/",
"cattax": 9,
"cat": ["52"],
"pagecat": ["391"],
"publisher": {
"id": "pub-1047",
"name": "Example Media GmbH",
"domain": "example.com"
},
"content": {
"language": "de"
}
},
"device": {
"ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
"sua": {
"browsers": [
{ "brand": "Google Chrome", "version": ["142"] },
{ "brand": "Chromium", "version": ["142"] },
{ "brand": "Not_A Brand", "version": ["99"] }
],
"platform": { "brand": "Windows" },
"mobile": 0,
"source": 1
},
"ip": "192.0.2.0",
"devicetype": 2,
"language": "de",
"js": 1,
"dnt": 0,
"geo": {
"country": "DEU",
"type": 2,
"utcoffset": 60
}
},
"user": {
"id": "exch-7d9e2f41",
"buyeruid": "dsp-55ab31c9",
"consent": "CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA",
"eids": [
{
"source": "pubcid.org",
"inserter": "example.com",
"mm": 4,
"uids": [
{ "id": "c29cb2ae-769d-42f6-891a-f53cadee823d", "atype": 1 }
]
}
]
},
"source": {
"fd": 1,
"tid": "4f6a2b8e-91c3-4d7e-a5b0-c8e2f1d36a94",
"schain": {
"complete": 1,
"ver": "1.0",
"nodes": [
{ "asi": "ssp-alpha.example", "sid": "pub-1047", "hp": 1 }
]
}
},
"regs": {
"gdpr": 1,
"gpp": "DBABM~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA",
"gpp_sid": [2]
},
"at": 1,
"tmax": 300,
"cur": ["EUR"],
"cattax": 8,
"bcat": ["1361", "1544"],
"badv": ["competitor-bank.example"]
}The display request, field by field
34 of 34 rows
BidRequest |
| string, required | Auction ID set by the exchange | The response must echo it; it fills the |
BidRequest |
| object array, required | Impressions on offer | At least one |
Imp |
| string, required | Impression ID inside this request |
|
Imp |
| string | Placement or ad tag ID | Useful for debugging and buyer optimisation |
Banner |
| object array | Sizes the slot accepts | Here 300x250 and 300x600 |
Banner |
| integer | Ad position, AdCOM list "Placement Positions" | 1 = above the fold |
Banner |
| integer array | Blocked creative attributes, AdCOM list | 3 = expandable (automatic), 8 = pop |
Imp |
| float, string | Minimum CPM and its currency | Currency defaults to USD if absent |
Imp |
| integer | 1 = creative must use HTTPS | Non-secure markup is rejected |
Metric |
| string, float, string | A metric the exchange supplies, such as predicted viewability | Names agreed in advance; "EXCHANGE" when the exchange computed it |
Pmp |
| integer | 0 = open auction bids also accepted | 1 would restrict bidding to the listed deals |
Deal |
| string, float, string, integer, string array | The deal ID, its floor, auction type and allowed seats |
|
Site |
| string | Where the ad will appear and the referrer |
|
Site |
| integer, string arrays | Site and page categories and the taxonomy used | 9 = Content Taxonomy 3.1; 52 = Business and Finance; 391 = Personal Finance |
Publisher |
| string | The seller of the impression |
|
Content |
| string | Content language, ISO 639-1 | Use |
Device |
| string | Raw user-agent header | Still recommended for compatibility |
Device |
| object | Structured user agent from client hints |
|
Device |
| string | IPv4 address closest to the device | Truncated here, a common practice under GDPR |
Device |
| integer, string, integer, integer | Device type, browser language, JavaScript support, Do Not Track |
|
Geo |
| string, integer, integer | ISO 3166-1 alpha-3 country, location source, minutes from UTC | "DEU"; |
User |
| string | Exchange user ID and the buyer's synced ID |
|
User |
| string | TCF TC string when GDPR applies | This is the example string from the GPP specification |
EID |
| string, string, integer, object array | One extended ID: here SharedID ( |
|
Source |
| integer | Who makes the final sale decision | 1 = an upstream source, typical for header bidding |
Source |
| string | Transaction ID shared by every exchange that sees this impression | Lets buyers spot the same impression arriving twice |
SupplyChain |
| integer, string, object array | Every seller between publisher and buyer | One node = a direct sale |
SupplyChainNode |
| string, string, integer | Exchange domain, seller account, payment flag |
|
Regs |
| integer | 1 = GDPR applies | Omitted means unknown |
Regs |
| string, integer array | Global Privacy Platform string and the section that applies | Section 2 = EU TCF v2 |
BidRequest |
| integer | Auction type | 1 = first price, 2 = second price plus |
BidRequest |
| integer | Milliseconds the exchange will wait | Includes network latency |
BidRequest |
| string array | Currencies accepted for bids | ISO 4217 codes |
BidRequest |
| integer, string arrays | Blocked advertiser categories and domains | 8 = Ad Product Taxonomy 2.0; 1361 = Gambling, 1544 = Tobacco |
BidRequest
- Field
id- Type
string, required
- Meaning
Auction ID set by the exchange
- Notes
The response must echo it; it fills the
${AUCTION_ID}macro
BidRequest
- Field
imp- Type
object array, required
- Meaning
Impressions on offer
- Notes
At least one
Imp
Imp
- Field
id- Type
string, required
- Meaning
Impression ID inside this request
- Notes
Bid.impidmust match it
Imp
- Field
tagid- Type
string
- Meaning
Placement or ad tag ID
- Notes
Useful for debugging and buyer optimisation
Banner
- Field
format- Type
object array
- Meaning
Sizes the slot accepts
- Notes
Here 300x250 and 300x600
Banner
- Field
pos- Type
integer
- Meaning
Ad position, AdCOM list "Placement Positions"
- Notes
1 = above the fold
Banner
- Field
battr- Type
integer array
- Meaning
Blocked creative attributes, AdCOM list
- Notes
3 = expandable (automatic), 8 = pop
Imp
- Field
bidfloor,bidfloorcur- Type
float, string
- Meaning
Minimum CPM and its currency
- Notes
Currency defaults to USD if absent
Imp
- Field
secure- Type
integer
- Meaning
1 = creative must use HTTPS
- Notes
Non-secure markup is rejected
Metric
- Field
type,value,vendor- Type
string, float, string
- Meaning
A metric the exchange supplies, such as predicted viewability
- Notes
Names agreed in advance; "EXCHANGE" when the exchange computed it
Pmp
- Field
private_auction- Type
integer
- Meaning
0 = open auction bids also accepted
- Notes
1 would restrict bidding to the listed deals
Deal
- Field
id,bidfloor,bidfloorcur,at,wseat- Type
string, float, string, integer, string array
- Meaning
The deal ID, its floor, auction type and allowed seats
- Notes
Deal.bidfloorcurdoes not inheritImp.bidfloorcur;at3 would mean a fixed deal price
Site
- Field
domain,page,ref- Type
string
- Meaning
Where the ad will appear and the referrer
- Notes
pageis the full URL
Site
- Field
cattax,cat,pagecat- Type
integer, string arrays
- Meaning
Site and page categories and the taxonomy used
- Notes
9 = Content Taxonomy 3.1; 52 = Business and Finance; 391 = Personal Finance
Publisher
- Field
id,name,domain- Type
string
- Meaning
The seller of the impression
- Notes
idis theseller_idin the exchange's sellers.json and matches the lastschainnode
Content
- Field
language- Type
string
- Meaning
Content language, ISO 639-1
- Notes
Use
langbinstead for BCP 47 tags
Device
- Field
ua- Type
string
- Meaning
Raw user-agent header
- Notes
Still recommended for compatibility
Device
- Field
sua- Type
object
- Meaning
Structured user agent from client hints
- Notes
source1 = only low-entropy hints were available
Device
- Field
ip- Type
string
- Meaning
IPv4 address closest to the device
- Notes
Truncated here, a common practice under GDPR
Device
- Field
devicetype,language,js,dnt- Type
integer, string, integer, integer
- Meaning
Device type, browser language, JavaScript support, Do Not Track
- Notes
devicetype2 = personal computer
Geo
- Field
country,type,utcoffset- Type
string, integer, integer
- Meaning
ISO 3166-1 alpha-3 country, location source, minutes from UTC
- Notes
"DEU";
type2 = derived from IP
User
- Field
id,buyeruid- Type
string
- Meaning
Exchange user ID and the buyer's synced ID
- Notes
buyeruidcomes from cookie sync
User
- Field
consent- Type
string
- Meaning
TCF TC string when GDPR applies
- Notes
This is the example string from the GPP specification
EID
- Field
source,inserter,mm,uids- Type
string, string, integer, object array
- Meaning
One extended ID: here SharedID (
pubcid.org) added by the publisher- Notes
mm4 = observed first-party ID;atype1 = browser or device ID
Source
- Field
fd- Type
integer
- Meaning
Who makes the final sale decision
- Notes
1 = an upstream source, typical for header bidding
Source
- Field
tid- Type
string
- Meaning
Transaction ID shared by every exchange that sees this impression
- Notes
Lets buyers spot the same impression arriving twice
SupplyChain
- Field
complete,ver,nodes- Type
integer, string, object array
- Meaning
Every seller between publisher and buyer
- Notes
One node = a direct sale
SupplyChainNode
- Field
asi,sid,hp- Type
string, string, integer
- Meaning
Exchange domain, seller account, payment flag
- Notes
hp1 = this node handles payment
Regs
- Field
gdpr- Type
integer
- Meaning
1 = GDPR applies
- Notes
Omitted means unknown
Regs
- Field
gpp,gpp_sid- Type
string, integer array
- Meaning
Global Privacy Platform string and the section that applies
- Notes
Section 2 = EU TCF v2
BidRequest
- Field
at- Type
integer
- Meaning
Auction type
- Notes
1 = first price, 2 = second price plus
BidRequest
- Field
tmax- Type
integer
- Meaning
Milliseconds the exchange will wait
- Notes
Includes network latency
BidRequest
- Field
cur- Type
string array
- Meaning
Currencies accepted for bids
- Notes
ISO 4217 codes
BidRequest
- Field
cattax,bcat,badv- Type
integer, string arrays
- Meaning
Blocked advertiser categories and domains
- Notes
8 = Ad Product Taxonomy 2.0; 1361 = Gambling, 1544 = Tobacco
Table by AdSovereign, CC BY 4.0.
Three details in this request trip up new integrations. The deal floor carries its own currency field, because the spec says it does not inherit the impression's. The cattax on the BidRequest describes only bcat, while site.cattax describes the site categories, so one request can use two taxonomies at once. And fd set to 1 tells the buyer that winning this auction is not the end: an ad server downstream still compares the bid with other demand (OpenRTB 2.6, objects Source and Deal).
OpenRTB 2.6 CTV bid request example with an ad pod
The second example is a live sports stream on a connected TV app in New York. The break is a hybrid pod. Impression 1 is a structured slot that the seller guarantees will play first. Impression 2 is a dynamic portion: up to three ads filling up to 90 seconds, the hybrid pattern in the implementation guide's pod examples. Both impressions share one podid, which is how a bidder knows they belong to the same break. Ads are stitched server-side. The supply reaches the buyer through a reseller, so the supply chain has two nodes.
{
"id": "e3a9d6f0-7b21-4c58-8f0e-61b2c4d9a7e3",
"imp": [
{
"id": "1",
"video": {
"mimes": ["video/mp4"],
"protocols": [7, 8, 11, 12, 13, 14],
"w": 1920,
"h": 1080,
"startdelay": -1,
"plcmt": 1,
"linearity": 1,
"skip": 0,
"rqddurs": [15, 30],
"podid": "pod-2",
"podseq": 0,
"slotinpod": 1
},
"bidfloor": 30.0,
"bidfloorcur": "USD",
"ssai": 3,
"exp": 900,
"secure": 1
},
{
"id": "2",
"video": {
"mimes": ["video/mp4"],
"protocols": [7, 8, 11, 12, 13, 14],
"w": 1920,
"h": 1080,
"startdelay": -1,
"plcmt": 1,
"linearity": 1,
"skip": 0,
"rqddurs": [15, 30],
"podid": "pod-2",
"podseq": 0,
"slotinpod": 0,
"poddur": 90,
"maxseq": 3,
"mincpmpersec": 0.75,
"poddedupe": [1, 3]
},
"bidfloor": 11.25,
"bidfloorcur": "USD",
"ssai": 3,
"exp": 900,
"secure": 1,
"pmp": {
"private_auction": 0,
"deals": [
{
"id": "CTV-LIVE-SPORTS-01",
"at": 1,
"wseat": ["seat-123"],
"durfloors": [
{ "maxdur": 15, "bidfloor": 15.0 },
{ "mindur": 16, "bidfloor": 27.0 }
]
}
]
}
}
],
"app": {
"id": "app-5521",
"name": "Example Streaming",
"bundle": "B0EXAMPLE1",
"publisher": {
"id": "4410",
"name": "SSP Alpha",
"domain": "ssp-alpha.example"
},
"content": {
"id": "ep-3301",
"title": "Example League Final",
"livestream": 1,
"realtime": 1,
"firstbroadcast": 1,
"len": 10800,
"language": "en",
"prodq": 1,
"context": 1,
"contentrating": "TV-PG",
"gtax": 9,
"genres": ["483"],
"cattax": 9,
"cat": ["484"],
"network": { "name": "Example Sports Network", "domain": "sportsnetwork.example" },
"channel": { "name": "Example Sports 2", "domain": "sportsnetwork.example" }
}
},
"device": {
"devicetype": 3,
"make": "ExampleTV",
"model": "4K Stick",
"os": "Linux",
"ip": "198.51.100.23",
"ifa": "6d92078a-8246-4ba4-ae5b-76104861e7dc",
"lmt": 0,
"connectiontype": 2,
"geo": {
"country": "USA",
"region": "NY",
"type": 2
}
},
"user": {
"eids": [
{
"source": "uidapi.com",
"inserter": "streaming.example",
"matcher": "uidapi.com",
"mm": 3,
"uids": [
{ "id": "AgAAAAexampleUID2token", "atype": 3 }
]
}
]
},
"source": {
"fd": 0,
"tid": "a1c7e5b3-2d94-4f60-8b1e-9f3a7c5d2e08",
"schain": {
"complete": 1,
"ver": "1.0",
"nodes": [
{ "asi": "ssp-alpha.example", "sid": "pub-2210", "hp": 1 },
{ "asi": "exchange-beta.example", "sid": "4410", "hp": 1 }
]
}
},
"regs": {
"coppa": 0
},
"at": 1,
"tmax": 800,
"cur": ["USD"],
"cattax": 8,
"bcat": ["1001", "1576"]
}The CTV request, field by field
26 of 26 rows
Video |
| string | Pod identifier | Impressions with the same |
Video |
| integer | Position of the pod in the stream | -1 = last pod, 0 = any pod, 1 = first pod |
Video |
| integer | In a request: the slot the seller can guarantee | 1 = first, -1 = last, 2 = first or last, 0 = any |
Video |
| integer array | Exact durations accepted, in seconds | Mutually exclusive with |
Video |
| integer | Seconds the dynamic portion can fill | Required only for dynamic pods or the dynamic part of a hybrid pod |
Video |
| integer | Most ads the dynamic portion can hold | Recommended whenever |
Video |
| float | Floor per second of ad | 0.75 means 11.25 for a 15-second ad and 22.50 for a 30-second ad |
Video |
| integer array | How the seller removes duplicates in the pod | Provisional; 1 = by advertiser domain, 3 = by creative ID |
Video |
| integer | Placement type | 1 = instream; replaced |
Video |
| integer | Where the break sits | -1 = generic mid-roll |
Video |
| integer array | Accepted VAST versions | 7, 8 = VAST 4.0 and wrapper; 11, 12 = 4.1; 13, 14 = 4.2 |
Imp |
| integer | Server-side ad insertion status | 3 = assets and tracking both server-side |
Imp |
| integer | Advisory seconds between auction and playback | Matters for stitched streams that fetch ads ahead of the break |
Imp |
| float | Fallback floor | Buyers should read |
Deal |
| object array | Deal floor by creative duration | Up to 15 s: 15.00; 16 s and longer: 27.00 |
App |
| string | Store ID of the app | Format follows IAB Tech Lab's OTT/CTV store ID guidelines |
Publisher |
| string | Seller account at the exchange that sent the request | Equals the |
Content |
| integer | Scheduled broadcast, happening live, first airing |
|
Content |
| integer, string array | Programme genre from a named taxonomy | 9 = Content Taxonomy 3.1; 483 = Sports in the CTV genre subset |
Content |
| integer, string array | Finer content categories | 484 = American Football |
Content |
| object | TV network and channel carrying the content | Added in 2.6 |
Device |
| integer, string, integer | Device type, resettable advertising ID, limit-ad-tracking flag |
|
EID |
| string, string, integer, object array | A UID2 token from a signed-in viewer |
|
SupplyChain |
| object array | Publisher's SSP, then the reseller exchange | Order runs from the publisher's seller to the last seller |
Regs |
| integer | 0 = not child-directed | A US request usually adds |
BidRequest |
| string array | Blocked advertiser categories | With |
Video
- Field
podid- Type
string
- Meaning
Pod identifier
- Notes
Impressions with the same
podidare slots in one break
Video
- Field
podseq- Type
integer
- Meaning
Position of the pod in the stream
- Notes
-1 = last pod, 0 = any pod, 1 = first pod
Video
- Field
slotinpod- Type
integer
- Meaning
In a request: the slot the seller can guarantee
- Notes
1 = first, -1 = last, 2 = first or last, 0 = any
Video
- Field
rqddurs- Type
integer array
- Meaning
Exact durations accepted, in seconds
- Notes
Mutually exclusive with
mindurationandmaxduration; built for live TV, where a short ad leaves dead air
Video
- Field
poddur- Type
integer
- Meaning
Seconds the dynamic portion can fill
- Notes
Required only for dynamic pods or the dynamic part of a hybrid pod
Video
- Field
maxseq- Type
integer
- Meaning
Most ads the dynamic portion can hold
- Notes
Recommended whenever
podduris sent
Video
- Field
mincpmpersec- Type
float
- Meaning
Floor per second of ad
- Notes
0.75 means 11.25 for a 15-second ad and 22.50 for a 30-second ad
Video
- Field
poddedupe- Type
integer array
- Meaning
How the seller removes duplicates in the pod
- Notes
Provisional; 1 = by advertiser domain, 3 = by creative ID
Video
- Field
plcmt- Type
integer
- Meaning
Placement type
- Notes
1 = instream; replaced
placementin release 2.6-202303
Video
- Field
startdelay- Type
integer
- Meaning
Where the break sits
- Notes
-1 = generic mid-roll
Video
- Field
protocols- Type
integer array
- Meaning
Accepted VAST versions
- Notes
7, 8 = VAST 4.0 and wrapper; 11, 12 = 4.1; 13, 14 = 4.2
Imp
- Field
ssai- Type
integer
- Meaning
Server-side ad insertion status
- Notes
3 = assets and tracking both server-side
Imp
- Field
exp- Type
integer
- Meaning
Advisory seconds between auction and playback
- Notes
Matters for stitched streams that fetch ads ahead of the break
Imp
- Field
bidfloor- Type
float
- Meaning
Fallback floor
- Notes
Buyers should read
mincpmpersecfirst when present
Deal
- Field
durfloors- Type
object array
- Meaning
Deal floor by creative duration
- Notes
Up to 15 s: 15.00; 16 s and longer: 27.00
App
- Field
bundle- Type
string
- Meaning
Store ID of the app
- Notes
Format follows IAB Tech Lab's OTT/CTV store ID guidelines
Publisher
- Field
id- Type
string
- Meaning
Seller account at the exchange that sent the request
- Notes
Equals the
sidof the lastschainnode
Content
- Field
livestream,realtime,firstbroadcast- Type
integer
- Meaning
Scheduled broadcast, happening live, first airing
- Notes
realtimeandfirstbroadcastarrived in release 2.6-202606
Content
- Field
gtax,genres- Type
integer, string array
- Meaning
Programme genre from a named taxonomy
- Notes
9 = Content Taxonomy 3.1; 483 = Sports in the CTV genre subset
Content
- Field
cattax,cat- Type
integer, string array
- Meaning
Finer content categories
- Notes
484 = American Football
Content
- Field
network,channel- Type
object
- Meaning
TV network and channel carrying the content
- Notes
Added in 2.6
Device
- Field
devicetype,ifa,lmt- Type
integer, string, integer
- Meaning
Device type, resettable advertising ID, limit-ad-tracking flag
- Notes
devicetype3 = connected TV
EID
- Field
source,matcher,mm,uids- Type
string, string, integer, object array
- Meaning
A UID2 token from a signed-in viewer
- Notes
mm3 = authenticated match;atype3 = person-based ID
SupplyChain
- Field
nodes- Type
object array
- Meaning
Publisher's SSP, then the reseller exchange
- Notes
Order runs from the publisher's seller to the last seller
Regs
- Field
coppa- Type
integer
- Meaning
0 = not child-directed
- Notes
A US request usually adds
gppandgpp_sid
BidRequest
- Field
bcat- Type
string array
- Meaning
Blocked advertiser categories
- Notes
With
cattax8: 1001 = Adult Products and Services, 1576 = Weapons and Ammunition
Table by AdSovereign, CC BY 4.0.
The pod rules come from the implementation guide. Sellers should send either rqddurs or the minduration and maxduration pair, never both. Buyers should expect the seller to build the final pod and to drop or mix bids from several buyers (OpenRTB implementation guide, section 7.6). Floors follow a fixed order: a buyer bidding on a deal uses the deal's floor, then the video floor, then imp.bidfloor (implementation guide, section 7.11). The engineering of stitching and pods is covered in SSAI and CTV ad serving.
This example omits a GPP string on purpose. A live US request would usually carry gpp with gpp_sid 7 (the MSPA US National section) or a state section such as 8 for California (GPP Section Information). IAB Tech Lab revised the US National section for the Fifth Amended and Restated MSPA in commits dated 4 November 2026 (GPP repository commit, 4 November 2026). We did not want to print a sample string that no longer decodes.
The OpenRTB bid response, field by field
The display response below bids on the open market for the medium rectangle. The CTV response sends three bids for the pod: one for the guaranteed first slot, one through the deal, and one that asks for the last slot of the dynamic portion.
{
"id": "b7e1c0a2-5f3d-4e8a-9c41-2d6f8a0b9e17",
"bidid": "dsp-resp-90311",
"cur": "EUR",
"seatbid": [
{
"seat": "seat-123",
"bid": [
{
"id": "bid-1",
"impid": "1",
"price": 1.42,
"adm": "<div class=\"ad\"><a href=\"https://bank.example/savings\"><img src=\"https://cdn.dsp.example/cr-4471-300x250.png\" width=\"300\" height=\"250\" alt=\"Savings account offer\"></a></div>",
"burl": "https://dsp.example/bill?auction=${AUCTION_ID}&price=${AUCTION_PRICE}",
"lurl": "https://dsp.example/loss?auction=${AUCTION_ID}&reason=${AUCTION_LOSS}&min=${AUCTION_MIN_TO_WIN}",
"adomain": ["bank.example"],
"crid": "cr-4471",
"cid": "camp-882",
"cattax": 8,
"cat": ["1337"],
"language": "de",
"w": 300,
"h": 250,
"mtype": 1
}
]
}
]
}{
"id": "e3a9d6f0-7b21-4c58-8f0e-61b2c4d9a7e3",
"bidid": "dsp-resp-90477",
"cur": "USD",
"seatbid": [
{
"seat": "seat-123",
"group": 0,
"bid": [
{
"id": "bid-1",
"impid": "1",
"price": 34.5,
"dur": 30,
"mtype": 2,
"protocol": 14,
"adm": "<VAST version=\"4.2\"><Ad id=\"cr-778\"><Wrapper><AdSystem>DSP Example</AdSystem><Impression><![CDATA[https://dsp.example/imp/cr-778]]></Impression><VASTAdTagURI><![CDATA[https://dsp.example/vast/cr-778]]></VASTAdTagURI></Wrapper></Ad></VAST>",
"adomain": ["autoinsurer.example"],
"crid": "cr-778",
"cattax": 8,
"cat": ["1341"],
"burl": "https://dsp.example/bill?auction=${AUCTION_ID}&price=${AUCTION_PRICE}"
},
{
"id": "bid-2",
"impid": "2",
"price": 16.0,
"dur": 15,
"dealid": "CTV-LIVE-SPORTS-01",
"mtype": 2,
"protocol": 14,
"adm": "<VAST version=\"4.2\"><Ad id=\"cr-779\"><Wrapper><AdSystem>DSP Example</AdSystem><Impression><![CDATA[https://dsp.example/imp/cr-779]]></Impression><VASTAdTagURI><![CDATA[https://dsp.example/vast/cr-779]]></VASTAdTagURI></Wrapper></Ad></VAST>",
"adomain": ["bank.example"],
"crid": "cr-779",
"cattax": 8,
"cat": ["1337"]
},
{
"id": "bid-3",
"impid": "2",
"price": 25.5,
"dur": 30,
"slotinpod": -1,
"mtype": 2,
"protocol": 14,
"adm": "<VAST version=\"4.2\"><Ad id=\"cr-901\"><Wrapper><AdSystem>DSP Example</AdSystem><Impression><![CDATA[https://dsp.example/imp/cr-901]]></Impression><VASTAdTagURI><![CDATA[https://dsp.example/vast/cr-901]]></VASTAdTagURI></Wrapper></Ad></VAST>",
"adomain": ["streamingservice.example"],
"crid": "cr-901",
"cattax": 8,
"cat": ["1431"]
}
]
}
]
}14 of 14 rows
BidResponse |
| string, required | ID of the request being answered | Must equal |
BidResponse |
| string | Bidder's response ID and bid currency |
|
SeatBid |
| string, integer | Buyer seat; whether bids must win together |
|
Bid |
| string, required | Bid ID and the impression it targets | Several bids may target one |
Bid |
| float, required | Bid as CPM | The spec advises integer or decimal maths for money, not floats |
Bid |
| string | Ad markup returned in the bid | HTML for display; VAST XML for video |
Bid |
| string | Billing and loss notice URLs with macros | The exchange replaces |
Bid |
| string array, string, string | Advertiser domain, creative ID, campaign ID | Used for blocks, ad quality checks and pod deduplication |
Bid |
| integer, string array | Creative category | With |
Bid |
| integer | Markup type | 1 = banner, 2 = video, 3 = audio, 4 = native |
Bid |
| integer | Creative length in seconds | Should match one of the request's |
Bid |
| integer | VAST version of the markup | 14 = VAST 4.2 wrapper |
Bid |
| string | Deal the bid is for | Must match a |
Bid |
| integer | In a response: the only slot this bid accepts | Use only on dynamic portions; -1 = last slot |
BidResponse
- Field
id- Type
string, required
- Meaning
ID of the request being answered
- Notes
Must equal
BidRequest.id
BidResponse
- Field
bidid,cur- Type
string
- Meaning
Bidder's response ID and bid currency
- Notes
curdefaults to USD; it must be one the request allowed
SeatBid
- Field
seat,group- Type
string, integer
- Meaning
Buyer seat; whether bids must win together
- Notes
group0 = each bid can win alone
Bid
- Field
id,impid- Type
string, required
- Meaning
Bid ID and the impression it targets
- Notes
Several bids may target one
impidin a pod
Bid
- Field
price- Type
float, required
- Meaning
Bid as CPM
- Notes
The spec advises integer or decimal maths for money, not floats
Bid
- Field
adm- Type
string
- Meaning
Ad markup returned in the bid
- Notes
HTML for display; VAST XML for video
Bid
- Field
burl,lurl- Type
string
- Meaning
Billing and loss notice URLs with macros
- Notes
The exchange replaces
${AUCTION_PRICE},${AUCTION_LOSS}and${AUCTION_MIN_TO_WIN}
Bid
- Field
adomain,crid,cid- Type
string array, string, string
- Meaning
Advertiser domain, creative ID, campaign ID
- Notes
Used for blocks, ad quality checks and pod deduplication
Bid
- Field
cattax,cat- Type
integer, string array
- Meaning
Creative category
- Notes
With
cattax8: 1337 = Banking, 1341 = Auto Insurance, 1431 = Music and Video Streaming Services
Bid
- Field
mtype- Type
integer
- Meaning
Markup type
- Notes
1 = banner, 2 = video, 3 = audio, 4 = native
Bid
- Field
dur- Type
integer
- Meaning
Creative length in seconds
- Notes
Should match one of the request's
rqddursvalues
Bid
- Field
protocol- Type
integer
- Meaning
VAST version of the markup
- Notes
14 = VAST 4.2 wrapper
Bid
- Field
dealid- Type
string
- Meaning
Deal the bid is for
- Notes
Must match a
Deal.idin the request
Bid
- Field
slotinpod- Type
integer
- Meaning
In a response: the only slot this bid accepts
- Notes
Use only on dynamic portions; -1 = last slot
Table by AdSovereign, CC BY 4.0.
The prices respect the floors. Bid 2 is a 15-second deal bid at 16.00, above the deal's 15.00 duration floor. Bid 3 is a 30-second open-market bid at 25.50, which works out to 0.85 per second, above the 0.75 mincpmpersec floor. In a first-price auction, the price you return is the price you pay, which is why most DSPs adjust it first; the mechanics are in bid shading explained. The ${AUCTION_MIN_TO_WIN} macro in the loss URL was added in 2.6 and is the feedback signal those models learn from (OpenRTB 2.6, section 4.4.1).
What changed in OpenRTB 2.6, release by release
IAB Tech Lab now publishes 2.6 as dated releases. The table lists each one with the fields it added. For the wider comparison with 2.5 and 3.0, and what is actually used in the market, see OpenRTB 2.5 vs 2.6 vs 3.0.
10 of 10 rows
2.6 (PDF) | April 2022 (release 2.6-202210 notes) | Ad pods ( |
2.6-202210 | 3 Nov 2022 | GitHub baseline, no new fields (notes) |
2.6-202211 | 17 Nov 2022 |
|
2.6-202303 | 5 Apr 2023 |
|
2.6-202309 | 28 Sep 2023 |
|
2.6-202402 | 20 Feb 2024 |
|
2.6-202409 | 23 Sep 2024 | EID |
2.6-202501 | 27 Jan 2025 |
|
2.6-202505 | 20 May 2025 |
|
2.6-202606 | 11 Jun 2026 |
|
2.6 (PDF)
- Date
April 2022 (release 2.6-202210 notes)
- Main changes
Ad pods (
podid,podseq,slotinpod,poddur,maxseq,mincpmpersec),rqddurs,Bid.dur,Bid.mtype,Bid.apis,Imp.rwdd,Imp.ssai,cattaxeverywhere,sua, Network and Channel objects, SupplyChain and EIDs moved into core,gdprandconsentmoved out ofext,${AUCTION_MIN_TO_WIN}; enumerated lists moved to AdCOM 1.0;Video.sequence,Bid.api,User.yob,User.genderand hashed device IDs deprecated (Appendix B)
2.6-202210
- Date
3 Nov 2022
- Main changes
GitHub baseline, no new fields (notes)
2.6-202211
- Date
17 Nov 2022
- Main changes
regs.gpp,regs.gpp_sid; DOOH and Qty objects;inventorypartnerdomainout ofext; monthly release policy (notes)
2.6-202303
- Date
5 Apr 2023
- Main changes
Video.plcmtreplacesplacement; Refresh and RefSettings objects;${AUCTION_IMP_TS}(notes)
2.6-202309
- Date
28 Sep 2023
- Main changes
BidRequest.acat; DurFloors object;Deal.guar,Deal.mincpmpersec,Deal.durfloors; floors guidance (notes)
2.6-202402
- Date
20 Feb 2024
- Main changes
Video.poddedupe(notes)
2.6-202409
- Date
23 Sep 2024
- Main changes
EID
inserter,matcher,mm; ID match guidance; Appendix C on cookie syncing (notes)
2.6-202501
- Date
27 Jan 2025
- Main changes
Content.gtax,Content.genres; Content Taxonomy 3.1 value in AdCOM (notes)
2.6-202505
- Date
20 May 2025
- Main changes
Data.cidsfor extended content IDs (notes)
2.6-202606
- Date
11 Jun 2026
- Main changes
Content.realtime,Content.firstbroadcast;${AUCTION_DISCOUNT_PCT},${AUCTION_DISCOUNT_CPM}(notes)
Table by AdSovereign, CC BY 4.0.
No release after 2.6-202606 appeared on the repository's release page when we checked on 9 November 2026 (openrtb2.x releases). Because the version header still reads 2.6, a bidder cannot tell from the header alone which release the exchange implements. Ask each partner which release they target, and log unknown fields instead of rejecting the request.
Privacy signals: regs, gdpr, gpp and gpp_sid
The regs object says which rules apply to this request. The coppa flag marks child-directed traffic under the US Children's Online Privacy Protection Act. A gdpr value of 1 means the EU or UK GDPR applies, and the TCF consent string then travels in user.consent. The us_privacy field carries the older US Privacy string. The gpp field carries a Global Privacy Platform (GPP) string, and gpp_sid lists the section IDs that apply to this transaction (OpenRTB 2.6, Object: Regs).
A GPP string is a header plus one or more sections joined by a tilde. In the display example, DBABM is the header declaring one section, and the part after the tilde is a TCF v2 section. That exact string is "GPP String Example 1" in the GPP Consent String Specification. Section ID 2 is the EU TCF v2 section, 7 is US National, and 6, the old US Privacy string, is marked deprecated (GPP Section Information).
One caveat applies to that example. Under TCF 2.3, a TC string must contain the Disclosed Vendors segment, which the April 2025 revision of the consent string spec made mandatory (TCF consent string and vendor list formats v2). The GPP specification's example predates that rule, so do not use it as a test of TCF 2.3 handling. The end-to-end consent flow, from CMP to bidder, is the subject of GPP and TCF implementation for engineers.
Supply chain and identity: source.schain and user.eids
The SupplyChain object lists every company that sold or resold the impression. Each node names the exchange domain (asi) and the seller account at that exchange (sid). The first node is the publisher's own account; each reseller appends one more. complete set to 1 claims that no seller is missing (OpenRTB 2.6, Object: SupplyChainNode).
Buyers verify a chain against two public files. Each asi domain publishes a sellers.json listing its sid values, and the publisher's ads.txt must authorise the first node. In the CTV example, publisher.id is "4410" because the request comes from Exchange Beta, where SSP Alpha sells as seller 4410. If publisher.id and the last sid differ, that check fails. The checks are worked through in SupplyChain, ads.txt and sellers.json together.
The user.eids array carries identifiers from sources other than the exchange's own cookie. Each entry names the ID's source domain.
Release 2.6-202409 added three fields that say how the ID got there: inserter (who added it), matcher (who performed the match) and mm, the match method from AdCOM (2.6-202409 release notes). The AdCOM list defines 3 as an authenticated match, such as an email login or hashed email, and 4 as an observed first-party ID such as SharedID (AdCOM 1.0, List: ID Match Methods). The source domains in the examples, pubcid.org for SharedID and uidapi.com for UID2, are the ones Prebid documents (Prebid User ID module).
Common mistakes
- Sending
rqddurstogether withmindurationormaxduration. The spec makes them mutually exclusive. Pick exact durations for live TV and a range for everything else (OpenRTB 2.6, Object: Video). - Returning
slotinpodfor a structured slot. In a structured pod theimpidalready identifies the slot. Buyers should returnslotinpodonly on dynamic portions, and only to demand the first or last position. - Pricing every duration off
imp.bidfloor. Whenmincpmpersecordurfloorsis present, a 30-second ad faces a higher floor than a 15-second ad. Bidders that ignore it send long creatives below the floor and see them rejected. - Assuming the deal floor uses the impression's currency.
Deal.bidfloorcurdefaults to USD unless the deal states otherwise. - Leaving
cattaxat its default. The default value 1 points to Content Category Taxonomy 1.0, which AdCOM now marks deprecated. Sending newer IDs without settingcattaxmakes every category ambiguous. - Breaking the supply chain. Common faults: a
publisher.idthat differs from the last node'ssid,completeset to 1 when a reseller is missing, or a node whoseasipublishes no sellers.json entry for thesid. - Sending
gppwithoutgpp_sid, or the reverse. The string alone does not say which section governs this transaction. - Reading deprecated fields.
Video.placementgave way toplcmtin 2.6-202303,Video.sequencetoslotinpod, andBid.apitoapis. Read both during migration, write only the new ones. - Rejecting unknown fields. Since 2.6-202211 the versioning policy requires partners to ignore fields and values they do not recognise. A strict schema validator that drops the request breaks this rule.
- Doing money in floating point. The spec recommends integer or decimal maths, such as BigDecimal in Java, for prices (OpenRTB 2.6, Object: Bid).
To check your own payloads against these rules, paste them into the OpenRTB bid request builder and validator. The RTB architecture hub collects the related engineering pages.
FAQ
Where is the OpenRTB 2.6 spec on GitHub?
Is there an OpenRTB 2.7?
What is the difference between OpenRTB 2.5 and 2.6?
ext (OpenRTB 2.6, Appendix B). Enumerated lists move out of the spec and into AdCOM. The full comparison, including 3.0, is in OpenRTB 2.5 vs 2.6 vs 3.0.What is gpp_sid in OpenRTB?
regs object that names the GPP section or sections that apply to the transaction. It usually holds one value, for example 2 for the EU TCF v2 section or 7 for the US National section. Sections 3 and 4, the header and signal integrity, are never listed (OpenRTB 2.6, Object: Regs).How does a bidder say it will not bid?
seatbid array and an nbr reason code, which helps when debugging (implementation guide, section 7.1).How this works on owned infrastructure
Every field on this page is a decision about what leaves your systems. The user.eids array, device.ifa, site.page and the consent strings are the parts of an OpenRTB 2.6 request that carry data about your users, and the schain nodes record who resold it. AdSovereign is an enterprise RTB stack (DSP, SSP, exchange, DMP and clean room) designed to run inside your own perimeter, so you choose which of these fields reach each bidder and you keep full request and response logs for audit. Its exchange and bidder are built on OpenRTB 2.6. The integrations page lists supported protocol versions and partner connectors, and the architecture page shows where request filtering sits.
Sources
- IAB Tech Lab, "OpenRTB API Specification Version 2.6" (2.6.md, main branch, accessed 9 November 2026). https://github.com/InteractiveAdvertisingBureau/openrtb2.x/blob/main/2.6.md
- IAB Tech Lab, "OpenRTB 2.x Implementation Notes" (implementation.md, accessed 9 November 2026). https://github.com/InteractiveAdvertisingBureau/openrtb2.x/blob/main/implementation.md
- IAB Tech Lab, openrtb2.x releases, 2.6-202210 (3 November 2022) to 2.6-202606 (11 June 2026), accessed 9 November 2026. https://github.com/InteractiveAdvertisingBureau/openrtb2.x/releases
- IAB Tech Lab, "AdCOM Specification v1.0" (accessed 9 November 2026). https://github.com/InteractiveAdvertisingBureau/AdCOM/blob/main/AdCOM%20v1.0%20FINAL.md
- IAB Tech Lab, "OpenRTB Specification v3.0" (lists of no-bid and loss reason codes). https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/OpenRTB%20v3.0%20FINAL.md
- IAB Tech Lab, "Global Privacy Platform: Consent String Specification" (accessed 9 November 2026). https://github.com/InteractiveAdvertisingBureau/Global-Privacy-Platform/blob/main/Core/Consent%20String%20Specification.md
- IAB Tech Lab, "GPP Section Information" (accessed 9 November 2026). https://github.com/InteractiveAdvertisingBureau/Global-Privacy-Platform/blob/main/Sections/Section%20Information.md
- IAB Tech Lab, Global Privacy Platform repository, commit "Prepare to finalize" to the MSPA US National section (4 November 2026). https://github.com/InteractiveAdvertisingBureau/Global-Privacy-Platform/commit/ab767c179195da2c33c89832ef7123d76fc3008a
- IAB Europe and IAB Tech Lab, "TCF: Consent string and vendor list formats v2" (revision 2.3, April 2025; accessed 9 November 2026). https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/blob/master/TCFv2/IAB%20Tech%20Lab%20-%20Consent%20string%20and%20vendor%20list%20formats%20v2.md
- IAB Tech Lab, Taxonomies repository: Content Taxonomy 3.1, Ad Product Taxonomy 2.0, CTV Genre Mapping (accessed 9 November 2026). https://github.com/InteractiveAdvertisingBureau/Taxonomies
More sources (1)
- Prebid.org, "User ID Module" documentation (accessed 9 November 2026). https://docs.prebid.org/dev-docs/modules/userId.html