Skip to main content

Intro

The API Keys API lets you create, list, and revoke API keys for your organization. Two key types are supported:
  • Personal keys — tied to a user, inherit the user’s RBAC permissions
  • Service keys — no user association, scoped to specific projects with ADMIN access. Ideal for CI/CD, scaffolding tools, and service-to-service integrations

Authentication

Requires an organization-level API key. Pass it as a Bearer token:
Reading your own keys needs organization:view. Creating, updating and revoking need organization:manage. Reading or listing keys that belong to somebody else needs organization:manage and organization administrator membership. Service keys are the exception, because they belong to nobody. A member credential with organization:view sees the organization’s service keys in its own listing and may read one by id: administrator membership is what minting a service key takes, not what reading one takes. A service credential acts as nobody and so owns no keys at all, which makes its only listing the organization-wide one, and that needs organization:manage.

Endpoints

Reading a key back

GET /api/api-keys/{id} and PATCH /api/api-keys/{id} return the same body, and it contains every field a write accepts. bindings comes back in exactly the shape POST and PATCH take, so comparing what you asked for against what the key has is a comparison rather than a translation. The secret itself is never returned: it exists only in the create response. A personal key belonging to somebody else is readable only with organization administrator membership plus organization:manage. Without both, the id answers 404 rather than 403, because a 403 would confirm the key exists. Service keys are the exception described above: a member credential with organization:view reads one by id.

Updating

PATCH is partial at the field level: send name alone and only the name changes. bindings, when you send them, replace the key’s bindings outright, so what you send is what the key has afterward.

Key Types

Personal Keys

Created for a specific user. The key’s effective permissions are the intersection of the key’s bindings and the user’s own role bindings (the “ceiling” model).
A personal key is capped by the access of the person it belongs to. It defaults to the caller; assignedToUserId mints one for somebody else, and that key is then capped by their access rather than yours.

Service Keys

Created without a user association (userId: null). Scoped to specific projects via projectIds. Each project gets an ADMIN binding automatically.
Service keys without projectIds get org-wide ADMIN access. Always scope to specific projects when possible.
Because a service key has no person capping it, and a key minted for somebody else is capped by their access rather than yours, both are reserved for organization administrators. A caller who holds organization:manage without being an administrator is refused with 403. Minting a personal key for yourself is always allowed: your own access caps it.

Narrowing what a key may do

Three fields decide how far a key reaches:
  • bindings, the roles the key holds and where, in the same role / scopeType / scopeId shape role bindings use.
  • permissionMode, one of all, readonly or restricted. all and readonly take their meaning from the bindings alone.
  • permissions, a list of resource:action keys. Only for restricted mode, where it is the exact set the key’s CUSTOM bindings grant.
A key can never grant more than the person or organization behind it already has, whatever you put in these fields.
Last modified on August 10, 2026