Domain Validation

How impression pixels are matched to their registered placement domain, and what server-side integrators must set.

Why we check it

Every placement is tied to a registered domain. When the impression pixel fires, we check the request's Referer header against that domain. The check exists for two reasons: it stops localhost traffic from being billed as real impressions, and it makes it harder for an unrelated site to siphon paid impressions through someone else's placement ID.

The rule

We compare the hostname of the request's Referer against the placement's registered domain. The match is permissive in two ways:

  • A leading www. on either side is stripped before comparison.
  • Subdomains of the registered domain are accepted. Registering myblog.com accepts impressions from news.myblog.com, blog.myblog.com, etc.

Test origins are always rejected

These origins can never serve a real production impression. Pixel calls from any of them are silently dropped (the pixel still returns a 1x1 GIF, but no row is recorded and no campaign is billed):

localhost
127.0.0.0/8       (any 127.x.x.x address)
0.0.0.0
::1               (IPv6 localhost)
*.local           (mDNS / Bonjour)
*.localhost
*.test            (RFC 6761 reserved)
*.invalid
*.example
example.com, example.org, example.net   (RFC 2606 reserved)
file:// URLs

If your local development domain falls in this list, your impressions will not record. Use ?test=1 on the serve endpoint while developing (returns ads with impression_url: null, so nothing is recorded), then deploy to a real domain to verify end-to-end.

Browser-side: nothing to do

When you fire the impression pixel from a browser (image tag, fetch(), or the script integration), the browser sets the Referer header automatically. As long as the page is on your registered domain, the check passes.

Server-side: set the Referer header

When you fire the pixel from a backend (Node, Python, PHP, Go, etc.), the runtime does not set Referer for you. You must set it explicitly to the URL of the page where the ad was rendered.

// Node (built-in fetch / undici)
await fetch(ad.impression_url, {
  headers: { Referer: pageUrl },
});
# Python (requests)
import requests
requests.get(ad["impression_url"], headers={"Referer": page_url})
// PHP (curl)
$ch = curl_init($ad['impression_url']);
curl_setopt($ch, CURLOPT_REFERER, $page_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);
curl_close($ch);

Enforcement

Today (soft launch): test origins are hard-rejected. Domain mismatches are warn-logged but the impression is still recorded. Future release: domain mismatches become hard-rejected too. If you integrate server-side, set the Referer header now to be future-proof.

Common failure modes

  • Local dev on a .test or .local TLD: silent zero impressions, looks broken with no error. Use ?test=1 during dev or run on the registered domain.
  • Server-side fire missing the header: warn-logged today, blocked after the cutover. Set the Referer on every pixel call.
  • Subdomain not registered: subdomains of the registered apex are accepted automatically. If you need to support news.myblog.com, registering myblog.com covers it.

See also