Authentication & scopes
- Written for
- + Written for
- Deprecated
- + Deprecated
- Applies to
- + Applies to
Authentication & scopes
Every request to the Developer API (https://api.cookiemunch.net/v1/*) is authenticated with an API key. There is no separate "organization id" parameter anywhere on this surface — the org is derived from the key itself, so a key can never be pointed at the wrong org, accidentally or otherwise.
Getting a key
Issue a key from Settings → API keys in the dashboard, or via the API itself once you have one full-access key to bootstrap with:
curl -X POST https://api.cookiemunch.net/v1/keys \
-H "Authorization: Bearer fck_existingkey…"{
"key": "fck_8f2a91c0b3d4e5f6...",
"prefix": "fck_8f2a91c0"
}Note: The full key (
key) is returned exactly once, at creation. Store it immediately — the server only ever persists a hash.GET /v1/keyslater shows you theprefixfor identification, never the secret.
Sending the key
Two equivalent forms are accepted on every request:
# Bearer token (recommended)
curl https://api.cookiemunch.net/v1/me \
-H "Authorization: Bearer fck_…"
# ...or the X-API-Key header
curl https://api.cookiemunch.net/v1/me \
-H "X-API-Key: fck_…"{ "orgId": "org_9k2m", "plan": "pro", "keyPrefix": "fck_8f2a91c0" }GET /v1/me is a cheap, no-scope-required identity check — useful for verifying a key works before wiring up real calls.
Scopes
Keys can be issued unscoped (full access to everything below) or scoped to a specific allow-list of resource:action pairs. Scoping follows least-privilege: a CI job that only needs to read consent stats should hold a consent:read-only key, not a full-access one.
Scope | Grants |
|---|---|
| List/get sites, read config, read cookies/scan-status/A/B results, get the install snippet, list/create brand kits, read a signed receipt, and export a subject's records (read/write respectively). |
| Consent log, stats, and CSV export (read); preference-center records (read via |
| List DSARs (read); create and advance DSARs (write). |
| List vendors (read); create a vendor (write). |
| List RoPA entries (read); create a RoPA entry (write). |
| List/get account-level banner library entries (read); create/update/delete banner library entries (write). |
curl -X POST https://api.cookiemunch.net/v1/keys \
-H "Authorization: Bearer fck_fullaccesskey…" \
-H "Content-Type: application/json" \
-d '{ "name": "nightly-export-job", "scopes": ["consent:read"] }'A request whose key lacks the required scope gets a 403:
{ "error": "insufficient_scope", "message": "missing required scope: consent:write" }Note:
GET /v1/meandGET /v1/usageneed no scope — every key, scoped or not, can call them. Everything else on/v1/members,/v1/keys, and/v1/webhooks— the org-admin surfaces — requires an unscoped (legacy full-access) key; there is nomembers/keys/webhooksscope to grant, by design. The account-level banner library (/v1/banners/*) has its ownbanners:read/banners:writescope, so a narrowly-scoped automation key can reach it without also grantingsitesaccess.
CORS and public routes
/v1/* responses always include permissive CORS headers (Access-Control-Allow-Origin: *), since these are server-to-server credentials, not cookie-based — there's no session to leak cross-origin. The one unauthenticated route on this surface is GET /v1/openapi.json, which serves the machine-readable OpenAPI 3.1 document for this API (useful for generating your own client, or feeding an API explorer).
curl https://api.cookiemunch.net/v1/openapi.jsonNext: conventions & errors for the request/response shape every endpoint shares, or jump straight to sites.