API · Auth
Tokens & API keys
Secret keys, publishable keys, and scoped agent tokens — the three credential families and their resource shapes.
Last updated
TL;DR
Matter has three credential families: account secret keys (sk_live_… /
sk_test_…), client-side publishable keys (pk_live_… / pk_test_…), and
scoped agent tokens (tok_…). Account keys come from the dashboard;
agent tokens are minted by the API. Every credential pins an api_version at
creation. Plaintext is shown once — Matter does not store it. Test-mode
and live-mode credentials sign receipts under separate cryptographic roots and
cannot be cross-replayed.
After reading this page you'll know which credential to use for which surface, how to mint and rotate an agent token, and where to find the structured scope-policy DSL (which lives on its own page because it has its own surface area).
Credential families
| Credential | Prefix | Surface | Provisioned by |
|---|---|---|---|
| Secret key | sk_live_ / sk_test_ | Server-side, full account access. The root credential; can mint tokens of any tier. | Dashboard. |
| Publishable key | pk_live_ / pk_test_ | Client-side, read-only on a CORS-whitelisted subset (e.g. GET /v1/entities/{id} for a public investor portal). | Dashboard. |
| Scoped token | tok_ | Agent identity with a structured scope policy and a tier (1–4). The unit of authority for autonomous agents. | POST /v1/tokens. |
Test-mode credentials (sk_test_, pk_test_, and any tok_ minted under a
test key) operate against an isolated dataset, never transact real fees, and
sign artifacts under a distinct key family. See
test mode for the boundary contract.
Why agent tokens are a separate resource
A tok_ carries more than authentication — it carries authorization in the
form of a structured policy: tier, allowed actions, allowed resources,
conditions, and limits. The unscoped secret key (sk_…) is preserved for
operator credentials, and a separate, structured token resource holds
everything an autonomous agent should be able to do. The
agents page is the canonical reference for tier semantics,
scope DSL, and the Authorization pause flow.
Minting a token
curl -X POST https://api.mattermode.com/v1/tokens \
-H "Authorization: Bearer $MATTER_KEY" \
-H "Matter-Version: 2026-05-01" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"tier": 3,
"principal": { "human_id": "usr_4Kj2m8pQ", "agent_id": "agt_paralegal_v2" },
"scopes": [
{
"allow": ["filings.create", "documents.create", "documents.sign"],
"resources": ["pf_studio_fund_i"],
"limits": { "max_calls_per_hour": 240 }
}
],
"expires_at": 1798761600,
"api_version": "2026-05-01"
}'{
"id": "tok_4Kj2m8pQ",
"object": "token",
"tier": 3,
"principal": { "human_id": "usr_4Kj2m8pQ", "agent_id": "agt_paralegal_v2" },
"scopes": [ /* …as supplied… */ ],
"expires_at": 1798761600,
"api_version": "2026-05-01",
"secret": "tok_4Kj2m8pQ.s3cr3t-shown-once-only-…",
"created": 1745539200,
"livemode": true
}The plaintext is in secret — it is the only time Matter returns it. Lose
it and you must revoke + re-mint. The full structured-policy DSL (allow,
deny, resources, conditions, limits, evaluation order) is documented in
agents › Structured scope policy DSL.
Rotating
POST /v1/tokens/{id}/rotate issues a new secret bound to the same id,
tier, scopes, and principal. The previous secret remains valid for
60 seconds to absorb in-flight callers, then is permanently rejected. The
60-second overlap is non-configurable.
curl -X POST https://api.mattermode.com/v1/tokens/tok_4Kj2m8pQ/rotate \
-H "Authorization: Bearer $MATTER_KEY" \
-H "Matter-Version: 2026-05-01" \
-H "Idempotency-Key: $(uuidgen)"Revoking
POST /v1/tokens/{id}/revoke invalidates immediately. Subsequent calls return
401 invalid_token. AuditEntries written before revocation are preserved —
revocation is forward-only. If the token had any pending Authorization
resources, they transition to expired and the paused operations cancel.
curl -X POST https://api.mattermode.com/v1/tokens/tok_4Kj2m8pQ/revoke \
-H "Authorization: Bearer $MATTER_KEY" \
-H "Matter-Version: 2026-05-01"Version pinning
Every token pins an api_version at creation. The token always behaves as if
its requests carried Matter-Version: <pinned>. A per-request Matter-Version
header overrides for that request only — useful for canary-testing a new
version before rotating the token's pinned version. See
versioning for the monthly release cadence.
Errors specific to tokens
| Status | Code | When |
|---|---|---|
401 | invalid_token | Token does not exist, was revoked, or its plaintext does not match. |
401 | token_expired | expires_at has elapsed. |
403 | tier_too_low | Operation requires a higher tier than the token holds. |
403 | missing_grant | No scopes[] entry matched the verb-resource pair. |
403 | condition_not_met | A matching entry's conditions evaluated false (e.g. dry_run required, livemode mismatch). |
429 | limit_exceeded | A limits cap was hit. The body identifies which cap and when it resets. |
All token errors follow the RFC 7807 envelope. The agents page catalogs the agent-surface specifically; the conventions page catalogs the API as a whole.
Related
- Agents — tier semantics, scope DSL, dual attribution, and
the
Authorizationpause flow. The canonical agent-surface reference. - Authentication — Bearer auth, version pinning, and the required-header trio across all credential families.
- Authorizations — the resource that gates tier-3 destructive operations on a human signature.
POST /tokens— generated reference for the mint endpoint.- Test mode — how
sk_test_keys sign under a separate key family and why test artifacts can't be replayed in live mode.