Documentation
The publisher ad tag
Dependency-free JavaScript, no framework and no third-party requests. It derives its own endpoint from the src attribute it was loaded with.
Installation
One container per slot and one script per page. Order does not matter and the script can sit anywhere in the document.
<div data-beet-placement="plc_xxx"></div>
<script async src="https://edge.beet.media/tag.js"></script>Every element carrying the placement attribute becomes a slot. All the slots on one page are requested together, in the order they appear, so a page with six slots makes one call rather than six.
A token fills at most one element: the tag gives each token its first matching element and stops there. Repeating a token across several elements — to get more than one ad out of one placement — fills the first one and leaves the rest permanently empty. Create a separate placement, and give each its own element, for every slot on the page.
window.beet.refresh();Checking with curl will show no slot. That is the crawler gate working, not a broken install: curl is treated as a bot, and bots are excluded so they cannot request slots they will never fill. Verify in a browser, or with a real browser user agent.
The endpoint is derived, never configured
No host is written anywhere inside the tag, and that is deliberate.
The tag reads the src of the script that loaded it and calls that same origin. If that fails — inside a tag manager, for instance — it looks for the last script whose path ends in the file name. If it cannot find that either, it disables itself and leaves the page untouched.
What it deliberately does not do is fall back to a hardcoded host. A wrong guess would serve from the wrong origin and break exactly the first-party measurement the derivation exists to protect.
What the ad request sends
The complete list. There is no parameter that is not on it.
| Parameter | Type | Required | Meaning |
|---|---|---|---|
| p | string | Yes | Placement tokens separated by commas, in slot order. |
| pr | string | No | The page's own content rating, when the page declares one. It can only make the page count as stronger, never weaker. |
| u | url | Yes | The page URL, without the fragment. |
| t | string | No | The page title. |
| d | string | No | The page's meta description. |
| h | string | No | The page's first three headings, joined. |
| r | url | No | The document referrer. |
| vw | integer | No | Viewport width. |
| vh | integer | No | Viewport height. |
| dpr | number | No | Device pixel ratio. |
| tz | integer | No | The browser's timezone offset, in minutes. |
| l | string | No | The browser language. |
| np | integer | No | Set to 1 when the request must be non-personalised. |
| cmp | integer | No | Set to 1 when a consent platform was present on the page. |
| gdpr | integer | No | Set to 1 when GDPR applies. |
| tcs | string | No | The consent string, if the consent platform supplied one. |
The response
JSON, never cached, one object per slot and in the order they were requested.
{
"slots": [
{
"p": "plc_xxx",
"w": 300,
"h": 250,
"img": "https://cdn.example/creative.png",
"alt": "",
"click": "https://edge.beet.media/c/<token>",
"t": "<impression token>",
"sk": "<per-impression signal subkey, base64url>",
"ac": "br",
"lang": "es",
"why": { "country": "MX", "category": "Arts & Entertainment" },
"report": "https://edge.beet.media/reports?t=<token>"
}
]
}- The explanation field is what backs the "why am I seeing this ad" disclosure a reader can open from the creative itself.
- The report field is a public, session-free link for reporting a specific ad. No account is needed to use it.
- The creative sits in an iframe nested inside ours: the outer frame carries the AdChoices icon and the click layer, and the creative never shares a document with them.
The viewability beacon
This is what produces the billable impression, which is why it is documented here rather than hidden.
POST /b/i
Content-Type: application/x-www-form-urlencoded
t=<impression token>&d=<view_duration_ms>&s=<signed signal blob>It is sent once per token, when the ad has spent at least one continuous second with half its pixels in view in a foreground tab. The server answers 204 and nothing else, always. A repeated token does not count again.