Supply-side platform API for programmatic advertising platforms
https://polads.eu/api/v1GET /online-advertisement/{PAID}
10,000 requests per minute
Rate limit enforced per SSP token
PUT /online-advertisement/{PAID}/metrics
1,000 requests per minute
Counted per SSP token, separately from the label endpoint, so reporting metrics never uses up your label requests
/online-advertisement/{PAID}📊 Compact Label Format
This endpoint returns a compact, EU-compliant transparency label suitable for display alongside online advertisements. Only works for advertisements with medium = "online".
Example Request
curl -X GET "https://polads.eu/api/v1/online-advertisement/ABC12" \
-H "Authorization: Bearer YOUR_SSP_TOKEN" \
-H "Accept: application/json"Response Example
{
"text": "Politisk Reklame - ACME Corp - Folketingsvalg - polads.eu/ABC12",
"link": "https://polads.eu/ABC12",
"PAID": "ABC12"
}Response Fields
Usage Example
Display the label on your platform:
<a href="[link]" target="_blank" rel="noopener">
[text]
</a>/online-advertisement/{PAID}/metricsYour SSP token needs the metrics:write permission. An administrator switches it on for the token you already use, so no new token is issued.
Send the running totals since the notice was published, never the change since your last delivery. Each delivery replaces the figures before it, so sending the same totals again changes nothing.
You can report any published notice, whichever publisher it belongs to. The figures appear on its public transparency notice with the date they were last reported.
Example Request
curl -X PUT "https://polads.eu/api/v1/online-advertisement/ABC12/metrics" \
-H "Authorization: Bearer YOUR_SSP_TOKEN" \
-H "Content-Type: application/json" \
-d '{"viewsCount": 15000, "engagementsCount": 320}'Request Fields
Both fields are required, each a whole number from 0 to 2147483647.
Response Example
{
"viewsCount": 15000,
"engagementsCount": 320,
"engagementMetricsUpdatedAt": "2026-10-12T08:30:00.000Z"
}Error responses from this endpoint
401 INVALID_TOKEN
The Authorization header is missing, or the token is unknown, revoked or a partner token. Both cases carry the INVALID_TOKEN code.
{
"error": "Missing or invalid Authorization header. Expected: Bearer <token>",
"code": "INVALID_TOKEN"
}{
"error": "Invalid or revoked SSP API token.",
"code": "INVALID_TOKEN"
}403 INSUFFICIENT_SCOPE
The token is valid but has not been given the metrics:write permission. Ask your administrator to switch it on.
{
"error": "This token is not authorised to write metrics. Required scope: metrics:write.",
"code": "INSUFFICIENT_SCOPE"
}404 NOT_FOUND
No published notice matches that PA-ID. As on the label endpoint, a notice that its publisher has not yet signed off, or whose publication start date is still in the future, also returns 404.
{
"error": "Advertisement not found",
"code": "NOT_FOUND"
}409 METRICS_NOT_APPLICABLE
The notice is outside the scope engagement metrics are defined for. Annex II note 15 covers an online or native notice that used targeting or ad-delivery techniques and has started running. Nothing is written.
{
"error": "Engagement metrics do not apply to this notice",
"code": "METRICS_NOT_APPLICABLE"
}400 INVALID_METRICS
The request body is not valid JSON, or the two counts are missing, negative or not whole numbers. The response lists what failed.
{
"error": "Invalid engagement metrics",
"code": "INVALID_METRICS",
"issues": [
{
"path": "viewsCount",
"message": "Too small: expected number to be >=0"
}
]
}{
"error": "Invalid request body",
"code": "INVALID_METRICS"
}429 RATE_LIMITED
The per-token limit was exceeded. The response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset.
{
"error": "Rate limit exceeded",
"code": "RATE_LIMITED",
"limit": 1000,
"remaining": 0,
"reset": "2026-05-14T15:14:00.000Z"
}Header Format
Authorization: Bearer YOUR_SSP_TOKENToken Format
64-character hexadecimal string (256-bit entropy)
Token Management
SSP tokens are managed by system administrators only. Contact your administrator to obtain a token.
No subscription plan applies
An SSP token is issued to an integrator rather than to a publisher, so it carries no publisher account and there is no plan to check. Unlike the partner API, nothing here depends on a subscription. A partner token is rejected on this endpoint with 401, and an SSP token is rejected on the partner endpoints the same way.
When the endpoint returns 404
The notice is resolved through the same visibility rule as the public register. A notice that is not yet confirmed, that its publisher has not yet signed off, or whose publication start date is still in the future returns 404. A 404 is therefore not proof that a PA-ID is wrong.
The endpoint above returns the one-line label TEXT, for a label your own platform draws. The badge returns a rendered, interactive notice you place beside the advertisement as an iframe. Both describe the same transparency notice.
One URL per version
The demo's controls map onto these parameters one to one, so you can choose on the demo page and copy the URL you see.
# Corner badge, mark only
GET https://polads.eu/badge/{PA-ID}
# Corner badge showing its wording
GET https://polads.eu/badge/{PA-ID}?variant=labelled
# Always-visible label strip
GET https://polads.eu/badge/{PA-ID}?layout=labelWhat each parameter does, and what leaving it out means
layout=label selects the strip. Leave it out for the corner badge. variant=labelled makes the closed badge show its wording. Leave it out for the mark alone. w and h declare the slot the badge sits in and choose how it degrades in a tight space. Leave them out and the badge assumes it has room, which is right for the standard formats.
hover=0 is for the demo, not for your page
It forces the no-hover layout so the demo can show the touch version on a desktop browser. The real badge tests the device for itself. Pin it and you send the wrong version to every visitor whose device disagrees.
The resize listener is required
The corner badge loads at 32 by 32 so it covers as little of the creative as it can, then asks the host page for room when it opens. Without the listener it cannot open at all. The label strip degrades more gently, and only clips at narrow widths.
Available only for a published notice
The badge is served once the notice is confirmed, signed off by the publisher and past its publication start date. An embargoed or unsigned PA-ID answers 404 by design, not by fault.
401 Unauthorized
{
"error": "Invalid or revoked SSP API token."
}{
"error": "Missing or invalid Authorization header. Expected: Bearer <token>"
}400 Bad Request
The notice was found, but its medium is not online. The response returns the actual medium value, for example print. A missing or unknown PA-ID returns 404 instead.
{
"error": "This endpoint is only for online advertisements",
"medium": "print"
}404 Not Found
{
"error": "Advertisement not found"
}429 Rate Limit Exceeded
{
"error": "Rate limit exceeded",
"limit": 10000,
"remaining": 0,
"reset": "2026-05-14T15:14:00.000Z"
}This is API version v1, and every response says so in an X-API-Version header. Breaking changes ship under a new path rather than changing this one. A v1 endpoint will not be switched off without a Deprecation header at least 90 days beforehand, following RFC 8594.
Machine-readable specification
The full OpenAPI 3.1 document is served at /api/docs. Point Postman, Swagger UI or a client generator straight at it rather than transcribing this page.
https://polads.eu/api/docs