Skip to content
ApiqDevelopers
API v1.64.0Open console
API referenceidentity

Mint api key

POST/v1/keys
Accepts bearer

Mint a scoped API key — the secret is in this response and nowhere else, ever

Requires keys:manage (session only, as built — an API key is 403 ACCESS_TOKEN_REQUIRED).Show moreRequires keys:manage (session only, as built — an API key is 403 ACCESS_TOKEN_REQUIRED). The key's scopes must be a subset of the minting user's; the key is a service principal that inherits nothing from the user who minted it. Stored hashed: a lost key is revoked and re-minted, never recovered. A key can also be exchanged for a short-lived Bearer token at POST /v1/oauth/token. A system key can never file an agent proposal (POST /v1/agent-proposals, AGENT_CREDENTIAL_REQUIRED). suppliers (optional) narrows the key to a supplier allowlist on top of its scopes — see MintApiKeyRequest.suppliers for the validation and the runtime answers. It is fixed at mint and survives rotation; console sessions are never narrowed by it. The request takes the key's scope — writes (KeyWrites), products, spendPerDay, lookToBook, reqPerSec, holdsPerHour, cancelsPerDay, expiresAt — and onBehalfOf, the Member the key acts for (default the caller; its principal and principalUserId). Minted by a session, the key is kind own and a member the request leaves out or sends null sets no key cap (the tenant's limits still govern), unchanged for people; a session's onBehalfOf naming a Member other than the caller needs users:manage (else 403 PERMISSION_DENIED details.reason MISSING_PERMISSION). The key records the agent of the X-Agent header. Either actorKind may mint: the device sign-up hands the agent a system key. A cap the request leaves out or sends null is the parent's cap, never null where the parent has one; the child keeps the parent's actorKind unless it asks for ai under a system parent, and an ai parent asking for system is widening (dimension actorKind). Anything wider is 403 PERMISSION_DENIED details.reason SCOPE_WIDENING with details.dimensions naming each wider member. The child is kind agt, mintedBy the parent's keyPrefix, and its principal is the parent's, fixed at mint: an onBehalfOf naming anyone else is 403 PERMISSION_DENIED details.reason PRINCIPAL_UNKNOWN, as is an onBehalfOf that is not an active Member of the tenant. A child never widens its ancestors' blast radius: every call of a minted key also counts against each ancestor key's velocity and spend windows, and while an ancestor is PAUSED its descendants answer 423 KEY_PAUSED (resuming the ancestor resumes them), so minting N children never multiplies what one key may do. Emits key.minted. MCP: the tool mint_api_key, on the same rule.

Request body

  • actorKindstringOptionalDefault "ai"
    Anyone else asking for system is 403 PERMISSION_DENIED details.reason SYSTEM_KEY_REQUIRES_ADMIN.Show moreAnyone else asking for system is 403 PERMISSION_DENIED details.reason SYSTEM_KEY_REQUIRES_ADMIN. Any other value is a 400. The mint is audited with the actorKind.
    • ai
    • system
  • namestringOptional
    A name for the key, shown in the key list.
  • scopesarray of stringRequired
    At least one and at most 32 (ApiKeyService.MAX_SCOPES; more is 400 VALIDATION details.field scopes); known permission strings, a subset of the minting user's (deny-by-default)
  • ipAllowlistarray of stringOptional
    The only addresses or ranges the key may call from; empty means any.
  • suppliersarray of stringOptional
    Optional supplier allowlist: the supplier registry codes (GET /v1/capabilities products[].suppliers[].code) this key may reach.Show moreOptional supplier allowlist: the supplier registry codes (GET /v1/capabilities products[].suppliers[].code) this key may reach. Absent or empty means every supplier the scopes reach. When set: every code must be a known supplier (else 400 VALIDATION details.field suppliers, details.reason UNKNOWN_SUPPLIER); every supplier must serve a product one of the key's search:<tabKey> scopes reaches (else 400 VALIDATION details.reason SUPPLIER_OUTSIDE_SCOPES); and every search:<tabKey> scope must keep at least one allowed supplier (else 400 VALIDATION details.reason SCOPE_WITHOUT_SUPPLIER). A search fans out to the allowed suppliers only; any other verb on an offer, reprice, hold or order of a supplier outside the list is 403 PERMISSION_DENIED details.reason SUPPLIER_NOT_ALLOWED_FOR_KEY, and GET /v1/capabilities lists the allowed suppliers only.
  • environmentstringOptional
    Optional; defaults to this deployment's environment, and any other value is a 400.Show moreOptional; defaults to this deployment's environment, and any other value is a 400. A live key is minted only for a tenant whose production activation has been approved and never for a sandbox twin; otherwise 403 PERMISSION_DENIED, details.reason TENANT_NOT_LIVE. A SUSPENDED tenant mints nothing: 403 TENANT_SUSPENDED.
    • sandbox
    • live
  • writesone of 2Optional
    The write ladder (KeyWrites); under the narrowing rule no higher than the minting key's, and the minting key's when left out or null.Show moreThe write ladder (KeyWrites); under the narrowing rule no higher than the minting key's, and the minting key's when left out or null. Every cap below follows the same rule on a key mint; on a session mint left out or null is no key cap.
  • productsarray of stringOptional
    Product tab keys (hotels, flights), each reached by one of the key's search:<tabKey> scopes (else 400 VALIDATION details.field products).
  • spendPerDayone of 2Optional
    Daily spend cap, in the tenant's cap currency (else 400 VALIDATION CURRENCY_MISMATCH).
  • lookToBookintegerOptional
    The most searches the key may make per booking, counted per UTC day; null means no cap.
  • reqPerSecintegerOptional
    The most requests per second the key may make; null means no cap of its own.
  • holdsPerHourintegerOptional
    The most holds the key may place per hour; null means no cap.
  • cancelsPerDayintegerOptional
    The most cancellations the key may request per UTC day; null means no cap.
  • expiresAtstring · date-timeOptional
    In the future (else 400 VALIDATION details.field expiresAt).
  • onBehalfOfstring · emailOptional
    The Member the key acts for (its principal); default the caller.Show moreThe Member the key acts for (its principal); default the caller. A session may name itself, or another active Member of the tenant when it holds users:manage (else 403 PERMISSION_DENIED details.reason MISSING_PERMISSION); a key may name only its own stamped principal. Anyone else, or an address that is not an active Member, is 403 PERMISSION_DENIED details.reason PRINCIPAL_UNKNOWN.

Responses

  • 201Minted. Show apiKey once; it cannot be retrieved again.MintedApiKey
  • 400VALIDATION or UNKNOWN_DOMAINApiErrorResponse
  • 401
    UNAUTHENTICATED — missing or expired token.Show moreUNAUTHENTICATED — 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.
    ApiErrorResponse
  • 403
    The 403s of the credential-issuing routes (POST /v1/keys, POST /v1/keys/{keyPrefix}/rotate, POST /v1/invites).Show moreThe 403s of the credential-issuing routes (POST /v1/keys, POST /v1/keys/{keyPrefix}/rotate, POST /v1/invites). PERMISSION_DENIED when the caller lacks keys:manage / users:manage, and on the key routes also when a live key is asked for a tenant that is not LIVE or is a sandbox twin. On POST /v1/keys also PERMISSION_DENIED with details.reason SYSTEM_KEY_REQUIRES_ADMIN when actorKind is system and the caller is not a tenant admin.
    ApiErrorResponse
  • 405
    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 moreVALIDATION — 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.
    ApiErrorResponse
  • 413
    VALIDATION — the request body is larger than the surface's limit.Show moreVALIDATION — 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.
    ApiErrorResponse
  • 414
    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 moreVALIDATION — 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.
    ApiErrorResponse
  • 415
    VALIDATION — a request body that is not JSON (application/json or application/*+json; a form body only on the OAuth token routes).Show moreVALIDATION — 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.
    ApiErrorResponse
  • 423
    PERMISSION_DENIED with details.reason KEY_PAUSED: the API key is PAUSED and every call with it is refused until an Owner or Admin resumes it (POST /v1/keys/{keyPrefix}:resume, a person only); or…Show morePERMISSION_DENIED with details.reason KEY_PAUSED: the API key is PAUSED and every call with it is refused until an Owner or Admin resumes it (POST /v1/keys/{keyPrefix}:resume, a person only); or details.reason LOOP_DETECTED on the call whose loop paused the key (20 identical requests in 60 s, or 50 holds without a booking or release in 10 min; replays of one Idempotency-Key never count). Not retryable; nextAction stop — the agent stops using the key and tells the person; details carry resumeBy (owner), consoleLink and evidence (ApiKeyPauseEvidence). Nothing was charged, held or sent; holds and orders already made are untouched. A key whose ancestor (the key that minted it, or that key's minter) is PAUSED answers the same 423 KEY_PAUSED, and resuming the ancestor resumes it, so a child never outlasts a pause of its parent. The MCP plane answers the identical body as an isError result. Any key-authenticated route may answer it; it is declared on the order and hold writes, search, reprice and the key routes.
    ApiErrorResponse
  • 429
    RATE_LIMITED with details.reason VELOCITY_LIMIT: a soft breach of the API key's own scope (reqPerSec, holdsPerHour, cancelsPerDay, lookToBook, spendPerDay) — the first two in 24 hours; the third, or a…Show moreRATE_LIMITED with details.reason VELOCITY_LIMIT: a soft breach of the API key's own scope (reqPerSec, holdsPerHour, cancelsPerDay, lookToBook, spendPerDay) — the first two in 24 hours; the third, or a burst above 5× the limit, pauses the key instead (423 KeyPaused). Retryable after retryAfterMs (mirrored by Retry-After); nextAction slow_down; details carry limit, windowSeconds and the dimension in details.field. The tenant quota of RateLimited and the key's velocity are separate limits. Every call of a minted key also counts against each ancestor key's velocity and spend windows, so minting N children never multiplies the blast radius; spendPerDay is reserved atomically before the order is placed and released if it fails.
    ApiErrorResponse
  • 500INTERNAL — a bug, and traceId is the support handle.ApiErrorResponse
  • 501NOT_IMPLEMENTED AGENT_KEYS_UNAVAILABLE — a scope member was sent while scoped agent keys are offApiErrorResponse

Errors you should handle

Branch on code and honour retryable — never on the HTTP status alone.

400VALIDATION
message.intent.checkOut must be after message.intent.checkIn
not retryable
400UNKNOWN_DOMAIN
Unknown domain 'HOTELS'. Did you mean HTL?
not retryable
401UNAUTHENTICATED
The bearer token is expired. Re-authenticate and retry.
not retryable
403PERMISSION_DENIED
Inviting colleagues needs the users:manage permission.
not retryable
403TENANT_SUSPENDED
This tenant is suspended; no key can be minted or rotated until it is reinstated. Existing keys can still be revoked.
not retryable
405VALIDATION
This method is not served.
not retryable
413VALIDATION
The request body is larger than this API accepts (262144 bytes).
not retryable
414VALIDATION
The request URI is longer than 8 KiB.
not retryable
415VALIDATION
Send application/json.
not retryable
423PERMISSION_DENIED
This API key is paused: 212 holds in 9 min. An Owner or Admin must resume it in the console.
not retryable
429RATE_LIMITED
This API key exceeded its rate: 10 requests a second. Retry after 1.2 s.
retryable
500INTERNAL
An unexpected error occurred. Quote the traceId to support.
retryable
501NOT_IMPLEMENTED
Key scopes beyond scopes and suppliers are not available on this deployment.
not retryable