Agents: markdown or /docs.json. This page is the same text.

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:

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.

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.