read, write and admin, and the fine-grained scopes graph:write, memory:forget, subjects:provision and usage:read.
GET /v1/me returns the scopes a key actually holds. Start there when a call returns 403.
The vocabulary
Satisfaction is transitive down that middle column. A requirement is met by the scope itself or by any scope that satisfies it, so a
write key passes a memory:forget check, and a memory:forget key passes a graph:write one.
Three implications worth knowing
graph:write does not grant memory:forget
graph:write does not grant memory:forget
This is the point of splitting them. A key with
graph:write can edit the knowledge graph, assert relations, supersede beliefs and restore a node someone tombstoned. It cannot forget anything: DELETE /v1/graph/nodes/{node_id} and DELETE /v1/graph/edges/{edge_id} both require memory:forget, and graph:write alone cannot remove structure.That lets you mint a curation key for an agent or an internal tool that is allowed to improve the graph and is structurally incapable of erasing it. A write key holds both, so if you want the separation you have to ask for it explicitly.memory:forget does grant graph:write, in that direction only
memory:forget does grant graph:write, in that direction only
The implication runs one way. Anything able to erase a node is also able to edit one, so
memory:forget satisfies a graph:write requirement. The reverse is what the previous section rules out. If you want an erase-only credential, there is no such thing: erasure is the strictly wider grant.A read key cannot read org-wide usage
A read key cannot read org-wide usage
GET /v1/usage aggregates every subject’s usage into one billing view, so it is not a read surface. It requires usage:read, which an admin key also qualifies for. A plain read key is refused.POST /v1/exports follows the same posture: an export at scope: "user" needs write, while scope: "org" exports every member’s data and additionally requires admin. GET /v1/team is a read route, because it returns the same fields GET /v1/me already gives you, but enumerating the members with GET /v1/team/members requires admin.What each route needs
The routes below need more thanread. Everything else in /v1 is a read surface, and GET /v1/me needs only a valid key.
Write
Graph mutation and erasure
Node history is read-shaped but sits on the write-managed family, because it reads the mutation record rather than the content.
Admin
GET /v1/subjects and GET /v1/subjects/{subject_id} are read routes. Only provisioning and erasure need subjects:provision.
Signed-in dashboard sessions may mint keys without holding
admin. The requirement applies to API keys calling POST /v1/keys, which is what stops a write key from minting itself a way around its own scopes.Minting a narrower key
POST /v1/keys takes an optional scopes array. Omit it and the new key inherits the caller’s scopes. Name a subset and the new key is narrower. Name a scope the caller does not hold and the mint is a 403, so minting can never escalate.
Sandbox keys ignore all of this
A sandbox key is minted withread and write, fixed, not caller-selectable. There is no way to widen or narrow it, because a test credential must never be able to mint keys, provision subjects or erase real data. See Sandbox.
What a refusal looks like
A key that authenticates but lacks the scope gets403 with permission_denied, not 401. The same status covers a subject selector that was never provisioned, so read the detail before assuming which one you hit.
403 application/problem+json
code is always the tail of the type URI, so documentationUrl resolves to a real page on this site. See Errors for the full envelope.
Next
Authentication
Headers, minting, revocation, and what a leaked key can and cannot reach.
One memory per end user
Where
subjects:provision is the scope you actually need.