Advertiser guide
v2.10 · 21 October 2026
Start here
- Create a campaign and wait for approval.
- Put
{click_id}in your landing URL, and{sub_id}to see which source each click came from. - Send us a postback for every conversion.
Campaign
A campaign leads either to one landing URL or to an offer feed — a list of your offers that the campaign rotates by itself.
Choose the vertical: Adult, Mainstream or All. Redirect (pop) runs on both verticals. Teaser and in-page push need an image and a title.
Campaign review
Every campaign is checked before it starts, and again after you change its landing URL, ad text, creative or format. Changing the bid, targeting or on / off does not send it back.
| State | What it means |
|---|---|
| In review | Not running yet. |
| Approved | Running and spending. |
| Rejected | Not running. The dashboard shows the reason. |
Fix what the reason says and save — the campaign goes back into the queue by itself.
Feed rows are not reviewed one by one: a new or edited row goes live on the next feed update. Where your rows lead is your responsibility. If a landing we serve turns up on a phishing list, the whole campaign is rejected.
Bids
Redirect (pop), teaser and in-page push each have their own bid. An empty one uses the campaign's main bid.
The bid is a price, not an on-off switch: a zero is ignored and the main bid applies. To stop
a placement, narrow the campaign's format or set delivery on your feed rows.
Budget limits
Three spend limits in USD. Leave any of them empty for no limit.
- Per hour
- Per day — resets at midnight, Moscow time.
- Total — for the whole life of the campaign. Never resets.
When a limit is reached, the campaign stops and shows Budget spent. It starts again when the hour or day rolls over. Limits apply within a few minutes, so spend can go slightly over.
Offer feed
Keep your list of offers at an HTTPS URL. We fetch it every 15 minutes.
JSON,CSVorXML, UTF-8. Up to 2000 rows and 8 MB, answer within 8 seconds.- Your own field names are fine — tell us once and we map them.
- An offer missing from the feed is paused, not deleted. It comes back when it reappears.
- If the feed is down or broken, we keep the last good version. An empty feed stops the campaign.
| Feed field | Required | Meaning |
|---|---|---|
| ext_id | required | Your offer id: a-z 0-9 _ -, up to 32 characters. Reports group by it, so keep it stable. |
| url | required | Landing URL. Must contain {click_id}, otherwise the row is rejected. |
| payout | recommended | What one conversion is worth to you, USD. Offers are ranked by conversion rate × payout. |
| coef | optional | Bid multiplier for this offer, 0.05–20. Empty or invalid = 1.0. |
| geo | optional | Country codes, comma-separated: US,CA. Empty = all countries. |
| device, os, browser | optional | Targeting. Empty = all. |
| title, text, image | for teaser / push | The ad itself. Without image and title the offer runs on redirect only. |
| title_ru, text_ru, … | optional | The same text in other languages. |
| vertical | optional | adult or mainstream limits the row to that vertical. Empty or both = no limit. The vertical a row is shown in is always the campaign's. |
| delivery | optional | pop, teaser or push — only that placement. Empty = all. |
[
{"ext_id": "dating_us_1", "url": "https://example.com/lp1?click_id={click_id}&sub1={sub_id}",
"payout": 3.5, "geo": "US,CA", "device": "mobile"},
{"ext_id": "dating_eu_2", "url": "https://example.com/lp2?click_id={click_id}",
"payout": 2.0, "geo": "DE,FR", "coef": 1.5,
"title": "Meet singles nearby", "text": "Sign up free", "image": "https://example.com/1.jpg",
"title_de": "Singles in deiner Nähe", "text_de": "Kostenlos anmelden"}
]
To get results
- Fill in
geo— a row without it is shown in every country. - Fill in
payout— without it a cheap offer can push out an expensive one. - Keep
titleandtextshort — we do not trim them for you. Anything over 255 characters is cut mid-word. About 90 characters reads well. urlandimagemust be public internet addresses.
Translations go as title_de / text_de or as
"title": {"en": "…", "de": "…"}. Each visitor gets their language,
otherwise the base title and text. Up to 24 languages per row.
Tracking
Put macros into your landing URL — we fill in real values on every click. If we have no value, the macro comes through empty.
https://your-lander.com/?cid={click_id}&src={sub_id}&offer={offer_id}&geo={geo}
| Macro name | Value |
|---|---|
{click_id} | Click id. Required — send it back in the postback. |
{sub_id} | Traffic source, as a token. It never changes, so you can block or allow sources by it in the campaign's Sources. |
{offer_id} | ext_id of the feed row that was shown. |
{camp_sid} | campaign_sid, as in your dashboard. |
{link_sid} | Id of the publisher placement. |
{geo} | Country, two letters. |
{city} | City, when known. |
{format} | pop, teaser, push or video. |
{vertical} | adult or mainstream. |
{device} | mobile, desktop, tablet or tv. |
{os} | Android, iOS, Windows, … |
{browser} | Chrome, Safari, Firefox, … |
{interest} | Niche of the page. |
{hair} | blonde, brunette, red. |
{skin} | light, tan, dark. |
{ethnicity} | asian, black, latina. |
{age} | young, mature. |
{body} | slim, curvy, busty. |
We do not pass the visitor's IP or User-Agent.
GET /pb — Conversions
Send us one request per conversion:
GET https://adorado.net/pb?cid={click_id}&event=signup&txid=<your event id>
| Param | Meaning |
|---|---|
| cid | required The {click_id} from the click. |
| event | required Event name: signup, purchase, … |
| txid | optional Your id of the event. With it a repeated request is not counted twice. |
| value | optional Event value, USD. |
| Reply | HTTP | What to do |
|---|---|---|
ok | 200 | Accepted. |
dup | 200 | Already counted. Stop retrying. |
unknown | 404 | No such click. Do not retry. |
retry | 503 | Problem on our side. Retry later. |
Conversions count for 90 days after the click.
GET /api/statistic — Statistics
GET https://adorado.net/api/statistic?api-key=<KEY>&role=advertiser
role=advertiser. Without it you get a report on traffic
sold to us, not bought from us — usually empty.| Param | Meaning |
|---|---|
| api-key | required Your key, from the Profile page. |
| role | required advertiser. |
| startDate | optional YYYY-MM-DD. Default: 7 days before endDate. |
| endDate | optional YYYY-MM-DD. Default: today. Up to 90 days per request. |
| groupBy | optional Up to three, comma-separated: date, hour, campaign, geo, sub_id, offer. Default: date. With hour — up to 14 days. |
| sid | optional One campaign only, by its campaign_sid from the dashboard. |
| event | optional Count only this conversion event. Default: all events. |
{
"currency": "USD",
"role": "advertiser",
"groupBy": "geo",
"rows": [
{"key": "US", "clicks": 1840, "spend": 9.2, "conversions": 24},
{"key": "DE", "clicks": 610, "spend": 3.05, "conversions": 6}
],
"total": {"clicks": 2450, "spend": 12.25, "conversions": 30}
}
| Field | Meaning |
|---|---|
| key | Value of the grouping. With two or three groupings each row has them by name: {"geo": "US", "offer": "a12", …}. |
| clicks | Clicks you paid for. |
| spend | USD. |
| conversions | Postbacks we accepted, by the day they arrived. |
| total | The whole period. |
| truncated | Only when the answer hit 5000 rows. Shorten the period or the grouping. |
| note | Only when something about the answer needs explaining. |
| Error | When |
|---|---|
| 400 | Wrong date, grouping or campaign_sid, or the period is too long. The reply says which. |
| 401 | No api-key. |
| 403 | Wrong api-key. |
| 429 | More than one request per 10 seconds. |
Ready-made requests
# by day
…&role=advertiser&groupBy=date
# which sources bring signups, last 30 days
…&role=advertiser&groupBy=sub_id&startDate=2026-09-06&endDate=2026-10-05&event=signup
# offers of one campaign
…&role=advertiser&groupBy=offer&sid=<campaign_sid>
# by country and source
…&role=advertiser&groupBy=geo,sub_id
GET /api/sources — Sources
GET https://adorado.net/api/sources?api-key=<KEY>&sid=<campaign_sid>
POST https://adorado.net/api/sources
api-key=<KEY>&sid=<campaign_sid>&list=black&action=add&sub_id=tok1,tok2
| Param | Meaning |
|---|---|
| api-key | required Your key, from the Profile page. |
| sid | required campaign_sid from the dashboard. |
| list | POST required white — buy only these sources, black — never buy them. |
| action | POST required add, remove, or set — replace the whole list (empty sub_id clears it). |
| sub_id | POST Sources, comma-separated, up to 500 per list. (none) — traffic without a source. |
| confirm | POST 1 when the change turns the whitelist on or off. |
{"sid": "c1a2b3c", "white": [], "black": ["tok1", "tok2"], "whitelist_on": false, "added": 2, "removed": 0}
| Field | Meaning |
|---|---|
| white, black | The lists after your request. |
| whitelist_on | true — we buy only from white. |
| added, removed | POST only: how many sources your request changed. |
| Error | When |
|---|---|
| 400 | Wrong campaign_sid, list, action or source. The reply says which. |
| 401 | No api-key. |
| 403 | Wrong api-key. |
| 409 | The change turns the whitelist on or off. Repeat with confirm=1. |
| 429 | More than 5 requests per 10 seconds. |
Publisher guide
v2.10 · 21 October 2026
Start here
- Add your site in the dashboard and wait for approval.
- Open the site card and copy a code. The easiest one is the Smart Tag.
- Put the code on your pages. Your earnings show up in Statistics; withdraw them in Billing (USDT TRC-20, from $100).
Smart Tag
One line on every page of your site.
<script src='https://example.com/stg?sid={SID}' type='text/javascript' async></script>
What visitors get depends on the Optimization goal in the site settings:
- Retention: ad blocks inside your content only.
- Balanced: blocks, plus push and video at most every 30 minutes and a popunder at most once an hour.
- Max monetization: blocks, plus push and video at most every 10 minutes and a popunder at most every 15 minutes.
A popunder never opens in a visitor's first minutes on your site. Blocks per page (1–3) and their look are set on the site's Design page. The Smart Tag already includes every format, so don't add the separate tags on the same pages.
GET /r — Pop (redirect)
Request
GET https://example.com/r?sid={SID}&ip=21.222.194.22&ua=Mozilla%2F5.0%20...&sub_id={YOUR_SUB_ID}&page=https%3A%2F%2Fexample.com%2F&lang={LANG}
Parameters
| Param | Type | Required | Description |
|---|---|---|---|
| sid | string | required | Your source ID from the dashboard. |
| ip | string | required | Visitor IPv4/IPv6 address. |
| ua | string | required | Visitor User-Agent, URL-encoded. |
| sub_id | string | optional | Your sub-source ID (max 128 chars). |
| page | string | optional | Page URL (max 512 chars). Improves bid rate. |
| lang | string | optional | Visitor browser language (Accept-Language, max 32 chars). |
Response
{
"currency": "USD",
"url": "https://example.com/m/6f1c2e4a-.../",
"bid": 0.00123,
"displayurl": "example.com"
}
| Field | Type | Description |
|---|---|---|
| url | string | Redirect the visitor's browser to this URL (302 / window.open / popunder). |
| bid | float | Your payout for a counted click. |
| displayurl | string | Display domain of the offer. |
- No bid → HTTP
200with an empty object{}. - HTTP
400— missingsidor malformedip. - Recommended client timeout: 800 ms.
url is single-visitor, TTL 10 minutes.Billing: you get bid (USD) for each counted click. Invalid traffic is not paid.
GET /p — In-Page Push
Request
GET https://example.com/p?sid={SID}&ip=21.222.194.22&ua=Mozilla%2F5.0%20...&sub_id={YOUR_SUB_ID}&page=https%3A%2F%2Fexample.com%2F&lang={LANG}
Parameters
| Param | Type | Required | Description |
|---|---|---|---|
| sid | string | required | Your source ID from the dashboard. |
| ip | string | required | Visitor IPv4/IPv6 address. |
| ua | string | required | Visitor User-Agent, URL-encoded. |
| sub_id | string | optional | Your sub-source ID (max 128 chars). |
| page | string | optional | Page URL (max 512 chars). Improves bid rate. |
| lang | string | optional | Visitor browser language (Accept-Language, max 32 chars). |
Response
{
"currency": "USD",
"url": "https://example.com/m/6f1c2e4a-.../",
"bid": 0.00087,
"displayurl": "example.com",
"title": "Some title",
"image": "https://.../creative.png",
"icon": "https://.../icon.png",
"descr": "Some description text"
}
| Field | Type | Description |
|---|---|---|
| title | string | Notification title. |
| image | string | Creative image URL. |
| icon | string | Notification icon URL. |
| descr | string | Notification body text. |
| url | string | Open this URL in the visitor's browser on click. |
| bid | float | Your payout for a counted click. |
| displayurl | string | Display domain of the offer. |
- No bid → HTTP
200with an empty object{}. - HTTP
400— missingsidor malformedip. - Recommended client timeout: 800 ms.
url on user click; it expires in 10 minutes after the feed response.Billing: you get bid (USD) for each counted click. Invalid traffic is not paid.
GET /vast — Video (Pre-Roll / VAST link)
Pre‑Roll and VAST link are the same tag. Use your site's sid (Adult or Mainstream).
Request
GET https://example.com/vast?sid={SID}
Hand this URL to any VAST-compatible player (Google IMA, JW Player, video.js, …) as the ad tag. The tag must be fetched client-side, in the viewer's browser/player — visitor IP and User-Agent are taken from the tag request itself.
- Response is VAST 4.1 XML; no demand → a valid empty
<VAST version="4.1"></VAST>— the player simply shows no ad. - Plain H.264/AAC
MediaFiles, no VPAID/SIMID. - The player fires all tracking itself (impression, quartiles,
ViewableImpression, click-through) — you call nothing back.
Billing: CPM — you are paid per viewable impression (not per click), USD. VAST placements start measure-only and turn paid per source.
Video demand — OpenRTB (demand partners)
We also buy out-stream video demand server-side via OpenRTB 2.x. You share a bid endpoint URL with your account manager; for each eligible visitor our server POSTs a JSON BidRequest and renders the winning VAST creative in an out-stream player on the publisher page.
Bid request (what we send)
POST {your-endpoint}
Content-Type: application/json
{
"id": "<uuid>",
"cur": ["USD"],
"imp": [{
"id": "1", "bidfloor": 0.01, "bidfloorcur": "USD", "secure": 0,
"video": {
"mimes": ["video/mp4", "video/webm", "application/javascript"],
"protocols": [2, 3, 5, 6, 7, 8],
"w": 640, "h": 480,
"minduration": 0, "maxduration": 60,
"linearity": 1, "skip": 1, "placement": 5, "startdelay": 0
}
}],
"site": {"domain": "example.com", "page": "http://example.com/page", "cat": ["IAB25"]},
"device": {"ip": "203.0.113.7", "ua": "Mozilla/5.0 ...", "language": "en"},
"user": {"id": ""}
}
placement: 5— out-stream (slider / floating);protocols— VAST 2.0 / 3.0 / 4.0 including wrappers.- Response timeout: 800 ms.
Bid response (what we expect)
{
"seatbid": [{ "bid": [{
"price": 1.25,
"adm": "<VAST version=\"3.0\">...</VAST>",
"nurl": "https://your.host/win?p=${AUCTION_PRICE}"
}]}]
}
| Field | Type | Description |
|---|---|---|
| price | float | Your bid, CPM (USD per 1000 impressions). |
| adm | string | VAST XML — InLine or Wrapper. Wrappers are followed server-side (up to 3 hops, ≤256 KB and ~700 ms per document); the final InLine must carry a progressive MP4 / WebM MediaFile. |
| nurl | string | Optional win notice — fired server-side when the creative is served. |
- No bid → HTTP
204or an empty body. ${AUCTION_PRICE}and${AUCTION_CURRENCY}macros are substituted innurland tracker URLs.
Billing: CPM — per impression, USD.
GET /api/statistic — Statistics API
Request
GET https://adorado.net/api/statistic?api-key={API_KEY}&startDate=2026-07-01&endDate=2026-07-07&groupBy=date,geo
Parameters
| Param | Type | Required | Description |
|---|---|---|---|
| api-key | string | required | Your API key from the dashboard Profile page. |
| startDate | string | optional | Period start, YYYY-MM-DD (inclusive). Default: 7 days before endDate. |
| endDate | string | optional | Period end, YYYY-MM-DD (inclusive). Default: today. Max range: 90 days (14 days when grouping by hour). |
| groupBy | string | optional | Up to 3 comma-separated dimensions: date (default), hour, site, format, sub_id, geo, os, browser, device. Unknown dimensions are rejected with 400. |
| sid | string | optional | Restrict the report to a single source (its sid). Omit for account-wide totals across all your sources. An unknown sid is rejected with 400. |
Dimensions
| Dimension | Values |
|---|---|
| date | YYYY-MM-DD, server time (UTC+3). |
| hour | 00–23, server time (UTC+3). |
| site | Your source sid. |
| format | pop / push / teaser / clickunder / video. |
| sub_id | Your sub-source ID as sent in the feed request. |
| geo | ISO 3166-1 alpha-2 country code of the visitor. |
| os | Visitor OS family: Android, iOS, Windows, macOS, Linux, … |
| browser | Visitor browser family: Chrome, Safari, Firefox, … |
| device | mobile / desktop. |
Response — single dimension
{
"currency": "USD",
"groupBy": "geo",
"rows": [
{"key": "US", "clicks": 1520, "uniqs": 1381, "payout": 1.87342100},
{"key": "SG", "clicks": 1340, "uniqs": 1274, "payout": 1.60218000}
],
"total": {"clicks": 2860, "uniqs": 2650, "payout": 3.47560100}
}
Response — combined dimensions (one named field per dimension instead of key)
{
"currency": "USD",
"groupBy": "date,geo",
"rows": [
{"date": "2026-07-01", "geo": "US", "clicks": 812, "uniqs": 745, "payout": 1.02160000},
{"date": "2026-07-01", "geo": "SG", "clicks": 700, "uniqs": 671, "payout": 0.85182100}
],
"total": {"clicks": 1512, "uniqs": 1410, "payout": 1.87342100}
}
| Field | Type | Description |
|---|---|---|
| key | string | Group value (single-dimension responses only). |
| clicks | int | Counted (paid) clicks. |
| uniqs | int | Unique visitor IPs within the group. Not included in plain date / site reports. |
| payout | float | Your earnings, USD. |
- Only counted clicks are included; traffic rejected by anti-fraud is excluded.
groupBy=dateandgroupBy=sitetotals match your balance; withsid=, that site's figures in the dashboard.- Rows are sorted by
payoutdescending (time-only groupings — newest first). A response is capped at 5000 rows; if the cap is hit, it carries"truncated": true— narrow the date range or reduce dimensions. - Data for the current day is updated in near-real-time and may still be adjusted; previous days are final.
- Rate limit: 1 request per 10 seconds.
- Errors are JSON:
{"error": "..."}with status400/401/403/429.