Browse the help center

OpenRTB bid request fields

Every field of the bid request Epom sends a DSP partner — the top-level BidRequest, the privacy signals, imp by placement type, site and app, device, user, pmp.deals and inventory masking — with the corner cases a buyer trips over.

Reference network manager admin

A detail page of the OpenRTB integration reference, which has the two directions, the currency rules and the bid floor chain. This page is the outbound bid request field by field: what Epom sends a DSP partner, when, and what it never sends. The response Epom reads back, the auction and the macros are on OpenRTB bid response, auction and macros; the inbound direction on Epom as a seller: the /hb/bid endpoint.

Request: top-level BidRequest

Eight fields ship on every request; five more are conditional.

FieldWhat Epom sendsAlways?
idGenerated UUID per requestYes
imp[]Exactly one impressionYes
site or appapp when the site’s inventory type is APP or the placement is an application placement; otherwise site. Sending neither or both is rejected before the request leaves.Yes (one of)
deviceSee deviceYes
userSee userYes
at (auction type)1 (first price) or 2 (second price) — see belowYes
tmaxThe partner’s configured Timeout (ms), minus the time already spent on this auction batch; on a header-bidding bid, never more than what is left of that bid’s own budgetYes
cur["USD"], or the partner’s currencyYes
bcatBlocked IAB categories — union of blocked categories on site + zone + placementWhen non-empty
sourcepchain (asi:sid of your own node), plus schain — in source.schain on 2.6 and in source.ext.schain on every earlier version (2.5 by the IAB SupplyChain spec; 2.2–2.4 have no standard place, so the chain goes where 2.5 puts it). Your node’s sid is the site’s Seller ID once sellers.json is published and one is set, otherwise the generated publisher id. On a site whose seller type is Intermediary or Both, a chain passed on the tag’s schain parameter comes first, with your node appended (or put in place of a copy of it the chain already ends with) and its complete flag kept; with no chain on the tag your node is alone, complete: 0 on an Intermediary site and 1 otherwise — see Supply chain and sellers.jsonOpenRTB 2.5 and 2.6 partners only, when the DSP partner’s Send supply chain is on — a banner’s Send supply chain (banner override) wins either way (On sends it, Off suppresses it)
regsThe privacy signals of the ad request — see Privacy signals: regs and user.consentOnly with Pass privacy signals to DSPs on
test0DoubleImpact only
extext.sub = placementIdExoClick only

Corner case: at is not always first price. It is 2 (second price) when the banner has Always 2nd price set and it is the only programmatic candidate, and also when several programmatic banners compete and the partner’s FORCE_FIRST_PRICE parameter is explicitly set to false. Note the inverted sense of that parameter: absent and true both mean first price; only an explicit false opens the door to second price. See First vs second price.

Corner case: the tmax you receive is the Timeout configured on the partner minus the time the current auction batch has already used, so it is usually smaller than the configured value. If 10 ms or less remains, the request is abandoned and never sent at all.

Not sent: badv, bapp, wseat and allimps.

Privacy signals: regs and user.consent

The network’s Pass privacy signals to DSPs setting (Admin → System preferences, on the GDPR card — see GDPR / TCF consent) decides whether a bid request carries the privacy signals of the ad request. It is off by default; off, none of the fields below is written. On, where they go depends on the partner’s OpenRTB version:

Ad request carriedOpenRTB 2.6 partnerEarlier versions
gdpr — stated, or inferred from the countryregs.gdprregs.ext.gdpr
gdprConsentIabuser.consentuser.ext.consent
usPrivacyregs.us_privacyregs.ext.us_privacy
gpp, gppSidregs.gpp, regs.gpp_sidregs.ext.gpp, regs.ext.gpp_sid
copparegs.copparegs.coppa

regs.gdpr is always written, 0 or 1; every other field only when the request carried a well-formed value — a stitcher’s macro sent back unfilled ({{US_PRIVACY}}) counts as none. The signals are forwarded, not enforced: whether the request is served, and whether the bid request is anonymised, is still the GDPR policy’s decision, and a US opt-out or a COPPA flag does not by itself strip anything from the request.

Request: imp by placement type

Every request carries exactly one impression object, typed to the placement.

Display (imp.banner)

FieldValue
banner.idThe placement id
banner.w / banner.hThe banner’s own size, or the placement’s size when Use placement size is on
banner.format[]A single {w,h} format — 2.5 partners only
banner.posThe placement’s ad position
banner.battrBlocked creative attributes from the placement

Corner case: format[] is sent to 2.5 partners only, and never to 2.6 partners — which is the reverse of what the spec’s own direction of travel suggests, since 2.6 is the version that deprecates banner.w/h in favour of format[]. A 2.6 partner receives w/h and no format.

Corner case: banner.btype is never populated. Only battr carries the placement’s blocking. banner.mimes, banner.expdir and banner.api are likewise never sent.

Corner case: on pop placements, several partner types receive no banner object at all (it is set to null), and DoubleImpact receives an empty one.

Video (imp.video)

FieldValue
video.linearityLinear / non-linear, from the banner’s In-Stream video type
video.mimes[]The banner’s Mime types list, or Epom’s default video mime set when empty
video.minduration / video.maxdurationThe placement’s min/max ad duration. A maxDuration on the ad request (a player’s own limit, filled in by a stitcher) narrows maxduration when it is shorter, never widens it, and minduration is lowered to match when it would exceed it
video.protocols[]A fixed list — see below
video.skip / video.skipmin / video.skipafterFrom the placement’s skip settings
video.playbackmethod[] / video.api[]The placement’s RTB playback methods and API frameworks, when non-empty
video.w / video.hThe placement ad-unit size, when set
video.battrBlocked video attributes from the placement
video.minbitrate / video.maxbitrateFrom the VAST request, when present
video.pos / video.sequence / video.maxextended / video.boxingallowedAlways sent: 0 / 1 / 0 / 1 by default
imp.ssai3 (stitched and tracked server-side) when the placement’s Server-side ad insertion (SSAI) setting names a stitcher; omitted otherwise — see Video placements

video.protocols[] is a hard-coded six-element list that does not vary by placement, partner or protocol version:

ProtocolId
VAST 2.02
VAST 3.03
VAST 2.0 wrapper5
VAST 3.0 wrapper6
VAST 4.07
VAST 4.0 wrapper8

Corner case: VAST 1.0 (1, 4) and VAST 4.1 / 4.2 / 4.3 (11–16) are all modelled in Epom’s enum but are deliberately never advertised. A DSP that only bids on 4.2 will never see a matching protocol, and there is no setting that adds one.

Corner case: boxingallowed defaults to 1 and therefore ships on every video impression, not only when a VAST request supplies it. The VAST request only overrides the default.

Native (imp.native)

FieldValue
native.verThe partner’s native protocol version (default 1.1)
native.requestThe native request spec built from the placement, optionally wrapped per the partner’s native request wrap setting
native.battrBlocked native attributes from the placement

native.api and native.ext are never sent.

Shared imp fields (all types)

FieldValue
imp.idThe request’s transaction id — not the placement id
imp.tagidThe placement key, or a custom OpenRTB tag id resolved from the placement (macros expanded)
imp.bidfloorThe calculated floor — see The bid floor
imp.bidfloorcurUSD, or the partner’s currency
imp.instl1 for interstitial and rewarded placements, or when the partner forces interstitial
imp.rwdd1 when the placement’s Application ad category is Rewarded video; omitted otherwise. A rewarded placement carries imp.instl = 1 as well, because it is full screen too — rwdd is the only field that tells the two apart, so a buyer that wants rewarded inventory (or wants to avoid it) reads this one
imp.secure1 on HTTPS requests
imp.pmpPresent only when the campaign has PMP deals
imp.extPartner-specific (e.g. TrafficHunt subid, Epom WL DSP partnerRef); TwinRed always gets adm_on_resp: 1. On an always-redirect placement a pop is type: "pop" for Custom partners, and for TwinRed the impression is sent without an imp.banner object — see pops

imp.displaymanager, imp.displaymanagerver, imp.exp and imp.clickbrowser do not exist on Epom’s model and are never sent.

Request: site and app — page URL, domain and publisher

The request carries site for web traffic and app for app inventory (see the top-level table).

Fieldsite (web)app
domain / nameHost of the page that called the tag: the page origin (the tag’s o parameter or the Origin header), else the Referer host, else the URL configured on the siteapp.name is the request’s appName when it carries one, else the site’s name; app.domain only when the SDK request passes one
pageThe full page URL — the tag’s requestUrl, else the Referer — when it belongs to that origin—
refThe document referrer (the tag’s requestRef), when known—
idA numeric hash of the domain; a custom parameter ortb.site.id (cp.ortb.site.id in the tag) replaces itThe site id
bundle / storeurl / ver—The site’s Bundle setting; the SDK request’s bundle (or the WebView’s X-Requested-With package), storeurl and ver override it
publisher.idA generated publisher id per site — never the account; the site’s Seller ID once sellers.json is published and one is setSame
cat / sectioncat / pagecatIAB categories of the site, the zone and the placementSame
privacypolicyThe site’s privacy-policy flag—
content.genre / contentrating / livestream / languageFrom the request’s contentGenre, contentRating, contentLivestream (1 / 0) and contentLanguage — the show a stitcher describes; each only when the request carried itSame, under app.content

The buyer sees a Google domain (imasdk.googleapis.com) instead of the site

Inside Google’s IMA player the tag is requested from Google’s SDK frame. Epom drops imasdk.googleapis.com from the origin and referrer and falls back to the site URL configured in Epom, so set the site’s URL. A page that sends no Referer (a strict referrer policy, some players) also leaves page empty — pass the page URL in the tag’s requestUrl parameter (data-page-url on the async tag), which replaces the Referer, and requestRef for the document referrer.

Readable source id or zone name in the partner’s stats

imp.tagid carries the placement key by default. To show the buyer a readable id (for example sports-daily-top), set the placement’s Custom tag ID on its RTB configuration card — see OpenRTB placement settings.

Is pre-roll, mid-roll or post-roll sent to the DSP?

No. Outbound video requests carry no video.startdelay, so a DSP cannot tell a pre-roll from a mid-roll or post-roll.

Request: device

FieldValueNotes
uaUser agentAlways
ip / ipv6Client IPOne or the other by address family; shortened on a GDPR-anonymised request — see below
jsAlways 1Always
connectiontypeMapped to the OpenRTB connection-type enumWhen known
carrierMobile carrierWhen known
languageBrowser languageWhen known
os / osvOperating system + versionWhen detected
devicetypePHONE / TABLET / CONNECTED_TV / PCDerived from OS device format
make / model / hwvVendor / family / modelFrom device detection
ifaAdvertising IDThe advertising ID, from the request’s ifa parameter or the Android/iOS advertising-ID identification. The SHA1 platform-ID form device.dpidsha1 is no longer sent since release 154. An all-zero ID, an unsubstituted macro ([IFA]) or a placeholder such as null / unknown is treated as no ID
lmtLimit ad tracking, 1 / 0From the request’s lmt parameter; omitted when absent
dntDo not track, 1 / 0From the request’s dnt parameter; omitted when absent
ext.ifa_typeSource of ifa — rida, tifa, aaid, sessionid, …From the request’s ifa_type parameter, lower-cased; sent only alongside an ifa
geoSee belowMay be absent entirely
ext.timezone / ext.timezoneCountry / ext.releaseYearNon-standard extensionsTimezone name, its primary country (alpha-3), device release year

device.geo carries country (ISO alpha-3), type, utcoffset, and lat/lon.

Corner case: geo.lat/lon are not GPS-only. They are filled from IP geolocation on an ordinary request, with geo.type = IP. Coordinates passed as request parameters are a second source and flip geo.type to GPS — on an API request, and on a VAST tag that carries latitude and longitude (a stitcher filling them from the player), unless the request is anonymised under the GDPR policy. Read geo.type if the distinction matters to you — a precise-looking lat/lon may be city-level IP data.

Corner case: the whole geo object is omitted when neither an alpha-3 country nor GPS parameters could be resolved. geo.region, metro, city and zip are never sent.

Corner case: Epom sends device.dnt and device.lmt only when the ad request carried a dnt or lmt parameter (CTV tags behind a stitcher do). Otherwise a DSP filtering on them sees them absent (treated as unknown), not as 0. Epom forwards lmt = 1 as it is and does not withhold the ID: a device that limits tracking already zeroes or session-scopes it.

Corner case: screen width and height are not forwarded. Epom collects them (they reach the ad log and the creative-scan context) but drops them before the bid request, so device.w/h never appear. ppi, pxratio, sua and mccmnc do not exist on the model.

Corner case: a request the GDPR policy anonymises — no consent under Do not use any cookies or server-side processing, see GDPR / TCF consent — reaches the DSP with ip ending in .0 (an ipv6 keeps only its /48), ua set to GDPR, no os/osv/devicetype, and no ifa, ext.ifa_type or GPS coordinates. Its user has no id, no buyeruid and no customdata.

Request: user

FieldValueNotes
idEpom’s user id (UID)Always
consentThe IAB TCF consent stringOpenRTB 2.6 partners, with Pass privacy signals to DSPs on; earlier versions get ext.consent — see Privacy signals
buyeruidThe partner’s synced user idOnly when user sync is enabled on the partner and its sync cookie is present
customdataPartner-specific custom dataKeyed by the partner shortname
keywordsThe request’s keywords custom parameter
gender / yob / data[]DMP segmentsOnly when DMP-to-bid-request enrichment is enabled
ext.privateBrowsing1 (incognito) / 0 (normal)Omitted when the state is unknown
ext.xrwThe in-app WebView package nameFrom the X-Requested-With header
ext.channelThe request channel
ext.category / ext.incomeDMP-derived audience attributesOnly with DMP enrichment
ext.<custom-param>Any custom parameter on the requestMacros in the values are resolved before sending

Note: user.ext.privateBrowsing is a proprietary Epom extension, not an OpenRTB field. No standard field for private-browsing state exists in 2.5, 2.6 or 3.0, so Epom follows the dnt/lmt convention with an integer 1/0 and omits the key when the state is unknown. Do not expect other exchanges to send it.

Corner case: with Pass privacy signals to DSPs off — the default — the bid request carries no user.consent and no regs at all, though Epom still uses the consent string to gate its own serving and to fill consent macros in markup. A DSP that needs the string then gets it only through the $$GDPR$$ / $$GDPR_CONSENT_IAB$$ macros in the partner’s endpoint URL, or as a custom parameter, which arrives as user.ext.<your-param-name>.

Request: pmp.deals

Present only when the winning banner’s campaign has PMP deals enabled and at least one deal matches. Set on imp.pmp:

FieldValue
pmp.private_auction1 when the campaign marks the auction private, else 0
pmp.deals[].idThe deal id
pmp.deals[].bidfloorThe deal’s floor, converted like imp.bidfloor
pmp.deals[].bidfloorcurUSD, or the partner’s currency
pmp.deals[].wseat[]The deal’s buyer (seat) id — always a single-element array
pmp.deals[].atThe deal’s auction type

Deals are matched by the request country first, then any global (country-agnostic) deals are appended, de-duplicated. A private auction (private_auction = 1) with an empty deal list is rejected before the request is sent — no HTTP call is made. A non-private auction with an empty deal list simply drops the pmp object and sends the request without it.

Inventory masking

If the banner’s mask-inventory setting (or the site’s) applies, site.name becomes Site_<id> and site.domain / site.page / site.ref are cleared. With field-hashing enabled, name and domain are sent as MD5 hashes instead. Publishers are never sent as the raw account: site.publisher.id (or app.publisher.id), schain.sid and the pchain suffix carry one ID — the generated publisher id until sellers.json is published, and from then on the site’s Seller ID where one is set — see Supply chain and sellers.json.

Note: even unmasked, site.name, site.domain and site.id describe the live page domain, derived from the ancestor-origin or referer — not the Epom site entity’s name. site.id is a hash of that domain. Do not expect it to match anything in the Epom UI. Only http(s) addresses count: an origin or referer such as about:blank, data:… or android-app://… is ignored, and when neither is usable the site’s configured URL supplies the domain instead.

Related pages

Please disable Adblock
Are you using adblock? Disable it and reload the page to proceed to the destination page.

A registration has already been submitted from this page. Please try again in 10 minutes.