The two surfaces, side by side
| Personal key | Organization key | |
|---|---|---|
| Endpoint | POST /v1/api-keys | POST /v1/orgs/{org_id}/api-keys |
| Who can create | Any authenticated user | Owner or admin of the org |
| Billed to | The user’s billing account | The org’s billing account |
| Acts as | The user’s identity | The user’s identity, scoped to the org |
| Visible in | Settings → Personal → API keys | Settings → Organization → API keys |
| Survives departure? | No — when the user leaves, key revokes | Yes — admin must explicitly revoke |
| Revoke | The user (or admin via support) | Owner, admin, or original creator |
mnm_ prefix; they’re identical at the wire level. The difference is billing attribution and lifecycle ownership.
Scope vocabulary
Mnemom keys use a capability-based scope vocabulary. Each scope names what the key is allowed to do. The default is least-privilege; admin scopes are opt-in and gated by your role at mint time and re-checked on every request.| Scope | Grants | Mintable by |
|---|---|---|
gateway | Send traffic through the Mnemom gateway worker (proxy LLM requests, capture traces). | Any authenticated user |
api:read | GET endpoints scoped to the bearer’s identity (your agents, traces, cards, policies). | Any authenticated user |
api:write | POST / PUT / PATCH / DELETE endpoints scoped to the bearer’s identity (mutate your agents, cards, policies). | Any authenticated user |
admin:org | /v1/orgs/{org_id}/... admin operations on orgs you own or admin (members, settings, billing, org-level keys). Re-checked per request against your current org membership. | Owner or admin of at least one org |
admin:platform | Mnemom-staff platform operations across tenants. Re-checked per request against your current staff role. | Mnemom-staff users only |
["gateway", "api:read", "api:write"]. Admin scopes are not added unless you explicitly request them.
Scope semantics — what to know
- Capabilities are independent.
admin:platformdoes NOT implyapi:read. A key with onlyadmin:platformcannot call/v1/agents. If your automation needs to call non-admin endpoints alongside admin ones, request both. - Mint-time ceiling is enforced server-side. Requesting a scope you’re not eligible for returns HTTP 403 at creation time. Examples:
- Request-time role is re-checked for admin scopes. If a staff member is demoted after minting an
admin:platformkey, that key’s admin power stops working immediately on the next request — without rotation. The key still authenticates for non-admin endpoints if those scopes are also present. - Demotion is silent. Mnemom does not auto-revoke admin-scoped keys when a user’s role changes. Use
DELETE /v1/api-keys/{key_id}(or rotate) when offboarding admin-role users.
Picking scopes for common patterns
- Local development on your laptop:
gateway,api:read,api:write(the default). - CI runner that publishes traces but doesn’t mutate state:
gateway,api:read. - Read-only analytics ingest into Snowflake/BQ:
api:read. - Service account that manages org members from a script:
admin:org(plusapi:readif it needs to read non-admin endpoints). - Mnemom-internal automation (deploy gates, on-call tooling):
admin:platform(plusapi:read/api:writeif it touches non-admin endpoints too).
When to use which surface
Personal key, every time — unless one of the things below applies.- Local development. A developer on the team using Mnemom from their laptop. Personal key.
- Per-engineer CI accounts. Each engineer has their own CI runner credentialed against their personal account. Personal key.
- Single-purpose script you’re running yourself. Personal key.
- Shared CI/CD infrastructure that runs as the org, not as a specific engineer. Survives engineer turnover.
- Service-account-style automation — a cron job, a webhook receiver, a third-party integration that needs to outlive any individual member’s tenure.
- Audit / compliance posture that needs requests attributed to the org rather than to a person. The audit log tags org-level keys distinctly from user-level keys.
Creating a key
Personal
Organization
key field. You see it once. Mnemom stores only its SHA-256 hash; we cannot recover the secret if you lose it.
scopes from the request body, the API substitutes the default set (["gateway", "api:read", "api:write"]).
Using a key
X-Mnemom-Api-Key header is the canonical auth path for mnm_* keys. (Some legacy SDKs send the key as Authorization: Bearer mnm_... — that path is deprecated; migrate to X-Mnemom-Api-Key.)
Legacy keys (["gateway", "api"])
Keys minted before May 2026 carry the legacy two-scope set ["gateway", "api"]. They continue to work — the auth gate aliases them to ["gateway", "api:read", "api:write"] at request time, so existing integrations need no changes.
The dashboard renders these keys with a “legacy” badge. To upgrade a legacy key to the canonical vocabulary:
- Rotate the key (
POST /v1/api-keys/{key_id}/rotate) — the rotation preserves the legacy scope set on the new key. - Revoke the rotated key and create a fresh one (
POST /v1/api-keys) without specifyingscopes. The new key inherits the default["gateway", "api:read", "api:write"].
Rotation
Two endpoints, identical contract:POST /v1/api-keys/{key_id}/rotatePOST /v1/orgs/{org_id}/api-keys/{key_id}/rotate
name and scopes, then immediately revokes the old key. The full new secret returns in the 201 response.
No grace period — by design
The old key is invalid as soon as the response reaches you. Rotation is for the suspect or compromised case where you do not want overlap. If you need overlap with an in-flight deploy, don’t rotate. Instead:POST /v1/api-keysto create a second key.- Update your deployment to use the new key.
- Verify it’s working in production.
DELETE /v1/api-keys/{old_key_id}to retire the original.
Failure semantics
- Insert-new fails: the response is 500; your old key is still valid. Try again.
- Insert-new succeeds, soft-revoke fails: the response is 500 with a hint pointing you at
DELETE /v1/api-keys/{old_key_id}to finish manually. The new key is fully active either way — capture it before retrying.
Audit trail
Rotations log a distinctapi_key_rotated event in your billing event history (and the org audit log for org-level rotations). The event records both the old and new key_ids so support can trace a rotation chain.
Org keys after P4f tightening
Org-key creation requiresowner or admin (not member). If you’re a member who used to create org keys, the path forward is:
- Use a personal key instead. They’re billed to you, but Mnemom doesn’t double-bill — the personal-key checkmeter is a courtesy view, not a separate ledger.
- Or ask an admin to create the org key for you. Once it exists, you can rotate it (you become the creator post-rotation) but only the admin can have created it initially.
Revocation
is_active flips to false, revoked_at is timestamped, the row stays for audit. You cannot reactivate a revoked key — create a new one.
For org keys, the same shape applies under /v1/orgs/{org_id}/api-keys/{key_id}. Owner, admin, or original creator can revoke; member can only revoke keys they created themselves.
Key hygiene checklist
- Rotate annually, or whenever a member with access leaves the org. The audit log shows
last_used_atper key — rotate dormant keys aggressively. - Name your keys.
"name": "ci-prod"is much more useful than"Default"six months later when you’re triaging an alert. - Use the smallest scope set that works. Default to
gateway+api:read/api:writeand only add admin scopes when the integration genuinely needs them. Smaller blast radius if leaked. - Prefer
api:readfor analytics integrations. Read-only keys are safer and the audit trail is cleaner. - Never commit secrets. The
mnm_prefix is a string git secret-scanners recognize; we recommend GitHub Secret Scanning + push protection to catch accidents. - Include a renewal reminder in your deploy / IaC if the key has a TTL constraint from your security policy. Mnemom keys themselves don’t expire by default.
- Treat admin-scope keys with extra care. Use them only for the specific automation that needs them; rotate them on any suspected leak; audit which keys carry
admin:orgoradmin:platformquarterly.