Browse the help center

OpenRTB integration reference

Field-level reference of both OpenRTB directions — the bid request Epom sends DSP partners and the response fields it reads back, the floor / PMP / creative-scan filters, the loss reasons and auction macros a buyer receives, and the /hb/bid endpoint Epom answers as a seller.

Reference network manager admin

This is the field-level map for anyone plugging a DSP into Epom, or plugging Epom into a buyer, and for debugging why a partner sees no bid opportunity, a malformed request, or a bid that never wins.

Epom speaks OpenRTB in two directions, and they are separate implementations with different defaults:

DirectionEpom’s roleEndpointProtocol
Outbound — Epom asks DSPs to bidExchange / SSPThe partner’s endpointPer partner, default 2.5
Inbound — a buyer asks Epom to bidSeller / bidderPOST /hb/bid on the ad-serving host2.6

Most of this page is the outbound direction, because that is where the field surface is large. The inbound direction is covered under Epom as a seller; the product side of it lives in Header bidding.

For the outbound direction: for each OpenRTB banner reached during ad selection, Epom builds one bid request per eligible banner, POSTs it to that banner’s DSP partner endpoint, and runs an auction over the returned bids. Partners are configured in DSP Partners; the demand-side banner in OpenRTB banners.

Note: two banners pointing at the same partner produce two requests, not one — the unit is the banner, not the partner. A banner whose DSP partner is deactivated is dropped before any request is built.

Note: the request is a JSON POST with Content-Type: application/json; charset=UTF-8 and an x-openrtb-version header naming the partner’s protocol version; the body is gzipped only when the partner has Gzip bid request on. Version, timeout, currency conversion and endpoint are per-partner settings — see the DSP Partners field table. Protocol version defaults to 2.5; native protocol to 1.1. Null fields and empty arrays are omitted from the JSON rather than sent.

Note: on a header-bidding call, a DSP partner is asked only when its Allow in header bidding setting is on, the platform-wide programmatic switch is on, and its pricing model is CPM. Otherwise its banners are skipped for that call.

Currency: USD, always

Epom is a single-currency exchange. The SSP currency is a hard-coded constant, and it appears on the wire in four places:

  • the outgoing cur on every bid request defaults to ["USD"];
  • imp.bidfloor and pmp.deals[].bidfloorcur are USD;
  • the ${AUCTION_CURRENCY} macro always substitutes the literal USD, whatever else is configured;
  • Epom’s own bid response as a seller declares cur: "USD".

There is no FX feed and no currency negotiation. The only escape is a pair of per-banner network parameters — DSP Custom Currency and USD to DSP Custom Currency Rate — which you set together on the OpenRTB banner. When both are present, Epom sends cur and imp.bidfloorcur as your currency with the floor converted at your rate, and converts the returned bid.price back to USD at the same rate.

Warning: that rate is a static number you typed, not a live exchange rate. It does not update, and nothing alerts you when it drifts. If the rate is missing or does not parse, Epom silently falls back to 1.0 — meaning a EUR bid is banked as though it were USD.

Corner case: because Epom rewrites the response currency to USD during that conversion, the “reject a non-USD bid response” check that exists in the floor validator can never actually fire on the DSP path. Sending cur: "EUR" in your bid response therefore does not produce an error — the price is taken at face value (or at your configured rate). Getting the rate parameters right is the only protection.

The bid floor

imp.bidfloor is the first non-zero value along this chain, evaluated for the request’s country:

banner Bid Floor → placement Bid Floor → site Bid Floor → the banner’s own price → the campaign price → the site CPM threshold

A header-bidding request raises the result to the publisher’s floor when that is higher.

If every link is unset or zero, no floor is sent. An empty country code short-circuits the chain to zero. The two price links only contribute when the pricing type yields an eCPM — see CPM threshold for the pricing-type table.

Warning: the javadoc above this method in the source states a different order (placement before banner) and lists a seventh step, “open rtb country bid floor”, that does not exist. The order above is what the code does. Do not use the javadoc.

Two things sit outside the chain:

  • A header-bidding caller’s floor raises ours. When the inbound request names its own floor, the value sent onward to DSPs is the higher of the two. This applies only to header-bidding requests; ordinary serving keeps the chain’s answer.
  • There is no per-partner floor. Nothing on the DSP partner sets or adjusts a floor, and there is no way to quote different partners differently except by giving them different banners.

Note: nothing takes a margin off DSP spend. The winning bid price is banked as the raw settlement price. Epom’s margin is taken on the publisher side, as revenue share on the site or placement — the buyer’s price is never marked down. (A “fee” field exists in the floor model but is never populated by any code path; it is always zero.)

Request: top-level BidRequest

Eight fields ship on every request; four 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 batchYes
cur["USD"], or the partner’s custom currencyYes
bcatBlocked IAB categories — union of blocked categories on site + zone + placementWhen non-empty
sourcepchain, plus schain — 2.5 puts it in source.ext.schain, 2.6 in source.schainOnly with the Add source schain network parameter
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, allimps, and regs — the regs object does not exist on Epom’s outgoing model at all, so there is no regs.gdpr, regs.us_privacy, regs.gpp or coppa.

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
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 custom 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 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 accountSame
cat / sectioncat / pagecatIAB categories of the site, the zone and the placementSame
privacypolicyThe site’s privacy-policy flag—

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 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
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
ifa / dpidsha1Advertising IDsThe advertising ID (device.ifa) and its SHA1 platform-ID form (device.dpidsha1), from the request’s ifa parameter or the Android/iOS advertising-ID identification. 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
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. 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 does not populate device.dnt, and sends device.lmt only when the ad request carried an 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.

Request: user

FieldValueNotes
idEpom’s user id (UID)Always
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: GDPR consent is not sent as a standard OpenRTB field. Epom carries the IAB consent string internally and uses it to gate its own serving and to fill consent macros in markup — but the outbound bid request has no user.consent and no regs.ext.gdpr, because neither field exists on the outgoing model. The supported workaround is to pass the consent string as a custom parameter, which arrives as user.ext.<your-param-name>; agree the name between the network and the DSP.

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
pmp.deals[].bidfloorcurUSD
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 always sent as a generated publisher id, never the raw account; the same id is used in pchain and schain.sid.

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.

Response: fields Epom reads

Epom parses the standard seatbid[].bid[] structure. Anything not listed here is discarded on parse — the deserializer ignores unknown fields.

Response fieldUsed for
priceAuction ranking, clearing price, billing
admThe served creative (HTML / VAST XML / native JSON)
nurlWin notice; for some partners the markup is delivered here
lurlLoss notice — see Loss reasons
impidMatched against the request’s impression; a bid that matches none is dropped
cridCreative-scan verdict key, troubleshooting, reporting
adidFills the ${AUCTION_AD_ID} macro
adomain[]Carried onto the winning creative and republished as the adomain of Epom’s own bid when that creative is resold through header bidding — unless the advertiser declares its own Advertiser domain, which wins
dealidValidated against the request’s deals
extext.url and ext.impression_tracking_url, for Epom WL DSP pops
seatbid[].seatDeal wseat validation, loss records
Response id / bidid / cur / customdataAuction macros and currency handling

Corner case: several fields you might expect to matter are parsed and then ignored: cid, attr[] and iurl have no consumer anywhere in the serving path, so a campaign id sent on the bid does not reach Epom’s reporting. And w/h are not even modelled — creative size is taken from the request’s impression, never from your bid. Send them for spec compliance, but do not rely on Epom acting on them.

Warning: Epom accepts exactly one seatbid containing exactly one bid. A response with two seat objects, or one seat carrying two bids, is discarded whole as an invalid bid response — not trimmed to the best bid. If your bidder normally returns a bid per impression or several candidates per seat, it must be configured to return a single bid to Epom.

What happens to a returned bid

A bid passes through four stages before it can serve. They run in this order:

1. Response validation and floor. The response must be exactly one seatbid with one bid, and the price must be at or above imp.bidfloor. A bid below the floor is dropped with BID_WAS_BELOW_AUCTION_FLOOR.

Corner case: a bid carrying a dealid skips the floor check entirely. Deal bids are held to the deal’s own floor instead, at stage 3. A deal priced below your open-auction floor still clears.

2. Private-auction pre-filter. When any impression in play is a private auction, seat bids whose deals are unsuitable are removed, and a partner left with nothing is dropped.

3. Creative scan. If the network scans the partner’s creatives (creative scanning), the bid’s creative is checked before the winner is chosen. A BLOCKED creative is removed from the auction, so the runner-up wins instead — the impression still fills, just not with the blocked creative. Bids removed here are recorded as CREATIVE_FILTERED_GENERAL_REASON_UNKNOWN.

4. Deal validation, inside the auction. This runs whenever any bid carries a dealid, private auction or not:

  • a bid whose dealid + seat matches no deal on the impression is dropped (INVALID_DEAL_ID);
  • a bid below its deal’s floor is dropped (BID_WAS_BELOW_DEAL_FLOOR);
  • a Bid floor price deal has the bid’s price overwritten with the deal floor, whatever was bid;
  • once any private-auction bid is present, every non-private bid is removed.

Corner case: a bid with no dealid is not dropped by stage 4 — it competes normally unless a private-auction bid displaces it. The page previously implied otherwise.

Is there a size limit on a bid’s markup or video? Not in Epom: the ad server sets no cap on the bid response or on adm, and a VAST in adm points at its video files by URL, so the file size never passes through Epom. A size limit quoted for a DSP’s video bids comes from the DSP, the player or the upload limit for your own video banners — not from the auction.

Native bids: which imptrackers and eventtrackers fire as impression beacons

For a native bid, Epom takes the impression trackers out of the native response in adm and fires them as impression beacons of the served ad, next to its own:

Native response versionTrackers fired at the impression
1.0, 1.1Every URL in imptrackers
1.2Every URL in imptrackers plus every eventtrackers entry with event: 1 (impression) and method: 1 (image pixel) that has a url — duplicates fired once

Not fired: eventtrackers with method: 2 (JavaScript), entries for other events (viewability 2–4 and custom events), and jstracker. Each tracker URL is macro-processed first, so ${AUCTION_PRICE} and similar auction macros are filled. In a native template the beacons are written as hidden 1×1 images by $$NATIVE_IMPRESSIONS$$, so they load when the ad renders — the same moment Epom’s own impression beacon fires. They do not change how Epom counts: the impression in Epom’s reports is Epom’s own beacon; the partner’s trackers feed the partner’s numbers.

Auction and clearing

Epom runs the auction over all surviving bids across all partners for the impression. Second-price clearing applies only when the auction type resolved to second price and more than one bid survived; the clearing price is then:

min( max(deal floor + $0.01, second-highest bid + $0.01), winning bid )

— so it never exceeds what the winner actually bid, and never drops below a deal’s negotiated minimum. With a single surviving bid the winner clears at its own price, capped toward the floor plus a cent when the banner is set to Always 2nd price. One cent is 0.01 USD.

The clearing price is what feeds the served markup’s price macro and the impression’s revenue — not necessarily the raw price the winner sent. See First vs second price for the full model.

Corner case: the DSP partner’s Second price only checkbox (and the matching banner-level network parameter) does not change the clearing rule. It withdraws the banner from the auction when it would be the only bidder — the partner is saying “only bid me when there is competition”. A partner that mysteriously never wins on low-competition inventory usually has this set.

Loss reasons

Epom fills ${AUCTION_LOSS} in your lurl with the numeric OpenRTB loss-reason code. Nine of the specification’s thirty codes are reachable:

CodeNameWhy Epom sends it
0BID_WONYou won
3INVALID_BID_RESPONSENot exactly one seatbid with one bid, or the bid’s impid matched no impression
4INVALID_DEAL_IDdealid + seat matched no deal on the impression
7MISSING_MARKUPThe winning bid produced no usable markup
100BID_WAS_BELOW_AUCTION_FLOORPrice under imp.bidfloor (non-deal bids only)
101BID_WAS_BELOW_DEAL_FLOORPrice under the matched deal’s floor
102LOST_TO_HIGHER_BIDOrdinary auction loss
103LOST_TO_A_BID_FOR_A_PMP_DEALLost to a deal bid
200CREATIVE_FILTERED_GENERAL_REASON_UNKNOWNRemoved by the creative scan

Note: 200 is the only signal you get for a creative-scan removal — the loss code does not say why the creative was removed.

Loss notices are sent only when the partner’s Call loss notification URL parameter is enabled.

Auction macros

Epom substitutes these in your nurl, lurl and adm before firing or serving them. An unresolvable macro is replaced with an empty string, never left in place.

MacroValue
${AUCTION_ID}The bid request id
${AUCTION_BID_ID}The response bidid
${AUCTION_IMP_ID}The impid of the impression won
${AUCTION_SEAT_ID}The winning seat
${AUCTION_AD_ID}The bid’s adid
${AUCTION_PRICE}The clearing price, not your bid
${AUCTION_PRICE:$$ENC$$}The clearing price, encrypted per the partner’s encryption setting
${AUCTION_CURRENCY}Always the literal USD
${AUCTION_CURRENCY:$$ENC$$}Encrypted form of the same
${AUCTION_LOSS}The numeric loss reason — see above
${AUCTION_MBR}Market bid ratio, clearing price ÷ bid price as OpenRTB defines it: 1 under first price, below 1 when a second-price auction clears under the bid

Note: the value is clearing ÷ bid, never the reciprocal, so it is at most 1. Do not invert it.

Epom as a seller: /hb/bid

Epom also answers OpenRTB bid requests, as a bidder in a Prebid auction. This is the header bidding path; the operational side — tags, slots, Prebid Server, reporting — is documented in Header bidding. The wire contract:

EndpointPOST /hb/bid on the ad-serving host. Any other method answers 405.
ProtocolOpenRTB 2.6
Requestid and at least one imp required; site or app required. Up to 40 impressions per request (configurable per network by Epom).
ValidationCheap field checks only, not full JSON-Schema. A rejection is a 400 with a JSON {"error": "<reason>"} body naming the reason.
No bid204 No Content — Epom does not send an OpenRTB no-bid object.
ResponseOne seatbid, seat epom, cur: "USD".

Each returned bid carries id, impid, price, adm, crid, cid, w, h, mtype (1 banner / 2 video / 4 native), exp, adomain when known, and dealid: "epom-direct" on bought demand.

Note: adomain is the Advertiser domain declared on the advertiser when the advertiser has one, otherwise the adomain that came in on the DSP bid the creative was bought from. When neither exists the field is omitted — an absent adomain is deliberate, not a bug.

Corner case: bid.exp tells you how long the bid may sit in your cache, and it is derived from the impression beacon’s own validity minus a few seconds of travel time. Render later than that and the impression is never counted — the bid is still valid markup, but you will not be paid for it.

Warning: a /hb/bid call is a bid, not a served impression, but Epom does not yet treat it as one: selection still increments opportunity limits, request capping and pacing for bids that never win or render. Expect header-bidding traffic to consume capping and limit budget ahead of actual delivery, and read the header bidding reporting notes before reconciling numbers.

Corner case: requests for a placement that no active header-bidding tag lists are refused by default. That gate has three settings and its own diagnostics — see Header bidding.

Corner case: on a video slot, bid.adm is a VAST document Epom builds, and for a VPAID framework creative its <Duration> can legitimately be 00:00:00. VAST requires a Duration on every Linear, but a VPAID creative’s real length is only known once the unit runs, so Epom emits a placeholder unless the framework declares a parameter literally named duration that parses as a positive number of seconds. A real duration always carries milliseconds (00:00:15.000); the bare 00:00:00 is the placeholder. Do not reject the creative on it, and do not use it to size a player or a timeout.

Partner “network parameters”

Beyond the OpenRTB fields above, a partner integration uses named parameters drawn from a fixed set of 18. These are partner-onboarding values, filled on the DSP partner and/or the OpenRTB banner — not OpenRTB spec fields. Sixteen are the checkboxes of the partner’s Parameters card: Template Content Adapter, Broker Url, Win Notification URL, Traffic Tier, Mask Inventory, Second Price Only, Allow empty DSP UUID, DSP Custom Currency, USD to DSP Custom Currency Rate, Force First Price Auction Type, Call loss notification URL, Send winner price in loss notification, Hash Publisher Site Field’s Values, Add Source Chain to Bid Request, Custom Source Supply Chain ASI and Interstitial. The other two are the template ids the code reads, Template Native Adapter and the deprecated Template General. No other keys are accepted.

None of them is a fee, margin, commission or revenue share; no such parameter exists.

Coverage note

This page documents both directions of the standard path in full: every field Epom’s builder populates, every response field it consumes, the filter pipeline, the loss reasons, the auction macros, and the seller endpoint’s contract.

This page does not enumerate per-partner-type differences. Several of the 16 branded partner types receive small partner-specific adjustments — a nulled or emptied banner object on pops, partner-specific imp.ext keys, forced interstitial, test:0, or the markup read from a partner-specific place in the response. They change when a partner’s integration is revised; ask Epom support or your account manager what your specific partner type sends.

Two limits that are not gaps but firm behaviour, restated so they are not mistaken for omissions: no dnt and no standard consent or regs on the outbound request — neither exists on Epom’s outgoing model. device.lmt is not in that category: it is sent whenever the ad request carried an lmt parameter — see Request: device.

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.