The header
Every authenticated request carries your key in theX-API-Key header.
Key tiers and prefixes
Each key carries a prefix that hints at its tier. The prefix is cosmetic; the real tier is stored server-side and returned byGET /v1/me.
| Prefix | Tier | Typical source |
|---|---|---|
exd_trial_ | Watch | POST /v1/keys/trial |
exd_watch_ | Watch | Paid Watch subscription |
exd_see_ | See | Paid See subscription |
exd_know_ | Know | Paid Know subscription |
exd_test_ | Test | Internal QA (not issued to customers) |
Minting a trial key
Public endpoint, IP-rate-limited, idempotent per email within the key’s active window.reused: true and HTTP 200. No duplicate keys, no silent issuance.
Inspecting the current key
reused. Use this to check your tier, expiry, and topic scope from a client at runtime.
Rotating a key
Rotation issues a new key with the same tier, topics, limits, and expiry. The old key is deactivated atomically — switch your clients to the new key immediately.Revoking a key
Permanent. Idempotent.401 invalid_api_key.
Who am I
GET /v1/me returns the caller’s identity and full entitlements — tier, topic scope, rate limit, quotas, and usage. Ideal for building tier-aware UIs.
Authentication errors
All auth errors use the standard typed envelope. See Errors for the full list. The four you’ll actually see:| Status | Code | When |
|---|---|---|
| 401 | missing_api_key | Header not sent |
| 401 | invalid_api_key | Unknown, rotated, or revoked key |
| 403 | key_expired | Key past expires_at |
| 403 | topic_denied | Key valid but not scoped to the requested topic |
Operational guidance
- Store keys server-side only. Never in a public SPA bundle, git, or a client-side env var shipped to users.
- Rotate on suspicion of leak. Rotation is free and atomic.
- Use
/v1/meat startup to detect tier changes (upgrades, downgrades, expiries) without polling the billing system. - Handle 401 as “get a new key” and 403 as “ask the user to upgrade or change topic” — the codes are distinct for a reason.