JS Ad SDK
This page covers the JS SDK for websites and H5. For native apps, see Android, iOS or Flutter.
The ADBNK Ad SDK (v3) offers an AdSense-style, minimal integration: place an ad-zone container tag on the page and include one line of SDK script to auto-load ads. The SDK automatically scans zones and loads and displays the right ad for each.
Quick start
Minimal integration takes two steps: place the zone container + include the SDK.
<!-- 1. Place an ad-zone container where you want the ad to show -->
<ins class="adsbyadbnk"
data-zone-id="zone_3887fe9a"
style="display:block;width:300px;height:250px;">
</ins>
<!-- 2. Include the SDK (anywhere; before </body> is typical) -->
<script async src="https://js.adbnk.co/sdk.js"></script>Once included, the SDK automatically:
- Scans all
<ins class="adsbyadbnk">zone elements on the page, including ones inserted later - Loads and displays the right ad for each zone
data-zone-id is the zone ID. Copy it (or the whole snippet) from Get code after creating a zone in the publisher console. The zone_ prefix is optional — zone_3887fe9a and 3887fe9a refer to the same zone.
Telegram Mini App
Running ads inside a Telegram Mini App? See Telegram Mini App — it adds a programmatic API for rewarded and interstitial ads.
Ad-zone container
Supported tag formats
The <ins> tag is recommended; <div> and the data-adbnk-zone attribute are also supported:
<!-- Recommended: ins tag + class -->
<ins class="adsbyadbnk" data-zone-id="zone_xxx" style="display:block;width:300px;height:250px;"></ins>
<!-- Also supported: div tag -->
<div class="adsbyadbnk" data-zone-id="zone_xxx" style="width:300px;height:250px;"></div>
<!-- Also supported: data-adbnk-zone attribute (used by the console's "Async loader" snippet) -->
<ins class="adsbyadbnk" data-adbnk-zone="zone_xxx"></ins>Zone attributes
| Attribute | Required | Description | Example |
|---|---|---|---|
data-zone-id | Yes | Zone ID | zone_3887fe9a |
data-width | No | Ad width (overrides CSS width) | 300 |
data-height | No | Ad height (overrides CSS height) | 250 |
data-responsive | No | Responsive zone: fills the container width, height follows the creative's ratio (the console's responsive snippet includes it) | (no value) |
data-lazy | No | Whether to lazy-load. By default, zones with a size are lazy-loaded and zones without a size load right away | true / false |
data-ad-type | No | Set by the console on formats that are not shown inside the tag (popup, interstitial, floating, push, etc.) so no placeholder box is drawn. Keep it as generated | POPUP |
data-adbnk-nofill | No | keep = when there is no ad, keep the box with an "Advertisement" placeholder instead of collapsing it | keep |
data-reward-user-id / data-reward-custom-data | Rewarded zones | See Rewarded ads |
Set a size on in-page zones
Zones shown inside the page (banner, native, video, etc.) need an explicit width and height (via style or data-width/data-height), or the responsive snippet from the console. They load when they scroll near the viewport.
Formats that decide their own placement (popup, interstitial, floating, push, etc.) use the size-less snippet from the console and load as soon as the page loads, wherever the tag sits.
Rendering and ad types
Ads are returned ready to display; the page doesn't need to handle rendering, and impressions and clicks are reported automatically. The format is determined by the zone type you chose in the console and by the creative; the page doesn't need to distinguish:
| Group | Formats |
|---|---|
| In-page (shown inside the tag, needs a size) | Banner, native, in-page video, rich media (template-based interactive) |
| Out-of-page (placement decided by the format, no size needed) | Popup / popunder, interstitial, floating / anchor bar, push / in-page push, floating video, icon, rewarded |
Common sizes: 300x250 (medium rectangle), 728x90 (leaderboard), 320x50 (mobile banner), 300x600 (half-page), 970x250 (billboard). See Ad Formats for more.
JavaScript API
After loading, the SDK mounts methods on window.adbnk to manually control zones (e.g. SPA route changes, infinite-scroll dynamic insertion).
Manually refresh an ad
// Refresh a specific zone (re-request and render)
window.adbnk.refresh('zone_3887fe9a');If the same zone is placed more than once on a page, refresh(zoneId) applies to the one registered last.
Manually add a zone
Tags matching the formats above are picked up automatically, even when inserted after page load. For any other container, register it with push:
window.adbnk.push({
zoneId: 'zone_3887fe9a',
container: '#ad-container' // element id or CSS selector
// or pass the element directly: element: document.getElementById('ad-container')
});An element that has already been registered is not registered twice.
Re-show a floating ad
// Show a floating zone again after the visitor closed it
window.adbnk.showFloat('zone_3887fe9a');Once a visitor closes a floating ad, the SDK doesn't show it again on its own during that visit; call showFloat only from your own UI (for example a "show ad" button).
Tracking is automatic
Impressions and clicks are reported by the SDK automatically; no manual tracking is needed.
Page targeting info
The SDK reads public information about the current page, such as its URL and title, to match relevant ads. You don't need to pass anything.
Error codes
From SDK 3.3.2, every empty or failed outcome is reported with a stable code. Use code to decide what to do; don't parse message.
| Field | Description |
|---|---|
code | The code name, such as NO_FILL. Use this to decide what to do |
message | A fixed English sentence for each code. It is for logs; don't parse or compare it |
retryable | Whether trying again later is worthwhile |
zoneId, requestId | Set when known. Include requestId when you contact support |
fallbackShown | Only with NO_FILL: true when your own fallback content is being shown in the slot |
Where you receive them
Tag zones: the adbnk:result event. The SDK fires it on the zone's <ins> element (it bubbles) when a zone ends without an ad: no fill, a request that fails, a container that is too small, the display limit you set on the placement, or a visitor closing a rewarded ad before it completes. It does not fire when an ad is shown.
document.addEventListener('adbnk:result', function (e) {
var r = e.detail; // { code, message, retryable, zoneId, requestId?, fallbackShown? }
if (r.code === 'NO_FILL' && !r.fallbackShown) hideMyAdWrapper(e.target);
});Rewarded zones: adbnk:reward_unverified. Its detail (and the argument of window.onAdbnkRewardUnverified) also carries code, message, retryable and, when known, requestId. This is not a reward: see Rewarded ads. The older reason field is kept for compatibility only; branch on code.
Telegram Mini App: errors from window.adbnk.telegram.init(...) carry the same code, message and retryable. See Telegram Mini App, which also describes the deprecated compatibility field e.legacyCode.
All error codes
| Error code | Retryable | Meaning | What to do |
|---|---|---|---|
NO_FILL | Yes | No suitable ad is available at the moment. | Hide the container or show your own content. You may retry later; avoid rapid retries. |
NOT_READY | Yes | The ad is not ready to be shown yet. | Wait for loading to finish before showing; try again once the page is in the foreground. |
LOAD_IN_PROGRESS | Yes | The same ad object is already loading or showing. | Call again after the current operation finishes. |
ALREADY_SHOWN | No | This ad has already been shown. | Load a new ad. |
EXPIRED | No | This ad has expired. | Load a new ad. |
NETWORK_ERROR | Yes | The request did not return successfully. | Check connectivity and retry later. |
TIMEOUT | Yes | The request timed out. | Retry later. |
INVALID_ZONE | No | The zone does not exist, is not enabled, does not match the API being called, or a request parameter is invalid. | Check the Zone Code (not the numeric ID), the zone type and the parameters you pass, for example do not use a banner zone as a rewarded zone and keep custom_data within 500 characters. |
UNSUPPORTED_ENV | No | The current environment cannot show this ad format. | Do not request this ad format in this environment. |
CONTAINER_TOO_SMALL | No | The container is too small for this ad size. | Widen the container and request again, or use a responsive-size zone. |
USER_DISMISSED | No | The user closed or skipped the ad before completion. | Do not grant a reward. Do not show again immediately; wait for the next natural moment. |
REWARD_UNVERIFIED | No | The reward could not be verified. | Do not grant a valuable reward on the client result alone; rely on server-side verification or the server callback. |
FREQUENCY_CAP_REACHED | No | The display limit that you configured for this placement has been reached. | Do not request or show this placement again in the current period; you may tell the user to try later. The limit is changed in the placement settings of the publisher console. |
NOT_ELIGIBLE | No | This request is not eligible for the reward. | Do not grant the reward. |
OBJECT_RELEASED | No | The ad object has been released. | Create a new ad object. |
INTERNAL_ERROR | Yes | An unexpected error occurred. | Retry later. If it persists, contact support with the requestId. |
Reward endpoints
When the SDK's reward request (/ad/reward/token) or your server's check (POST /ad/reward/verify) is rejected, the JSON body has a top-level error_code next to the HTTP error status. It is one of four values from the table above:
error_code | Meaning |
|---|---|
NOT_ELIGIBLE | The reward cannot be granted for this request. |
NOT_READY | Not ready yet. |
INVALID_ZONE | The zone or a request parameter is invalid. On /ad/reward/verify this is also what a missing or malformed parameter returns. |
INTERNAL_ERROR | A server error (HTTP 500). Retry later. |
Any response with an error_code means "do not grant": the SDK reports it as an unconfirmed reward. The message text of these responses is fixed and is for logs only.
Migrating from v2
| Change | v2 | v3 |
|---|---|---|
| Container tag | <div data-adbnk-zone="zone_xxx"> | <ins class="adsbyadbnk" data-zone-id="zone_xxx"> (data-adbnk-zone still works) |
| Script | async.js + ADBNK_CONFIG | sdk.js (async.js and ADBNK_CONFIG are no longer used) |
Upgrading to 3.3
Breaking change (since 3.3.0): unconfirmed rewards no longer call onAdbnkReward. If the SDK cannot get the reward confirmed by our server, it used to call window.onAdbnkReward with { unsigned: true }. It now fires only the adbnk:reward_unverified event (and calls window.onAdbnkRewardUnverified if you define it). adbnk:reward and onAdbnkReward fire only for confirmed rewards.
If your page checked reward.unsigned inside onAdbnkReward, move that handling to adbnk:reward_unverified. Either way, grant rewards of value only from the server-side callback or a server-side check. See Rewarded ads.
Troubleshooting
If an ad doesn't show, check in order:
- Is
data-zone-idcorrect, and is the zone approved and enabled? - Did
sdk.jsload successfully (confirmjs.adbnk.co/sdk.jsreturns 200 in the Network panel)? Ad blockers can block it. - Does an in-page container have a valid width and height?
- Is there simply no ad to fill right now? With no fill the container collapses (takes no space) and the SDK retries later. Add
data-adbnk-nofill="keep"if you'd rather keep the box.
Security note
Ads render in a sandboxed iframe, so ad code can't access the host page's DOM or cookies.