API referenceidentity
Update api key scope
PATCH
/v1/keys/{keyPrefix}Accepts bearer
Narrow an API key's scope — never widen it
Changes the scope of a live key in place; it takes effect on the key's next request, no re-issue.Show more
Changes the scope of a live key in place; it takes effect on the key's next request, no re-issue. Every member is optional and only the members sent change. Each dimension may only stay equal or get narrower than the key's current scope: writes lower on the ladder (KeyWrites), products and scopes a subset, suppliers a subset (an absent list meaning every supplier, so setting one narrows), a numeric cap lower or a cap set where there was none, expiresAt earlier or set where there was none. Anything wider is 403 PERMISSION_DENIED details.reason SCOPE_WIDENING with details.dimensions naming each wider member, and nothing changes; widening means minting a new key from a person's session. name is free. A REVOKED or EXPIRED key is 409 CONFLICT details.reason KEY_NOT_ACTIVE (a PAUSED key may be narrowed). Human session only, as every /v1/keys route (an API key is 403 PERMISSION_DENIED details.reason ACCESS_TOKEN_REQUIRED); needs keys:manage, as the other key routes, or to be the user who minted the key. Audited as key.narrowed with the before and after scope. MCP: excluded.Path parameters
- keyPrefixstringRequired
Request body
- namestringOptional
- scopesarray of stringOptionalA subset of the key's current scopes (at most 32, as MintApiKeyRequest.scopes)
- suppliersarray of stringOptionalA subset of the key's current supplier allowlist (absent there means every supplier)
- writesone of 2Optional
- productsarray of stringOptional
- spendPerDayone of 2Optional
- lookToBookintegerOptional
- reqPerSecintegerOptional
- holdsPerHourintegerOptional
- cancelsPerDayintegerOptional
- expiresAtstring · date-timeOptional
Responses
- 200The key with its narrowed scopeApiKeyMetadata
- 400VALIDATION or UNKNOWN_DOMAINApiErrorResponse
- 401ApiErrorResponse
UNAUTHENTICATED — missing or expired token.Show more
UNAUTHENTICATED — missing or expired token. Declared on every operation because `security` is declared globally at the document root: every route is authenticated, so every route can answer 401. - 403PERMISSION_DENIED — SCOPE_WIDENING (details.dimensions; nextAction widen_scope_via_owner), ACCESS_TOKEN_REQUIRED (an API key), or MISSING_PERMISSION (neither keys:manage nor the minter)ApiErrorResponse
- 404NOT_FOUND — unknown or expired ref (unguessable refs, 15)ApiErrorResponse
- 405ApiErrorResponse
VALIDATION — the public edge serves GET, POST, PUT, PATCH and DELETE only; any other method is refused before the platform sees it (details.reason METHOD_NOT_ALLOWED, details.source edge).Show more
VALIDATION — the public edge serves GET, POST, PUT, PATCH and DELETE only; any other method is refused before the platform sees it (details.reason METHOD_NOT_ALLOWED, details.source edge). Not retryable as sent. - 409CONFLICT KEY_NOT_ACTIVE — the key is REVOKED or EXPIREDApiErrorResponse
- 413ApiErrorResponse
VALIDATION — the request body is larger than the surface's limit.Show more
VALIDATION — the request body is larger than the surface's limit. Not retryable as sent: shrink the body. Declared on every operation that takes a request body. details carries exactly one key, maxBodyBytes (integer): the limit that applies to this surface, in bytes. - 414ApiErrorResponse
VALIDATION — the request URI (path and query string) is longer than 8 KiB; the public edge refuses it before the platform sees it (details.reason URI_TOO_LONG, details.source edge).Show more
VALIDATION — the request URI (path and query string) is longer than 8 KiB; the public edge refuses it before the platform sees it (details.reason URI_TOO_LONG, details.source edge). Not retryable as sent: send long input in the body of a POST. - 415ApiErrorResponse
VALIDATION — a request body that is not JSON (application/json or application/*+json; a form body only on the OAuth token routes).Show more
VALIDATION — a request body that is not JSON (application/json or application/*+json; a form body only on the OAuth token routes). The public edge refuses it before the platform sees it (details.reason UNSUPPORTED_MEDIA_TYPE, details.source edge). Not retryable as sent: send Content-Type application/json. Declared on every operation that takes a JSON request body. - 500INTERNAL — a bug, and traceId is the support handle.ApiErrorResponse
- 501NOT_IMPLEMENTED AGENT_KEYS_UNAVAILABLE — scoped agent keys are off on this deploymentApiErrorResponse
Errors you should handle
Branch on code and honour retryable — never on the HTTP status alone.
| 400 | VALIDATION message.intent.checkOut must be after message.intent.checkIn | not retryable |
| 400 | UNKNOWN_DOMAIN Unknown domain 'HOTELS'. Did you mean HTL? | not retryable |
| 401 | UNAUTHENTICATED The bearer token is expired. Re-authenticate and retry. | not retryable |
| 403 | PERMISSION_DENIED This change would widen the key on: writes, reqPerSec. Mint a new key from a signed-in session instead. | not retryable |
| 404 | NOT_FOUND searchRef SR-F-7b31d0a9 is unknown or has expired; re-search | not retryable |
| 405 | VALIDATION This method is not served. | not retryable |
| 409 | CONFLICT This key is revoked and cannot be changed. | not retryable |
| 413 | VALIDATION The request body is larger than this API accepts (262144 bytes). | not retryable |
| 414 | VALIDATION The request URI is longer than 8 KiB. | not retryable |
| 415 | VALIDATION Send application/json. | not retryable |
| 500 | INTERNAL An unexpected error occurred. Quote the traceId to support. | retryable |
| 501 | NOT_IMPLEMENTED Scoped agent keys are not available on this deployment. | not retryable |