Consent
Turn on the permission popup so identification runs only after the visitor accepts "identify this visit" (resolution) on the current policy.
You need an active account's API key and a canonical pixel_id. Header: Authorization: Bearer <api_key> and content-type: application/json.
1. Publish the policy
POST /v1/pixels/{pixel_id}/consent
{
"controller_name": "Ada Studio",
"controller_type": "company",
"controller_contact": "privacy@example.com",
"controller_jurisdiction": "United States",
"data_sharing": false,
"contact_channels": ["email"],
"purposes": ["analytics", "resolution"],
"disclosed_parties": [],
"site_policy_url": "https://example.com/privacy"
}
controller_name is required. purposes needs at least one of: analytics, resolution, newsletter, email_sharing, phone_sharing, partner_email, partner_calls, partner_sms. controller_type is company, person, or organization. site_policy_url is optional and must be https. With it, the popup shows two links (the site's privacy policy and our identification notice). Without it, the hosted page is the whole policy.
Agents on MCP use the configure_consent tool. It takes the same fields.
200 returns policy_version, policy_hash, policy_url, snippet, and purposes. Paste snippet. It loads /px/{pixel_id}.js. Do not also paste the immediate pixel snippet from setup. The popup loads identification only after an acceptance of resolution whose policy hash is still current.
Saving identical text keeps the version. A text change increments policy_version and replaces policy_hash. Older acceptances then fail the check with policy_version_stale until the visitor accepts again.
The public notice is GET /v1/policy/{pixel_id} (same page as GET /api/v1/policy/{pixel_id}). /px/{pixel_id}.js and the policy URL also accept a script alias. The stored id and the receipt use the canonical pixel id. Account routes such as GET /v1/pixels/{pixel_id} do not accept an alias.
2. What the browser sends
The popup POSTs /v1/consent/record (same handler as POST /api/v1/pixel/fire). You do not need to call it for a normal install. The contract, if you record a choice yourself:
- 202 with
receipt,signature, andsignature_alghmac-sha256when the choice is stored. - 403
{"recorded": false, "reason": "site_mismatch", "domain": "<pixel domain>"}when the page host is a different site. - 204 with an empty body when the call is ignored: bad JSON, Global Privacy Control, a missing id, consent turned off, an accept that is not affirmative, a stale
policy_version_hash, or a purpose that was not configured.
An acceptance must send affirmative true, policy_version_hash equal to the current hash, and purposes that are a non-empty subset of the configured list. The page url host must be the pixel's domain or a subdomain.
3. Ask if a visitor is allowed
GET /v1/consent/check?pixel_id={pixel_id}&visitor_id={visitor_id}&required_purpose=resolution
200 returns permitted and reason.
ok:permittedis true. The latest row accepts the current policy and includesrequired_purposewhen you sent one.no_consent_record: nothing stored. No receipt in the body.consent_off: the pixel no longer has consent enabled.declined_or_withdrawn: the latest choice is not an acceptance.policy_version_stale: the acceptance is for an older policy hash.purpose_not_granted: the acceptance does not includerequired_purpose.
required_purpose must be one of the purpose names or the call is 400 invalid required_purpose. The check and the receipt accept a script alias and answer for the canonical pixel. An unknown id on the check is no_consent_record.
GET /v1/consent/receipt?pixel_id={pixel_id}&visitor_id={visitor_id} returns the latest receipt plus valid true, or 404 no consent record. The alias path is GET /api/v1/consent/receipt.
4. Verify a signature
POST /v1/consent/verify
{"receipt": {"pixel_id": "...", "receipt_id": 1, "visitor_id": "...", "origin": "example.com", "consent_state": "accepted", "policy_hash": "...", "purposes": ["resolution"], "recorded_at": "..."}, "signature": "..."}
200 is {"valid": true} or {"valid": false}. Send the receipt object you were given. Do not recompute the signature. The signing secret is not published.
5. Read the log
GET /v1/pixels/{pixel_id}/consent with the API key. Optional state is accepted, declined, or withdrawn. 200 returns events, newest first, at most 200. Each event includes receipt and signature. The HTML page at /log calls this route.