Advertisers (DSP) integration
We send you OpenRTB 2.5 bid requests for popunder traffic; you answer with a bid or no bid. You pay only for impressions confirmed by your own billing notice (burl), which we call for you.
Requests we send
POST {your bid endpoint}
Content-Type: application/json
X-Openrtb-Version: 2.5
{your authentication headers, if any}- The body is the publisher's OpenRTB 2.5 request. We change only
imp.bidfloor: it may be raised by our margin and is always sent as a number. Everything else —site,device,user,imp,regs,source,ext— is passed to you as received. - Currency: USD. Auction: first price (
at= 1). Your bid price is what you pay. - Rate: never more requests per second than the QPS cap agreed with you, and never more requests in flight than agreed.
- Filters: we can send you only the traffic you want — allow or block lists by country, OS and OS version, browser, device type, domain and site.
Timeouts
tmax is passed as the publisher sent it (up to 250 ms). We wait for your answer up to tmax minus our network reserve (about 40 ms) and the time already spent. Answer well within tmax: late answers are dropped and counted as timeouts.
Your answer
| Code | Meaning |
|---|---|
| 200 + JSON | A bid |
| 204, or 200 with an empty body | No bid |
| 429 | Too many requests: counted separately, never retried |
| Anything else, or late | Counted as an error |
Bid response fields
| Field | Required | Notes |
|---|---|---|
id | yes | Must equal the request id |
cur | no | USD or absent |
seatbid[].bid[].impid | yes | An imp.id from the request |
price | yes | CPM in USD, above 0, at or above imp.bidfloor, at most 1000 |
adm | yes | The landing URL (http or https), or the popunder XML wrapper <ad><popunderAd><url>…</url></popunderAd></ad> |
burl | yes | Your billing notice URL: https, on a domain agreed with us. Use ${AUCTION_PRICE} for the price |
nurl | recommended | Your win notice URL (statistics only): https, on an agreed domain |
adomain, cat, crid, adid, cid | recommended | Bids whose adomain or cat the publisher blocked (badv / bcat) are dropped |
Bids without burl, with a burl that is not https or not on an agreed domain, with an unreadable adm, below the floor or above $1000 CPM are dropped. One bid per impression is used: the highest one.
{
"id": "079675c8bdb440daa073c39fbac3bacc",
"seatbid": [{
"seat": "seat-1",
"bid": [{
"id": "b-1",
"impid": "3851dc773b66462f81bc32c3a07a08aa",
"price": 0.045,
"adm": "https://landing.advertiser.example/offer?cid=42",
"burl": "https://notify.advertiser.example/bill?price=${AUCTION_PRICE}&auction=${AUCTION_ID}",
"nurl": "https://notify.advertiser.example/win?price=${AUCTION_PRICE}",
"adomain": ["advertiser.example"],
"crid": "cr-7",
"cid": "42"
}]
}],
"cur": "USD"
}Macros
We fill these macros in your burl and nurl, written plain (${…}) or URL-encoded (%24%7B…%7D):
| Macro | Value |
|---|---|
${AUCTION_PRICE} | Your bid price, exactly as you sent it |
${AUCTION_ID} | The request id |
${AUCTION_BID_ID} | Your bid.id |
${AUCTION_IMP_ID} | The impid of your bid |
${AUCTION_SEAT_ID} | Your seat |
${AUCTION_AD_ID} | Your adid |
${AUCTION_CURRENCY} | USD |
If your burl has no ${AUCTION_PRICE}, we still accept the bid; your system then records the impression at your own bid price, which in a first-price auction is the same number.
Notices we send you
| Notice | When | How |
|---|---|---|
burl (billing) | After the publisher confirms the impression to us | GET, usually within a second; retried with back-off for up to 5 minutes and never later than your acceptance window (300 s from the bid by default) |
nurl (win) | When our bid wins at the publisher | GET, once; statistics only |
How we treat your answer to the billing notice
- 2xx — delivered.
- 409 — too late; we do not retry.
- 429 — we retry.
- 5xx, redirects and network errors after the request was sent — the outcome is unknown. Unless you confirm in writing that repeated notices are de-duplicated on your side, we do not repeat them, so an impression is never billed twice.
We do not follow redirects and do not keep connections open between notices. Notices go only to public addresses on your agreed domains.
Billing only on burl. No billing notice — no charge. Each confirmed impression is stored durably on our side before your notice is queued, so a restart never loses it.
Statistics and reconciliation
Your statistics with us — requests we sent you, your bids, wins, billed impressions and spend — are updated every minute and available by the reporting API. If you give us a read-only key to your reporting API, we reconcile with your numbers every day.
FAQ
Why were my bids dropped?
The most common reasons are a burl on a domain we have not agreed yet, a burl over plain http, a price below imp.bidfloor, or a response id that does not match the request. Ask your manager for the breakdown.
Can I use several billing domains?
Yes — tell your manager every host your burl and nurl use (with the port, if it is not the default one).
Do you send second-price or loss notices?
No. The auction is first price and there is no lurl.
How do I slow you down?
Ask your manager to lower the QPS cap of your feed. HTTP 429 answers are counted separately, but the cap is what limits the rate.
Questions about the integration? Write to manager@gfybid.com or use the contact form.