/v1 request must carry a credential in the Authorization: Bearer header. The gateway identifies the caller from it (team, workspace, user or service account) and applies that caller’s access rules, limits and budgets.
How the credential is recognised
The gateway checks the shape of the token to decide how to verify it:- No bearer token, but an
ml_sessioncookie goes to console session authentication (only when console sign-in is enabled). With neither, the request is refused. - A JWT-shaped token (three dot-separated parts, not starting with
ml-) is verified against your identity provider, when OIDC is configured. - Anything else is looked up as a stored credential: an API key, a personal access token or a virtual account token.
Credential types
| Credential | Prefix | Issued by | Use it for |
|---|---|---|---|
| API key | ml- | Console (Gateway → API Keys), POST /admin/keys, or gateway.yaml on self-hosted installs | Services and applications owned by a team |
| Personal access token (PAT) | ml_pat_ | A signed-in person, in the console (Gateway → Access → Personal Access Tokens) | Your own scripts, notebooks and local tools; acts as you |
| Virtual account token (VAT) | ml_vat_ | A signed-in person holding gateway.serviceaccounts.manage (Gateway → Access → Virtual Accounts) | Production workloads that need their own model and provider allow-list and scheduled rotation |
| OIDC JWT | (JWT) | Your identity provider | Callers that already hold an SSO token |
| Console session | ml_session cookie | Console sign-in | The console and its Playground |
API keys (ml-)
API keys (ml-)
An API key belongs to a team and carries a role (Self-hosted installs can also seed keys under
member, editor or admin; default member). team and name are required. Optional fields are rpm_limit, tpm_limit, budget_usd_monthly, budget_reset_period (daily, weekly, monthly or never), expires_at (RFC 3339) and user_id (an owner in the same team). Pass workspace_id to bind the key to a workspace: it then resolves chat models from that workspace’s console providers. Without it, the key is team-scoped and resolves from gateway.yaml. The plaintext key is returned once, in the creation response.Key management is a control-plane call on the console host, made by a signed-in person or a credential allowed to manage Gateway API keys:teams[].api_keys in gateway.yaml (name, key, role), with ${ENV_VAR} interpolation for the key value.Personal access tokens (ml_pat_)
Personal access tokens (ml_pat_)
A PAT authenticates as the person who created it, with their roles, in the one workspace it was issued for. If their access is revoked, so is the token’s. PATs can be issued or rotated only from a signed-in console session, never with another token, and every PAT must have an expiry. The organization’s credential policy caps the lifetime and the number of PATs per person.
Virtual account tokens (ml_vat_)
Virtual account tokens (ml_vat_)
A virtual account is a service identity in a workspace with optional
allowed_models and allowed_providers lists. A request for a model outside the list is refused with 403 model_not_allowed. Its tokens can be rotated on a schedule with a grace period. See Credentials.OIDC JWTs
OIDC JWTs
The gateway verifies the token’s signature, issuer and audience, then maps a claim to a team by name. A token whose team claim is missing or maps to no team is rejected. If the role claim matches
admin_role, the caller is an admin; otherwise a member.Key expiry
API keys, PATs and VATs can carry anexpires_at timestamp. From that moment the credential is refused with 401 key_expired rather than invalid_api_key, so a client can tell “rotate your credential” apart from “your credential is wrong”. PATs always expire. A VAT may be set never to expire if the organization’s credential policy allows it. An expired OIDC JWT fails signature verification and returns invalid_api_key.
Acting as a PAT from the console
The id of one of your own PATs. Accepted only from a signed-in console session. The request is then authenticated and attributed as that PAT, so its limits, usage and traces match the snippet the Playground generates. The header is never forwarded upstream.
400 credential_header_not_allowed. Naming a PAT that is not yours, or is no longer usable, returns 401 invalid_api_key.
Configure OIDC
Self-hosted installs enable OIDC underauth.oidc in gateway.yaml. An empty issuer disables it, and audience is required when issuer is set.
gateway.yaml
Use the Anthropic SDK
Error responses
Authentication errors use the OpenAI error envelope:| Status | code | Cause |
|---|---|---|
401 | invalid_api_key | No credential, an unknown or disabled credential, or an OIDC token that fails verification |
401 | key_expired | The credential’s expires_at has passed |
400 | credential_header_not_allowed | X-ManyLayers-Credential sent without a console session |
403 | product_not_entitled | The caller’s organization does not hold the AI Gateway product (type permission_error) |
403 | model_not_allowed | The credential’s team or virtual account may not use the requested model (type permission_error) |
Next steps
Access control
Roles, permissions and model allow-lists.
Credentials
Manage PATs, virtual accounts and rotation.