Engineering · 13 Jan 2026
nurl, burl, and lurl: when an OpenRTB win actually bills
Winning the auction, showing the ad, and charging for the ad are three events. OpenRTB gives each one a URL so they are not mistaken for each other.

A DSP sends a bid. The SSP picks a winner. Money should move only if the ad had a real chance to be seen, under the billing event both sides agreed. If you charge on the auction decision alone, you will invoice impressions that never left the server.
OpenRTB splits that story into three callbacks on the bid response: nurl, burl, and lurl.
nurl: you won
The win notice URL fires when the exchange selects this bid as the auction winner. It is allowed to carry the clearing price, using the ${AUCTION_PRICE} macro, so the DSP can learn what the impression cleared for.
A win notice is not proof the creative played. The auction can pick a winner and the app can still crash, the pod can run out of time, or a higher-priority sponsorship can take the slot a moment later. Treat nurl as “we chose you,” not “you may invoice.”
burl: you may bill
The billing notice URL fires when the exchange’s billing event happens. For many display and video deals that event is the impression, as the exchange defines it in the integration. This is the URL that should drive spend in the DSP and revenue in the SSP.
If your integration supports burl, do not also add spend when nurl fires. Double-counting wins is how discrepancy tickets start. One event bills. The other informs.
lurl: you lost, and why
The loss notice URL fires when this bid does not win. A reason code can say the bid was below the floor, lost on price, failed a creative check, or lost to a deal. Serious bidders use those codes to tune shading and to stop sending creatives you will never approve.
Loss notices are optional in older stacks and easy to drop under load. If you care about win rate, ask for them on a sample before you assume the floor is the only reason you lose.
A clean sequence
- DSP bids, and includes nurl, burl, and lurl.
- Exchange runs the auction and substitutes the clearing price into the winning URLs.
- Exchange calls lurl on the bids that lost, when it supports loss notices.
- Exchange calls nurl on the winner so the DSP can record the clear.
- Exchange calls burl when the billable event happens. The DSP increments spend here.
Call the URLs from the server when you can. A browser or television that never loads the pixel should not be the only copy of your invoice.
Macros you will actually see
${AUCTION_PRICE}— the price the exchange expects to use for settlement, in the currency you agreed.${AUCTION_LOSS}— on lurl, a code for why this bid lost.${AUCTION_ID}and related IDs — so the notice can be joined back to the bid request in your logs.
Replace macros on the server before the call. A DSP that receives the literal text ${AUCTION_PRICE} cannot reconcile the impression.
FAQ
What if the exchange only supports nurl?
Agree in writing that nurl is the billing event, and accept that you will over-count whenever a win does not render. Move to burl when the exchange offers it.
Should a loss notice include the winning price?
Some exchanges send a minimum bid to win. That helps shading. It is still not a bill. Nothing on lurl should increment spend.
Does this change in a fixed-price deal?
The auction type changes the price you substitute. The roles of the three URLs stay the same: win, bill, and loss.
← All posts · What is OpenRTB? · OpenRTB integration · First-price auctions