Authentication & limits

API keys, SDK keys, session cookies, HMAC ingest signatures, rate limits and the error format.

Updated 2026-09-02

Credentials#

CredentialFormatUsed byHow to send
API keywc_live_ + 32 charsREST API (/api/v1/*, /postback), MCP server, edge warm-upAuthorization: Bearer wc_live_… or ?api_key= (postback URLs only)
SDK keysk_… per appMobile / web / CTV SDK endpoints (/api/sdk/v1/*)X-SDK-Key: sk_… header (or ?sdk_key=)
Sessionwc_session JWT cookieDashboard and /api/dashboard/*, /api/protect/export, /api/protect/syncBrowser only
Ingest signaturehex HMAC-SHA256 of the raw bodyPOST /api/ingest/clicks (edge worker)X-WC-Signature header, secret EDGE_INGEST_SECRET

API keys are hashed with SHA-256 at rest; only the prefix is stored in clear. Revoked keys fail immediately. Every key belongs to exactly one organization; there are no cross-organization reads.

Tip

Create one key per integration (for example google-ads-offline-import, claude-mcp) so you can revoke them independently. The audit log records which key performed each write.

Rate limits#

Limits are applied per client IP (IPv6 aggregated at /64) per minute at the Next.js proxy, and additionally per key in Redis and at the Cloudflare edge when deployed.

PathLimit / minute
/api/sdk/*600
/api/protect/beacon600
/api/v1/*300
/postback300
/api/mcp240
/api/skan/*120
/login, /register20

A limited request returns 429 with a Retry-After header and body {"error":"rate_limited","retry_after":<seconds>}. Redirect endpoints (/c, /l, /i) are not rate limited here; the edge worker applies burst protection there.

Error format#

Validation and auth errors are JSON:

401
{ "error": "unauthorized" }
400 (Zod flatten())
{ "error": { "formErrors": [], "fieldErrors": { "value": ["Too small: expected number to be >=0"] } } }

See Errors & idempotency for the full status-code table.

CORS#

SDK endpoints and the beacon answer OPTIONS with Access-Control-Allow-Origin: * so web and React Native apps can call them directly. The REST API is server-to-server; do not embed API keys in browsers.

Security headers#

Every response carries X-Content-Type-Options: nosniff, X-Frame-Options: DENY and Referrer-Policy: strict-origin-when-cross-origin. Redirect responses add Cache-Control: no-store.