Cookies and headers
The complete list of everything AdPix writes to or reads from your visitor's browser — cookies, local storage keys and one URL parameter — and every header exchanged on the tracker, Tag Gateway and server-side API paths.
Two writers, and one of them is usually silent#
Two things can write a cookie on your visitor's browser.
The tracker, which is the JavaScript inside the page and creates cookies with document.cookie. Its public global is window.ap(), and window.__sov() is another name for the same function.
The collector, which answers with a Set-Cookie header. In the default deployment this writer is completely silent: when an event goes from your domain to the collector's domain, the request is cross-origin as far as the browser is concerned and its cookie would be a third-party cookie — something browsers either drop or partition. So the collector sets no cookie at all on that path, and identity rides on the durable ID in local storage. Only when the traffic is genuinely first-party — Tag Gateway on your own subdomain, or a single-domain deployment — do the server-side cookies come back.
None of these cookies holds an email, a phone number or a name.
Cookies the tracker writes#
| Name | What it holds | Lifetime | Consent category |
|---|---|---|---|
__sov_did |
the anonymous visitor ID; the same value that is in local storage | 365 days | statistics |
__sov_ft |
first touch: source, medium, campaign, content, term, click ID type, landing path, referrer and time | 365 days | marketing |
__sov_lt |
last touch, same structure; updated only when the page URL carries a campaign parameter | 90 days | marketing |
cc_cookie |
the visitor's consent choice: accepted categories, revision number, configuration version, mode, consent ID and time | 182 days (configurable) | necessary |
_svp |
probe cookie for finding the widest writable domain; its value is only 1 |
until the browser closes | technical, no identifier |
_apxcp |
the same probe, from the consent banner bundle | until the browser closes | technical, no identifier |
__sov_test |
only when the tag was started in test mode | until the browser closes | technical, no identifier |
All of these are written with Path=/ and SameSite=Lax, on the widest registrable domain the browser will allow. The tracker finds that domain at startup with the _svp probe cookie, working from a two-part domain outward to a three-part one, because browsers reject public suffixes like .co.uk. The result is that shop.example.com and www.example.com see one ID and one first touch.
_svp and _apxcp hold only the value 1 and are written before any consent choice, because that is precisely their job: discovering which domain a cookie can be set on at all. They contain nothing about the visitor and disappear when the browser closes.
Cookies the collector writes#
| Name | What it holds | Lifetime | Consent category |
|---|---|---|---|
__sov_aid |
the anonymous visitor ID, from the server's point of view | 365 days | statistics |
__sov_ses |
the session ID and last activity time, as <id>|<time> |
30 minutes, rolling | statistics |
Both are written with Path=/ and SameSite=Lax on the domain the collector is configured for. __sov_ses is refreshed on every event; 30 minutes of inactivity means the next session is a new one.
The rule for writing these two is simple:
| Install mode | Server-side cookie written? |
|---|---|
| Direct install against the collector's domain | No — the request is cross-origin, Set-Cookie is suppressed |
| Tag Gateway on your own subdomain | Yes — the request is first-party and carries the X-Site-Key header |
No Origin header (a server-side call) |
Yes |
Invalid or null origin |
No — the envelope fails and no cookie is written |
When no server-side cookie is written, the session is computed from the browser's durable ID and the same 30-minute window, not from a cookie.
The cookie AdPix only reads#
__sov_x is the opt-out cookie. If its value is 1, the tracker sends no events and the collector discards any event that arrives with it — and still returns a 200. AdPix does not create this cookie; you do, for example behind a "do not track me" link in your site's footer. Its lifetime and domain are yours to choose.
Things that are not cookies#
| Key | Where | What it holds |
|---|---|---|
__sov_aid |
local storage | the same anonymous visitor ID; more durable than the cookie and not tied to a domain |
__sov_q |
local storage | the queue of unsent events, at most 200, so nothing is lost if the page closes abruptly |
__sov_em |
local storage | the last healthy stream configuration: enhanced measurement, internal domains, the heatmap block and consent metadata |
_apx |
URL parameter | carries the visitor ID between your own domains, as <id>.<time> |
The _apx parameter is accepted for only 2 minutes after it is created, and its value is validated before use, so nobody can attach an arbitrary ID to a visitor with a tampered link. This transfer sits under the marketing category and does not happen without it.
Without "statistics" consent the tracker writes neither __sov_did nor the local storage key: if an ID is already on the browser it only reads it, otherwise it creates a temporary in-memory ID for that page which is never stored anywhere.
When consent is rejected#
At the moment the choice is recorded, the consent banner itself clears the rejected category's cookies:
- Rejecting "statistics" →
__sov_didand__sov_sesare deleted and the__sov_aidkey is removed from local storage. - Rejecting "marketing" →
__sov_ftand__sov_ltare deleted.
After that the tracker's own gates stay closed and none of them are recreated. A __sov_aid cookie written by the collector is not part of this cleanup, but since no event is sent from that moment on, the collector never refreshes it and it expires on its own. What each category means is in Consent categories, and the publishable declaration is generated under Cookie consent → Cookie declaration.
Request headers#
| Header | Who sends it | What for |
|---|---|---|
Content-Type: text/plain;charset=UTF-8 |
the tracker | it is on the CORS safelist, so the beacon triggers no preflight |
Origin |
the browser | the collector uses it to decide whether to set a cookie |
X-Site-Key |
the Tag Gateway proxy | marks the traffic as first-party and coming from your proxy |
X-Site-Token |
the Tag Gateway proxy | the proxy token; missing or invalid means a 403 |
Ar-Real-Ip |
the fronting CDN | the visitor's real address behind the CDN |
X-Real-IP |
the edge proxy | the visitor's real address |
X-Forwarded-For |
any intermediate proxy | the full chain of intermediaries |
Authorization: Bearer sk_… |
your own server | the server key for the server-side API |
X-Sov-Site |
your own server | the ID of the property the key belongs to |
X-Sov-Timestamp |
your own server | Unix seconds; more than 5 minutes from the server clock is rejected |
X-Sov-Signature |
your own server | v1=<hex> — the HMAC-SHA256 signature over <timestamp>.<body> |
The visitor's IP address is resolved in this order: Ar-Real-Ip first, then X-Real-IP, then the first public address inside X-Forwarded-For — private addresses are skipped so a proxy's internal address is not recorded instead of the visitor's — and finally the connection's own address.
The browser's beacon request carries only Content-Type and no X- header at all. The X-Site-* headers are added by the Tag Gateway proxy and the X-Sov-* headers by your server-side code. Adding a header on the browser path turns the request from a simple beacon into a preflighted one, and it is lost when the page is closing.
Response headers#
The collector returns these on every path:
| Header | Value |
|---|---|
Access-Control-Allow-Origin |
the request's own Origin, or * when no origin was sent |
Vary |
Origin |
Access-Control-Allow-Headers |
Content-Type, Authorization |
Access-Control-Allow-Methods |
POST, GET, OPTIONS |
An OPTIONS request is answered with 204. The Access-Control-Allow-Credentials header is deliberately not sent: when the origin is reflected, granting credentials to any origin is a full vulnerability. Its practical consequence is exactly what was said above — no cookie is exchanged at all on the cross-origin path, and the durable ID does all the work.
Two cache values are worth noting: the tracker files are cached for five minutes, but the stream configuration for only one — because the consent block arrives in that same response, and a change to it has to reach live visitors within about a minute, not five.
The console cookie#
ap_admin is the AdPix console's own session cookie. It is written on the console's domain, is HttpOnly and Secure, uses SameSite=Lax, and lasts 12 hours for a local sign-in. This cookie is never written on your site visitors' browsers and has nothing to do with your site's cookie declaration; it exists only when you sign in to the console yourself.
Frequently asked questions#
In a standard install, does AdPix set server-side cookies too?
No. In a direct install, events go from your domain to the collector's domain, and the collector sets no cookie on that path. The __sov_aid and __sov_ses cookies are written only when the traffic is first-party — that is, Tag Gateway on your own subdomain, or a single-domain deployment.
Are AdPix cookies third-party?
No. Every cookie is written on your own site's registrable domain, so they are first-party and third-party cookie blockers do not remove them. Identity across domains is not built from a shared cookie either; the server-side identity graph does that.
Why is the visitor ID in both a cookie and local storage?
Because neither survives everywhere on its own. The cookie is shared across subdomains; local storage survives when cookies are cleared or capped. The tracker keeps both with the same value and reads from whichever is present.
If a visitor rejects the "statistics" category, what gets cleared?
At that moment the consent banner deletes the visitor ID cookie and the session cookie, and removes the ID key from local storage. Rejecting "marketing" deletes the two attribution cookies. After that the tracker's own gates stay closed, so none of them are recreated.
Thanks — your feedback helps us improve the docs.