- API keys, for server-to-server integrations against the public
/v1API. Scoped, org-bound, and what the SDK and MCP server use. - Session tokens, for the web app and the CLI, acting as a user across their organizations.
API keys (recommended for integrations)
Create a key in Settings → Applications. Keys come in two shapes:
Send a secret key as a Bearer token (the
X-Api-Key header is also accepted and takes precedence):
/v1 requests do not need an Organization header, the key already identifies the workspace.
Scopes
Each key holds a set of scopes; every endpoint requires the matching one (fail-closed). Grant only what an integration needs:
Call
GET /v1/me at any time to confirm a key’s org, environment (live / test), and scopes.
Keys issued by browser sign-in
An MCP client that signs in through the browser is handed one of these same keys. There is no second kind of token. You choose the workspace on the approval screen, the scopes it asks for are listed there before you authorize, and the result shows up in Settings → Applications where you can see its last use and revoke it like any other key. That means everything on this page applies to it too: the same scope checks, the sameinsufficient_scope errors, the same revocation. The only difference is that nobody had to copy a secret.
Signing in as a user (the CLI)
Not every caller is a server. The CLI acts as you, across every organization you belong to, so it signs in rather than carrying a key:custral logout ends it.
Session auth exists for Custral’s own clients, the web app, the desktop and
mobile apps, and the CLI. It is tied to a signed-in person, it expires, and its
shape is an internal detail that changes without notice.Build integrations on API keys and
/v1. That’s the surface with scopes, a
stable contract, and versioning. If you’re reaching for a session token to do
something /v1 can’t, email hello@custral.com.
That’s a gap worth closing properly.Errors
invalid_api_key: the API key is missing, unknown, inactive, or expired.insufficient_scope: the key lacks the scope the endpoint requires.authorization_missing: no session token was sent (session auth).authorization_invalid: the token does not match an active session.organization_invalid: the user behind the session is not a member of the organization in the request.