Authentication and key configuration reference
Section: DOC-CP-identity-access-authentication-reference#overview.
Use this reference for credential configuration, required headers, key limits and authentication errors. Start with the signed-in conversation recipe for a complete integration.
This is a curated reference for shared authentication behavior. Exact operation request and response schemas remain in the generated API reference; this page does not publish key-management endpoints.
Key management availability
Section: DOC-CP-identity-access-authentication-reference#managing-api-keys.
Use the key-management surface enabled for your deployment. The current public reference does not publish application key-management endpoints; a signed-in dashboard session is distinct from application API authentication.
Application keys identify the tenant in the current integration. Their names do not create separate project or test/live isolation. Keep key-management access restricted, and revoke or rotate a key explicitly when its value may have been exposed.
Ask your account admin if you need a key issued, a scope added, or an existing key rotated.
That dashboard session authenticates you. Use the documented application credential pair for public API calls. Session invalidation and token revocation depend on the identity provider and the platform's validation path; a signed token is not inherently irrevocable. See Firebase session management for the distinction between token expiry, refresh-token revocation and revocation checking.
Application key types
Section: DOC-CP-identity-access-authentication-reference#key-types.
| Type | Prefix | Use it from | Pairs with |
|---|---|---|---|
| Secret | sk_* | Your backend | X-On-Behalf-Of, when acting for a user |
| Publishable | pk_* | Client apps (iOS, web) | A user JWT, always |
Every key carries a name, a description, a set of scopes, and an
optional expiry. Each also has a short prefix (for example sk_2hfK) shown in the dashboard,
so you can identify a key in logs without handling the full value.
The full key value is shown once at creation and cannot be retrieved afterward. Store it through your approved secret-handling mechanism.
Scope matching accepts an exact permission such as conversations:read, a prefix wildcard such as users:*, or the all-scopes wildcard *. Scope enforcement varies by operation; a matching key permission does not replace the application’s own authorization checks.
Publishable-key identity configuration
Section: DOC-CP-identity-access-authentication-reference#create-a-publishable-key.
Publishable keys are designed for client-side apps (iOS, web). They must always be paired with a user JWT, and require OIDC configuration so the platform can validate that JWT.
When you create one, select an accepted provider and supply its issuer and audience.
The API accepts only firebase, auth0, okta, cognito and supabase.
It derives the verification-key URL from the validated provider configuration;
supplying a custom JWKS URL does not enable another provider.
| Field | Description |
|---|---|
provider | Required provider identifier from the allowlist above |
issuer | Expected iss claim in the JWT |
jwksUrl | Derived verification-key URL; caller-supplied values do not override provider validation |
audience | Expected aud claim in the JWT |
userIdClaim | (Optional) JWT claim to extract the user ID from. Defaults to sub |
requiredClaims | (Optional) Map of claim names to expected values. Supports dot notation for nested claims (e.g., firebase.tenant) |
These are common provider configuration patterns, not a certification of every provider or token type. Qualify the issuer, audience, signing algorithm, key rotation and required claims for your deployment. Use the provider-issued token type accepted by that configuration.
| Provider | issuer | jwksUrl |
|---|---|---|
| Firebase | https://securetoken.google.com/<project-id> | https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com |
| Auth0 | https://<tenant>.auth0.com/ | https://<tenant>.auth0.com/.well-known/jwks.json |
| Okta | https://<org>.okta.com/oauth2/default | https://<org>.okta.com/oauth2/default/v1/keys |
| AWS Cognito | https://cognito-idp.<region>.amazonaws.com/<user-pool-id> | https://cognito-idp.<region>.amazonaws.com/<user-pool-id>/.well-known/jwks.json |
Keycloak is not currently accepted. The examples describe accepted issuer patterns and their derived URLs; they are not custom-JWKS configuration instructions.
See Build an AI chat assistant for a client using one end to end.
Publishable-key permission restrictions
Section: DOC-CP-identity-access-authentication-reference#publishable-key-restrictions.
Do not give client keys management permissions. Creation removes api_keys:*, webhooks:*, tenants:*, billing:*, system:*, users:impersonate and * from publishable keys, but later updates and operation checks do not uniformly apply that filter. Review permissions after editing a key, restrict who can edit keys, and keep administrative operations behind your backend's access checks; a pk_* prefix alone is not a management-access boundary.
For a worked example that selects only the permissions an application feature needs, follow Control access with scopes.
User identity and operation scope
Section: DOC-CP-identity-access-authentication-reference#acting-as-a-user--x-on-behalf-of.
A secret key identifies your tenant, not a user. Most endpoints operate on a specific user's data and reject a request that doesn't identify one:
{ "code": "UNAUTHENTICATED", "message": "authenticated user_id is required" }
With an sk_* key, X-On-Behalf-Of is the only way to supply that user. If your very
first call returns the 401 above, this header is what's missing — not your key.
The key must also carry the users:impersonate scope, or the request fails with 403 insufficient_scope. Ask for that scope when you request your key.
Which endpoints need it:
| Endpoints | X-On-Behalf-Of with sk_* |
|---|---|
LLM (/api/v1/llm/*) | Required |
Storage (/api/v1/storage/*) | Required |
Scheduler (/api/v1/scheduler/*) | Operation-specific: owner operations select a user; project teardown requires a backend request without this header. Requests without a user are also accepted on the current path, which uses the legacy default project. |
End User (/api/v1/enduser/*) | Required |
| Notifications — user-facing (inbox, preferences, push devices) | Required |
| Notifications — subscriber-specific operations, including management reads/updates/deletes | Required when selecting a user |
| Notifications — project configuration (workflows, providers, topics) | Follow the operation reference; /manage/ alone does not establish scope |
Webhooks (/api/v1/webhooks/*) | Not needed — tenant-scoped |
| Agent profiles, custom MCP configuration, project secrets | Key-only project/tenant operations in the current reference; use the operation's required permissions |
| Evals | Reads, configuration and queue operations can use a bare key. record-score requires verified reviewer identity; a backend supplies permitted X-On-Behalf-Of. Supply reviewer identity for comment attribution too. See the review recipe. |
Publishable keys (pk_*) never need it: the user comes from the accompanying JWT.
Identify the user from your authenticated application session. Do not accept an arbitrary user ID from an untrusted client merely because your backend holds an impersonation-capable key.
Key replacement and revocation
Section: DOC-CP-identity-access-authentication-reference#key-rotation.
For planned replacement, issue the successor through your enabled management interface, update the application’s secure configuration, and make a permitted request from each consumer. Keep the old credential only for the overlap needed to finish that migration. For suspected exposure, prioritize revoking the exposed credential and recover the affected consumers.
The current rotation contract issues a replacement key and sets the old one to expire after a grace period you choose — 24 hours by default, up to 720 hours (30 days). Both keys authenticate during that window, giving your consumers time to switch over. Verify that every consumer has switched before the old key expires. Revocation may not stop requests already in flight or immediately reach every cache.
Once every consumer is on the new key, the old one expires on its own; revoke it early from the dashboard if you want it dead sooner.
Publishable keys (pk_*) cannot be rotated this way. Issue a new one, migrate your clients,
then revoke the old key.
Rate-limit availability
Section: DOC-CP-identity-access-authentication-reference#rate-limiting.
The API accepts a per-minute request limit, but do not rely on that setting as a guaranteed rate or spending ceiling. Confirm your account's enforced limits and bound traffic in your application. Hourly and burst settings are not currently supported.
An absent per-key limit does not mean free, unmetered or unlimited use. Admission limits, free allowances and provider spending budgets are separate controls. Your deployment may reject requests with 429 for other reasons. Apply bounded concurrency, deadlines and backoff in your client.
Requested limit fields
Section: DOC-CP-identity-access-authentication-reference#requesting-a-limit.
If you want a ceiling applied to a key, set requests_per_minute when the key is created
or updated:
{
"rate_limit": {
"requests_per_minute": 1000
}
}
| Field | Status |
|---|---|
requests_per_minute | Positive values request a limit. Zero or omission on creation adds no per-key limit; on update it leaves an existing limit unchanged. An update cannot clear a limit with zero. |
requests_per_hour | Accepted by the API but ignored — no hourly window is applied. |
burst_size | Accepted by the API but ignored — no burst shaping is applied. |
The last two exist in the request schema and will not error, but setting them has no effect.
Rate-limit response headers
Section: DOC-CP-identity-access-authentication-reference#response-headers.
When supported and emitted by the deployment, inspect:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests in the current window |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
Retry-After | Seconds until the next request is allowed (429 responses only) |
A throttled request can return HTTP 429 (Too Many Requests). Headers may be absent; do not infer unlimited capacity from their absence. Honor Retry-After when present and stop retrying at your operation deadline.
Authentication error formats
Section: DOC-CP-identity-access-authentication-reference#error-responses-and-troubleshooting.
Use the HTTP status and the error fields described below to choose the recovery action. Key-verification errors can include denialReason; other authentication errors use the shapes shown for that error.
Application key errors
Section: DOC-CP-identity-access-authentication-reference#authentication-errors.
| Error | HTTP Status | Cause | Fix |
|---|---|---|---|
missing_credentials | 401 | No API key or JWT in request | Add X-API-Key header |
api_key_not_found | 401 | Key doesn't exist | Verify the key value is correct |
api_key_expired | 401 | Key has passed its expiration date | Create a new key |
api_key_disabled | 401 | Key is disabled | Contact your admin to re-enable |
api_key_revoked | 401 | Key has been revoked | Create a new key — revocation is permanent |
api_key_invalid | 401 | Generic invalid key | Verify the key format (sk_* or pk_*) |
insufficient_scope | 403 | Key lacks the required scope | Update the key's permissions or create a new key with the needed scope |
rate_limited | 429 | Key hit its rate limit | Wait for the reset window or increase the rate limit |
User token errors
Section: DOC-CP-identity-access-authentication-reference#publishable-key-errors.
| Error | HTTP Status | Cause | Fix |
|---|---|---|---|
publishable_key_requires_jwt | 401 | pk_* key used without a user JWT | Add Authorization: Bearer <jwt> header |
jwt_expired | 401 | User JWT has expired | Refresh the JWT token |
jwt_malformed | 401 | JWT is malformed | Verify the JWT structure |
jwt_invalid_signature | 401 | JWT signature verification failed | Ensure the JWT was issued by the correct provider |
jwt_invalid_issuer | 401 | JWT issuer doesn't match expected value | Check the OIDC issuer config on the publishable key |
jwt_invalid_audience | 401 | JWT audience doesn't match | Check the OIDC audience config on the publishable key |
user_id_claim_not_found | 401 | JWT missing the user ID claim | Ensure your JWT includes the sub claim (or the configured userIdClaim) |
Verification service errors
Section: DOC-CP-identity-access-authentication-reference#server-errors.
| Error | HTTP Status | Cause | Fix |
|---|---|---|---|
denialReason: "unkey_error" | 500 | Key verification failed | Retry with bounded backoff; if persistent, contact support |
misconfigured_publishable_key | 500 | Publishable key missing OIDC metadata | Recreate the key with publishableConfig.oidc |
oidc_not_configured | 500 | User sign-in configuration unavailable | Contact platform support |
In the inspected contract, key-verification failures can return HTTP 500 with denialReason: "unkey_error". Transport failures reaching verification return a separate 503 response; do not assume every failure uses the same JSON shape.
Request headers
Section: DOC-CP-identity-access-authentication-reference#headers.
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Your API key (sk_* or pk_*) |
Content-Type | Yes | Always application/json |
Authorization | For pk_* keys | Bearer <user-jwt> — required with publishable keys |
X-On-Behalf-Of | Required for user-scoped calls with sk_* | The application user to act for (requires users:impersonate scope) |
Use the common JSON contract for field names, omitted values and decimal-string 64-bit integers.
Document ID: DOC-CP-identity-access-authentication-reference. Section identities and revisions.