SSP Auction

On every approved impression, Inlay runs a real-time first-price auction across all configured SSPs. This page covers the auction architecture, OpenRTB request structure, winner selection, and impression recording in detail.

Overview

Inlay's auction is implemented as a server-side header bidding wrapper. All SSPs receive bid requests simultaneously — each in its own isolated promise with an independent abort controller. The auction collects responses as they arrive, then selects a winner once either all SSPs have responded or the hard timeout has elapsed.

The entire auction runs within the HTTP request lifecycle of POST /api/serve/{siteScriptId}. The endpoint does not return until a winner is selected and the winning creative is rendered server-side — there is no asynchronous rendering step on the client.

OpenRTB request

Bid requests comply with IAB OpenRTB 2.6 and the Native Ad Specification 1.2. Each request is routed to the SSP's hosted Prebid Server endpoint as a standard POST with the following key fields:

FieldValue
idUnique auction ID (CUID)
imp[].idUnique impression ID
imp[].nativeIAB Native request: title, image (300×200 min), body, sponsored label, icon, CTA assets
imp[].bidfloorPlacement floor CPM converted to per-impression USD (floorCpm ÷ 1000)
imp[].bidfloorcur"USD"
site.pageFull URL of the publisher's page (from embed script request)
site.domainHostname of the publisher's domain
site.publisher.idInlay's publisher account ID registered with the SSP
device.uaUser-agent forwarded from the visitor's request headers
device.ipVisitor IP address forwarded from the request
tmaxSSP-specific bid deadline in milliseconds (default 450)

Real publisher domain in every request

The site.page and site.domainfields always carry the visitor's actual publisher page URL — not Inlay's domain. This is the mechanism that allows SSPs to verify the supply chain against the publisher's ads.txt file and maintain inventory quality scoring.

Auction execution

Each SSP is wrapped in a Prebid Server adapter that handles serialisation, deserialisation, error isolation, and native creative parsing. Adapters are fully independent — a timeout or network error from one SSP has no effect on the others.

Timeout behaviour

  • Each SSP adapter enforces its own request deadline (default: 450 ms)
  • A hard auction cap of 500 ms is enforced at the orchestration layer via AbortController
  • SSPs that have not responded by their per-adapter deadline are excluded from this auction
  • Network failures and non-2xx responses return null and are silently excluded

Parallel execution

All enabled SSP adapters are started concurrently before any individual response is awaited. Auction duration is bounded by the slowest responding SSP — up to 450 ms — not the sum of all SSP latencies. Five SSPs configured results in the same wall-clock auction time as a single SSP.

Winner selection

Once all bids are collected, the auction selects a winner as follows:

  • All null responses (timeout, network error, no fill) are discarded
  • Remaining bids are filtered against the placement's floorCpm
  • Bids are sorted descending by CPM value; the highest bid wins
  • Ties are broken in favour of the first bid received

This is a first-price sealed-bid auction. The winner pays exactly the price it bid — there is no second-price (Vickrey) adjustment.

Win notification

After the creative is rendered and the HTTP response is returned to the embed script, Inlay fires the winning SSP's win notification URL (nurl) asynchronously. The nurl is an OpenRTB standard field that:

  • Confirms to the SSP that the impression was delivered
  • Triggers billing reconciliation on the SSP side
  • Accepts macro substitutions for ${AUCTION_PRICE}, ${AUCTION_ID}, and ${AUCTION_BID_ID} — substituted by Inlay before the request is fired

Win notification failures do not affect impression recording on Inlay's side. The request is fired with keepalive: true to ensure delivery even if the serve function exits before the request completes.

Impression recording

After a successful auction, the serve endpoint records the impression synchronously before returning a response:

  • An AggregatedMetrics row is upserted (daily rollup per placement), incrementing the impression count and accumulating publisher revenue
  • An SspImpression row is written with the full timestamp, winning SSP name, and CPM — used for monthly payout reconciliation and the earnings SSP breakdown

Publisher revenue per impression is calculated as:

publisherRevenue = (winningCpm ÷ 1000) × 0.70

Only SSP-won impressions generate revenue. House ad impressions increment the impression counter but contribute $0.00 to revenue and are excluded from payout calculations.

House ad fallback

When no SSP bid clears the placement's floor — whether because no SSPs are configured, all bids fell below the floor, or all SSPs timed out — Inlay renders a house ad into the publisher's approved template. The house ad is structurally identical to a real creative from the browser's perspective: same template, same injection mechanism, no impression trackers fired.

House ad impressions appear in the total impression count in the analytics dashboard but are excluded from SSP impression breakdowns and do not contribute to the monthly payout calculation.