API keys
pk_, sk_, rk_, ak_ — when to use which.
All API access uses Bearer tokens. We ship four kinds, modelled after Stripe's pk_/sk_ split so the right ones can safely live in a browser.
pk_live_…
pk_live_f6589a94_7xPq…
Browsers, public pages, snippets
Ingest only. Origin-allowlisted — requests must come from an origin in your project's allowed_origins. Rejected at /mcp — MCP never accepts a key that ships in browser source.
sk_live_…
sk_live_a1b2c3d4_secret…
Servers, cron jobs, MCP write access
Ingest + read. No origin check.
rk_live_…
rk_live_99887766_secret…
Server-side dashboards, MCP clients (recommended)
Read only — query, stats, sources, MCP read tools. Cannot ingest.
ak_live_…
ak_live_1c4d8a90_secret…
Account-level MCP — agencies, multi-product teams
Read every project this account owns through one credential. Business tier only. Used by /mcp/account. Cannot ingest.
What's in a key
{kind}_{env}_{prefix}_{secret}
└──┬──┘ └─┬┘ └──┬───┘ └──┬───┘
pk/sk/rk live 8-char url-safe
lookup secretThe prefix (
pk_live_f6589a94) is the lookup key. It's safe to display in dashboards and logs.The secret is shown to you exactly once at mint time. Only
sha256(secret || pepper)is stored — we cannot recover or re-display it. If you lose it, revoke and mint a new one.
Origin allowlist for pk_* keys
Every project has a list of allowed_origins. pk_* requests must carry an Origin: header that matches one of them, or they're rejected with 403 origin_not_allowed.
POST /v1/track HTTP/1.1
Authorization: Bearer pk_live_…
Origin: https://yoursite.com ← must be in the project's allowed_originsIf you serve from https://yoursite.com and https://www.yoursite.com, list both.
sk_* and rk_* keys ignore Origin because they're never meant to be in a browser.
Minting and revoking
In the dashboard (apps/web):
Open the project.
Click
+ pk/+ sk/+ rk, give it a label.The secret appears in a modal once — copy it.
To revoke, click Revoke on the key row. It cannot be undone; existing clients will immediately get
401 invalid_api_key.
Scopes vs kinds
pk
ingest
Browser-safe. Only ingest endpoints. Never accepted by /mcp.
sk
ingest
Same powers as pk but no origin check. Required for /v1/forget. Accepted by /mcp.
rk
read
Read endpoints + MCP read tools. Accepted by /mcp (recommended for AI agents).
ak
read
Account-scoped. Accepted only by /mcp/account. Sees every project the account owns. Business tier.
If you call a read endpoint with an ingest-scope key (or vice versa) you'll get 403 insufficient_scope. If you hit /mcp with a pk_ or ak_ key you'll get 403 key_kind_not_allowed. If you hit /mcp/account with anything other than ak_, you'll get 403 account_key_required.
When to use an ak_ key
Use one if you own more than one Millimetric project and you'd otherwise mint and rotate an rk_ key per project for the same agent. Examples:
A consultancy / agency running analytics for many clients.
A multi-product company with one project per app.
Staging + production isolated as separate projects.
You configure your MCP client once, against /mcp/account, and the agent can call list_projects, query a single project by project_id / project_slug, or run cross-project tools like compare_projects in one round trip. See MCP overview.
Operational notes
Rotation: revoke + re-mint. Re-issuing all keys requires changing the server pepper, which is a deliberate, planned event.
Last-used timestamp: each successful auth updates
last_used_aton the key. Stale keys are easy to spot.Caching: the Worker caches verified keys for 5 minutes per instance. Revocation takes effect within that window.
Last updated
Was this helpful?