Administration API
Namespaces, backends, routing rules, members and keys — everything the console drives.
The console is the usual way to do all of this, and the CLI wraps the same routes. This page is the API underneath both, for anyone automating a deployment.
There are two scopes. Tenancy routes live under /{tenancy}/v1 and concern the organisation.
Namespace routes live under /{tenancy}/{namespace}/v1 and concern one isolated workspace
inside it.
Roles and what they carry
| Role | Can |
|---|---|
user | Find the tenancy's namespaces, and use the ones granted to them |
admin | Everything a user can, plus manage namespaces, backends, rules, members and keys |
owner | Everything an admin can, plus delete a namespace, delete the tenancy, and transfer ownership |
A role is held in the tenancy. A grant is narrower: it gives one member a role inside one
namespace, which is how a user comes to be able to use prod but not staging.
Getting in
| Route | Takes | Gives |
|---|---|---|
POST /v1/registrations | A registration token, or an identity provider's | A new tenancy and its owner |
POST /v1/sessions | Email and password | A session key |
POST /v1/sessions/exchange | An identity provider's token | A session key |
A registration token is a file in the deployment's secret mount, one per client. Registration is the only way a tenancy comes to exist, and the first account created owns it.
Where the deployment signs people in through an identity provider, that provider's token is
accepted in place of a registration token, and the owner's address is taken from it rather than
from the body — a token whose address the provider has not confirmed is refused. Such an owner
has no password on this service, because they do not sign in with one: they exchange the
provider's token for a session at POST /v1/sessions/exchange, and everything below that point
is the same for them as for anybody else. A deployment that runs no provider has neither route
behaviour and is unchanged.
Namespaces
| Route | Scope |
|---|---|
GET /{tenancy}/v1/namespaces | Any member |
POST /{tenancy}/v1/namespaces | Admin |
DELETE /{tenancy}/v1/namespaces/{namespace} | Owner |
{ "slug": "prod", "name": "Production" }The slug is the URL segment. name is for people, and defaults to the slug.
Backends
Created in a namespace, then optionally attached to others.
| Route | Does |
|---|---|
POST /{tenancy}/{namespace}/v1/backends | Create one here |
GET /{tenancy}/{namespace}/v1/backends | List the ones this namespace can route to |
GET /{tenancy}/{namespace}/v1/backends/{backend} | Show one |
POST /{tenancy}/{namespace}/v1/backends/{backend} | Attach an existing backend to this namespace |
DELETE /{tenancy}/{namespace}/v1/backends/{backend} | Detach it from this namespace |
GET /{tenancy}/v1/backends | List every backend in the tenancy |
GET /{tenancy}/v1/backends/{backend}/namespaces | Which namespaces use one |
DELETE /{tenancy}/v1/backends/{backend} | Delete it everywhere |
{
"name": "anthropic-prod",
"kind": "anthropic",
"base_url": null,
"credential": "sk-ant-…"
}kind is openai_compat, anthropic or openrouter — see Routing. base_url may
be omitted where the kind implies it. credential is write-only: it is encrypted before
storage and never appears in any response, so BackendView carries id, name, kind and
base_url and nothing else.
Note the two deletes. Detaching removes a backend from one namespace; deleting removes it from the tenancy.
Routing rules
All namespace-scoped, all admin.
| Route | Does |
|---|---|
POST /{tenancy}/{namespace}/v1/routing-rules | Create |
GET /{tenancy}/{namespace}/v1/routing-rules | List |
DELETE /{tenancy}/{namespace}/v1/routing-rules/{rule} | Delete |
{
"priority": 100,
"pattern": "claude-*",
"backend_id": "…",
"model_rewrite": "claude-sonnet-4-20250514"
}Lowest priority wins. Routing has the semantics.
Members and grants
| Route | Does |
|---|---|
GET /{tenancy}/v1/users | List members |
GET /{tenancy}/v1/users/{user} | One member, with the grants they hold |
POST /{tenancy}/v1/users | Invite one |
POST /{tenancy}/v1/users/{user}/role | Change their tenancy role |
POST /{tenancy}/v1/users/{user}/password | Set their password |
DELETE /{tenancy}/v1/users/{user} | Revoke them |
GET /{tenancy}/v1/namespaces/{namespace}/grants | Who may use this namespace |
POST /{tenancy}/v1/namespaces/{namespace}/grants | Grant a member a role in it |
DELETE /{tenancy}/v1/namespaces/{namespace}/grants/{user} | Take it back |
An invited member given a password they did not choose must replace it before they can do
anything else — that is the 403 password_change_required in Errors.
Keys
| Route | Does |
|---|---|
POST /{tenancy}/v1/me/keys | Mint one for yourself |
GET /{tenancy}/v1/me/keys | List your own |
DELETE /{tenancy}/v1/me/keys/{key} | End one of your own |
POST /{tenancy}/v1/users/{user}/keys | Mint one for a member (admin) |
GET /{tenancy}/v1/users/{user}/keys | List theirs (admin) |
DELETE /{tenancy}/v1/keys/{key} | Revoke any key (admin) |
Minting answers with the only copy of the secret:
{ "id": "…", "name": "batch-worker", "prefix": "ab12cd34", "key": "sar_ab12cd34_…" }Listing never does — ApiKeyView carries id, name, prefix, created_at and revoked_at.
The secret is stored only as a keyed hash, so a lost key is replaced rather than recovered. The
eight-character prefix is the public half, and it is what usage figures and log lines name a
key by.
Ownership
| Route | Does |
|---|---|
POST /{tenancy}/v1/ownership | Transfer the tenancy to another member |
DELETE /{tenancy}/v1/tenancy | Delete the tenancy |
Both are the owner's alone.
API reference
The submission and retrieval routes for durable LLM inference, SSE replay with Last-Event-ID, and the record a request leaves behind.
Usage and storage
What a namespace has spent per key and per model, what it is holding, and why accepted submissions and provider calls are different numbers.

