Skip to documentation content

Authentication

Create and use CookieBeam API keys, choose scopes, and understand live vs test keys.

The public API authenticates requests with API keys. API access requires a plan that includes the API feature; on a plan without it, a valid key is rejected with a plan_required error (HTTP 403).

Create a key

Team owners create, rotate and revoke keys in the dashboard under Settings > API keys. Each key has a name, an environment, a list of scopes, and an expiry. Keys always expire: the default is 90 days for live keys and 30 days for test keys, and you can choose any lifetime from 1 to 365 days. A team can have at most 20 active keys.

The full key is displayed exactly once at creation. CookieBeam stores only a SHA-256 hash of the key's validator segment, so a lost key cannot be recovered — revoke it and create a new one.

Key format

Keys are prefixed by environment followed by 64 lowercase hexadecimal characters:

cb_live_<64 hex chars>
cb_test_<64 hex chars>

A key that does not match this format, or whose prefix does not match the environment it was created in, is rejected as invalid_key.

Send the key

Send the key as a bearer token in the Authorization header:

Authorization: Bearer cb_live_your_key_here

Keys are team-level principals. A key acts as the team, not as the member who created it, and per-member banner access lists do not restrict key-authenticated requests. Treat keys with the same care as team administrator credentials.

Live vs test keys

Test keys are read-only. Any endpoint that requires a scope ending in :write or :publish rejects a test key with HTTP 403 and the error code test_key_read_only. Use test keys to explore read endpoints without touching production data, and live keys for mutations.

Scopes

Each key carries an explicit allow-list of scopes. An endpoint declares the scopes it requires; if the key is missing one, the request fails with HTTP 403 and the error code missing_scope, with the missing scopes named in the message.

Scopes are grouped by resource. Active scopes are required by at least one endpoint or MCP tool. Reserved scopes are part of the scope vocabulary but no endpoint uses them yet.

ScopeStatusGrants
banners:readActiveList and read banners and their embed code (GET /api/v1/banners, MCP banner tools)
banners:writeActiveCreate banners (POST /api/v1/banners)
banners:publishReservedPublish banner configurations
consent:readActiveResolve cross-device consent subjects
consent:writeActiveLog consent and write or delete cross-device consent state
consent:exportReservedExport consent records
scanner:readActiveRead scans, scan results and the discovery inventory (MCP tools)
scanner:writeReservedStart and manage scans
analytics:readActiveRead consent analytics (MCP tool)
team:readReservedRead team members
team:writeReservedManage team members
webhooks:readReservedRead webhook configuration
webhooks:writeReservedManage webhook configuration
audit:readReservedRead the audit log

Rules when you create or rotate a key:

  • New keys can only request active scopes. Requesting a reserved scope is rejected (BAD_REQUEST) and the message names the reserved scopes. When an endpoint ships for a reserved scope, the scope becomes active.
  • Existing keys keep their scopes. A key that already holds a reserved scope keeps authenticating, and rotating it copies its scopes unchanged.
  • A key cannot exceed its issuer. Every scope maps to a set of dashboard permissions; you can only grant a scope whose permissions you hold yourself. This is checked on create and on rotate (FORBIDDEN otherwise), and the dashboard disables scopes you cannot grant.

Grant only the scopes an integration actually uses. A reporting job needs banners:read and nothing else; keep write scopes off keys that ship to CI or shared environments.

A key can optionally be limited to specific banners and to specific banner environments (for example production or staging). Leave both empty and the key covers every banner and environment of the team, which is how all keys created before restrictions existed behave.

  • Banners. A banner outside the key's list behaves exactly like a banner of another team: single-banner requests return HTTP 404 not_found (MCP tools report Banner not found), and lists such as GET /api/v1/banners and the MCP list_banners and list_scans tools only include the allowed banners. A banner-restricted key cannot create banners (HTTP 403, code key_restricted), because the new banner would sit outside its own list.
  • Form consent proofs. A banner-restricted key only sees form consent proofs recorded for its banners; proofs recorded without a banner are hidden from it. It must pass a bannerId from its list when it records a proof, and it cannot erase a person's proofs, because erasure covers every banner of the team (both HTTP 403, code key_restricted).
  • Environments. Environment-specific results, such as the per-environment script URLs from the MCP get_embed_code tool, only include the allowed environments. The install snippet, which serves the production environment, is only returned when production is allowed.
  • Who can set them. You can only restrict a key to banners you can access yourself; every banner must belong to your team and every environment must exist on one of the selected banners. Restrictions can be changed on an existing key from the dashboard without re-issuing it, and rotating a key keeps them.

Authentication errors

All authentication errors use the standard error envelope.

HTTP statusCodeCause
401invalid_keyThe key is malformed, unknown, or its prefix does not match its environment
401revoked_keyThe key has been revoked
401expired_keyThe key has passed its expiry date
401unauthorizedThe endpoint requires an API key and none was sent
403plan_requiredThe team's plan does not include API access
403missing_scopeThe key lacks a scope the endpoint requires
403test_key_read_onlyA test key was used for a write or publish operation
403key_restrictedA key restricted to specific banners was used to create a banner, to record a form consent proof without one of its banners, or to erase form consent proofs

Failed authentication attempts are limited to 10 per minute per client IP. Past that budget, further attempts return HTTP 429 with the code rate_limited and a Retry-After header, even if the credentials are wrong. This slows down key guessing; if you see it during legitimate troubleshooting, wait for the window to pass.