Programmatic broadsheet · Set in real time
adon3
The Real-Time Bidding Exchange
Integration Docs
Supply side · XML feed · OpenRTB 2.6 / 2.5

Substitution Macros

The markup and notice URLs we return contain placeholder tokens. You replace them with real values before you render the creative and before you fire the notices. The clearing price is not known when the buyer writes the bid, so it cannot be written into the markup at that point.

This is your job as the seller, not ours. A creative rendered with the tokens still in it will not track, and a notice fired with ${AUCTION_PRICE} unreplaced records the win at no price.

How substitution works

Every macro takes the form ${NAME}. Replacement is literal string replacement across the whole of adm, nurl and burl. Scan for the tokens listed below, swap in the values, and leave anything you do not recognise untouched.

Do the substitution after you have decoded the JSON string and before you write the markup into the page. Substituting inside the raw JSON body works too, but it puts URL-encoded values into places that expect plain ones.

The macros

These are the substitution macros defined by OpenRTB. The right-hand column says where each one comes from in the exchange you just ran.

MacroReplace with
${AUCTION_ID}BidRequest.id, the id you generated for the auction
${AUCTION_BID_ID}BidResponse.bidid
${AUCTION_IMP_ID}imp.id from your request
${AUCTION_SEAT_ID}seatbid.seat
${AUCTION_AD_ID}bid.adid
${AUCTION_PRICE}The settlement price, as a plain decimal CPM
${AUCTION_CURRENCY}BidResponse.cur
${AUCTION_MBR}Minimum bid to win, when you disclose it
${AUCTION_MIN_TO_WIN}Minimum bid that would have won, when you disclose it
${AUCTION_LOSS}Loss reason code, on loss notices only

${AUCTION_LOSS} applies to lurl, which we do not return to you because we send you the winner rather than the full bid landscape. It is listed here for completeness.

${AUCTION_MBR} and ${AUCTION_MIN_TO_WIN} are optional disclosures. Substitute them with an empty string if you do not disclose that figure, rather than leaving the token in place.

The price macro

${AUCTION_PRICE} is the settlement price, not bid.price. Under a second-price auction (at of 2) it is normally below what the buyer bid. It is expressed as a plain decimal CPM in ${AUCTION_CURRENCY}, for example 1.204800.

Substitute the same value into the markup and into both notices. A creative that reports one price and a billing notice that reports another produces a reconciliation dispute that takes days to unpick.

Worked example

We return this nurl in the bid:

Plain
https://dsp.example.com/win?a=${AUCTION_ID}&b=${AUCTION_BID_ID}&p=${AUCTION_PRICE}&c=${AUCTION_CURRENCY}

The bid of $1.50 wins your auction, the runner-up bid $1.2048, and BidResponse.bidid is bid-77e3c0a9. You fire:

Plain
https://dsp.example.com/win?a=8f2a1c30-6b4e-4d9a-9f11-2c7e3b5a8d40&b=bid-77e3c0a9&p=1.204800&c=USD

The same substitution applies inside adm:

JSON
"adm": "<img src=\"https://cdn.acme.example/300x250.jpg\" width=\"300\" height=\"250\"><img src=\"https://dsp.example.com/imp?p=${AUCTION_PRICE}\" width=\"1\" height=\"1\">"

Checking your work

Before you go live, grep a rendered page and a fired notice for the literal string ${. If it appears anywhere, substitution is incomplete. This is the check that catches the majority of integrations that pass everything else and still report no revenue.

Next: Errors & No-Bids.

sellers.json · schain enforced · OpenRTB 2.5 / 2.6 / 3.0 · XML
Printed on the Open Exchange
—  Integration Docs  —