Publisher API
The publisher endpoints are prefixed with /api/publisher. Except for login / register / password reset, all require the publisher JWT: Authorization: Bearer <token>.
For the response envelope, pagination, and error-code conventions, see Overview & Authentication.
Authentication
Login
POST /api/publisher/auth/login
| Param | Type | Required | Description |
|---|---|---|---|
username | string | Yes | Username or registered email |
password | string | Yes | Login password |
curl -X POST https://api.adbnk.co/api/publisher/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"pub_demo","password":"secret123"}'The response structure matches advertiser login, returning token / token_type / expires_in / user.
Other auth endpoints
| Method | Path | Description |
|---|---|---|
POST | /auth/register | Register |
POST | /auth/forgot-password | Send reset email, param email |
POST | /auth/reset-password | Params token, new_password, confirm_password |
POST | /auth/logout | Log out |
GET | /auth/profile | Current publisher info |
POST | /auth/password | Change password (old_password/new_password/confirm_password) |
Sites
List
GET /api/publisher/sites
| Param | Type | Required | Description |
|---|---|---|---|
page / page_size | int | No | Pagination |
keyword | string | No | Name/domain search |
status | string | No | Status |
audit_status | string | No | Review status |
start_date / end_date | date | No | Creation time range |
Create a site
POST /api/publisher/sites
| Param | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Site name |
media_type | string | No | Media type: WEB (default) / APP / TELEGRAM |
media_type_id | int | No | Sub-type of the media type. It must belong to the site's media_type; otherwise the request fails with 400 error.site.media_type_id_invalid |
domain | string | Yes* | Required for WEB and TELEGRAM; must be a valid, unclaimed domain. For TELEGRAM it is the domain of the Mini App URL |
app_package | string | Yes* | Required for APP; package name unique |
url | string | No | Site URL; auto-set to https://<domain> when omitted. For TELEGRAM, send the https URL of the Mini App |
tg_bot_username | string | Yes* | TELEGRAM only. Bot username: 5–32 characters; starts with a letter, then letters, digits or underscores, and ends with bot (any case). A leading @ is accepted and removed |
tg_app_short_name | string | No | TELEGRAM only. Mini App short name, 3–30 letters, digits or underscores |
description | string | No | Site description |
industry_id | int | No | Industry ID |
icp | string | No | ICP filing number |
curl -X POST https://api.adbnk.co/api/publisher/sites \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"name":"My Blog","media_type":"WEB","domain":"blog.example.com"}'A new site defaults to audit_status=PENDING and must be approved before zones can be created.
Telegram Mini App sites
To add a Telegram Mini App, send media_type=TELEGRAM with domain, url, tg_bot_username and, optionally, tg_app_short_name. Don't send a Bot ID or a bot token: we look up the bot from its username. The Telegram fields can't be changed after the site is created (they are ignored on PUT); to use another bot, add a new site. Telegram sites are always reviewed manually. See Telegram Mini App for the whole setup.
curl -X POST https://api.adbnk.co/api/publisher/sites \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"name":"My Mini App","media_type":"TELEGRAM","domain":"app.example.com","url":"https://app.example.com/","tg_bot_username":"my_app_bot"}'Telegram sites carry an extra tg object in the site response (create, list and details):
| Field | Type | Description |
|---|---|---|
bot_id | string | The Bot ID we found. A decimal string — keep it as a string, it can exceed the safe integer range of JavaScript |
bot_username | string | Bot username |
app_short_name | string | null | Mini App short name |
tme_url | string | https://t.me/<bot_username> |
steps | object | Verification state: domain, bio, launch, each verified or pending |
Check that bot_id and bot_username are your bot.
code | message_key | Meaning |
|---|---|---|
400 | error.site.tg_bot_username_invalid | The bot username is not valid |
400 | error.site.tg_short_name_invalid | The Mini App short name is not valid |
400 | error.site.tg_bot_not_found | No bot with this username was found |
400 | error.site.media_type_id_invalid | media_type_id doesn't belong to the site's media type (applies to every media type) |
429 | common.rate_limited | Too many bot lookups; try again later |
503 | error.site.tg_resolve_unavailable | The bot lookup is temporarily unavailable; try again later |
Other site operations
| Method | Path | Description |
|---|---|---|
GET | /sites/{id} | Details |
PUT | /sites/{id} | Update. A changed media_type_id must belong to the site's media type (400 error.site.media_type_id_invalid) |
DELETE | /sites/{id} | Delete |
POST | /sites/{id}/toggle | Enable/pause |
GET | /sites/{id}/stats | Site stats |
GET | /sites/{id}/verify-code | Get the verification codes. For TELEGRAM sites the response also has a tg object: the fields above plus bio_code (the code for the bot description) and launch_links (the links to open once in Telegram) |
POST | /sites/{id}/verify | Verify the site, param method. For TELEGRAM sites see below |
Verifying a Telegram site
A Telegram site is verified in three steps: domain (the same methods as a website), bot description and opening the launch link once in Telegram. Each call to POST /sites/{id}/verify re-checks every step that hasn't passed yet; steps that passed stay passed.
Until all three pass, the call returns 422 with message_key error.site.tg_verify_incomplete and the state of each step in data.steps:
{ "code": 422, "message_key": "error.site.tg_verify_incomplete",
"data": { "steps": { "domain": "verified", "bio": "not_found", "launch": "not_detected" } } }| Step | Values |
|---|---|
domain | verified / pending (the verification code was not found on the domain yet) |
bio | verified / not_found (the code is not in the bot description) / retry (couldn't check right now; try again in a few minutes) |
launch | verified / not_detected (no launch with the code seen yet) / retry (couldn't check right now; try again) |
When all three pass, the call succeeds with verified: true and the steps. Calling it again for a site that is already verified also succeeds with verified: true, but that response may not include steps. This means the site is verified and waiting for our review — audit_status doesn't change (a new site stays PENDING) until the review is done. Verification never approves a Telegram site by itself.
Zones
List
GET /api/publisher/zones
| Param | Type | Required | Description |
|---|---|---|---|
site_id | int | No | Filter by site |
type | string | No | Ad-type filter |
status | string | No | Status |
audit_status | string | No | Review status |
keyword | string | No | Name search |
Create a zone
POST /api/publisher/zones
| Param | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Zone name |
site_id | int | Yes | Parent site; must belong to the current publisher and be approved |
zone_type_id | int | Yes* | Zone-type ID (recommended); the ad type follows from it |
ad_type / type | string | Yes* | Ad type, e.g. BANNER / NATIVE / VIDEO / POPUP / REWARDED, etc. Needed only when zone_type_id is not sent |
size_id | int | No | Size ID |
width | int | No | Width, default 300 |
height | int | No | Height, default 250 |
position | string | No | Position, default CONTENT |
device | string | No | Device, default ALL |
floor_ecpm | number | No | Floor price in eCPM ($ per 1,000 impressions), default 0 |
On success the system auto-generates a unique zone_key (of the form zone_ab12cd34), used for ad requests.
Other zone operations
| Method | Path | Description |
|---|---|---|
GET | /zones/{id} | Details |
PUT | /zones/{id} | Update (site_id immutable) |
DELETE | /zones/{id} | Delete |
POST | /zones/{id}/toggle | Enable/pause |
GET | /zones/{id}/code | Get embed code |
GET | /zones/{id}/preview | Preview |
POST | /zones/{id}/submit-audit | Submit for review |
GET | /zones/{id}/stats | Zone stats |
Telegram Mini App zones
On a TELEGRAM site, send zone_type_id; only these zone types are available: banner, mobile banner, sticky banner, floating banner, mobile floating banner, native feed, mobile interstitial, desktop interstitial, rewarded video and rewarded interstitial. Any other type returns 400 error.zone.type_telegram_unsupported.
For these zones, GET /zones/{id}/code returns one Telegram snippet, each shaped {name, description, code}:
| Key | Zone types | Description |
|---|---|---|
telegram_tag | Banners, floating banners, native feed | Zone tag plus the SDK, placed in the page |
telegram_programmatic | Interstitials, rewarded | Calls window.adbnk.telegram.init().show() from your code. Also has ssv (boolean): true for rewarded zones, which should grant rewards from the server callback |
There is no link, iframe or VAST form for Telegram zones. See Telegram Mini App.
Once you have the zone_key, you can make ad requests — see Ad Request API.
Revenue reporting
| Method | Path | Description |
|---|---|---|
GET | /statistics/explore | Flexible report: choose metrics, dimensions, filters and comparison (what the console's Statistics page uses). Params and export=csv|xlsx work as in the Advertiser API |
GET | /statistics/explore/meta | The metrics and dimensions available to your account |
GET | /statistics/report | Summary report |
GET | /statistics/sites | By site |
GET | /statistics/zones | By zone |
GET | /statistics/region | Geo report |
GET | /statistics/hourly | Hourly report |
GET | /statistics/device | Device report |
GET | /statistics/export | Export |
GET /api/publisher/statistics/report params:
| Param | Type | Required | Description |
|---|---|---|---|
start_date | date | No | Start date, default 7 days ago |
end_date | date | No | End date, default today |
group_by | string | No | Group dimension, default date |
site_id | int | No | Specific site |
Withdrawals
| Method | Path | Description |
|---|---|---|
GET | /withdrawals/balance | Query withdrawable balance |
GET | /withdrawals | Withdrawal record list |
POST | /withdrawals | Initiate a withdrawal |
GET | /withdrawals/transactions | Fund transactions |
GET | /withdrawals/payment-methods | Available payout channels |
GET | /withdrawals/bank-cards | Bank card list |
POST | /withdrawals/bank-cards | Add bank card |
DELETE | /withdrawals/bank-cards/{id} | Delete bank card |
GET | /withdrawals/{id} | Withdrawal details |
POST | /withdrawals/{id}/cancel | Cancel withdrawal |
Initiate a withdrawal
POST /api/publisher/withdrawals
| Param | Type | Required | Description |
|---|---|---|---|
amount | number | Yes | Withdrawal amount, greater than 0 and not below the channel minimum |
payment_method / channel | string | Yes | Payout channel: BANK/USDT (channels currently enabled) |
account_info | string | No | Receiving account info (channel-specific) |
bank_info | object | No | Account details for the bank channel |
KYC hard gate
Withdrawals require the account to complete identity verification (KYC); otherwise the request returns 412.
curl -X POST https://api.adbnk.co/api/publisher/withdrawals \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"amount": 300, "payment_method": "USDT", "account_info": "TRC20:TXxxxx"}'Fees and taxes are computed per platform and channel config; the final arrival amount = withdrawal amount − fee − tax. For settlement and payout rules, see the Settlement & Payouts guide.
TIP
For more publisher features (blacklist, notification binding, referral, etc.), refer to the publisher console.