{"openapi":"3.1.0","info":{"title":"VectorAxis API","description":"The VectorAxis AI gateway: OpenAI, Anthropic and Cohere compatible inference, and the management API for virtual keys, prompts, routing configs, guardrails, observability, the MCP Gateway and the AI Trust Pack.","version":"v1"},"servers":[{"url":"https://api.vectoraxis.ai"}],"tags":[{"name":"Chat completions","description":"OpenAI-compatible chat completions through the gateway. Point the OpenAI SDK's base URL at VectorAxis and call any supported provider's models with a virtual key, direct provider credentials or a routing config; caching, retries, fallbacks and guardrails are set with headers."},{"name":"Claude Messages","description":"Anthropic Messages API compatible endpoints, so the Claude SDKs and Claude Code work against VectorAxis with only the base URL and key changed. Requests get the same credentials, caching, retries, fallbacks and guardrails as chat completions."},{"name":"Claude Message Batches","description":"Anthropic Message Batches API compatible endpoints, so the Claude SDKs' batch clients work against VectorAxis. Batches run on your own Anthropic key, are checked by guardrails before they are sent, and are billed to the virtual key once they end."},{"name":"Embeddings","description":"Turn text into vectors through the gateway, in OpenAI's Embeddings format (OpenAI, Voyage AI, Cohere, Azure OpenAI and other OpenAI-compatible providers) or in Cohere's own Embed v2 format. The provider's SDK works with only its base URL and API key changed."},{"name":"Responses","description":"OpenAI's Responses API through the gateway, for any provider: create a model response, streamed or not, then retrieve it, list its input items or delete it. The OpenAI SDK and tools built on it (Codex) work with only the base URL and API key changed, and get the same caching, retries, fallbacks, routing configs and guardrails as chat completions."},{"name":"Audio","description":"Speech to text and text to speech through the gateway, compatible with OpenAI's Audio API: transcribe or translate an audio file, or generate speech from text. Works with OpenAI and OpenAI-compatible providers, Sarvam and ElevenLabs."},{"name":"Images","description":"Generate and edit images through the gateway, compatible with OpenAI's Images API. The OpenAI SDK works with only the base URL and API key changed."},{"name":"Files","description":"Upload files for batch jobs, the Responses API and chat messages, compatible with OpenAI's Files API. Every file gets a VectorAxis id (`vxf-...`) that you use everywhere in place of the provider's file id."},{"name":"Batches","description":"Run large sets of requests asynchronously with OpenAI's Batch API through the gateway: create a batch from an uploaded JSONL file, follow its progress, cancel it and download its results."},{"name":"Decisions","description":"OpenAI's Decisions API through the gateway: ask typed questions about an input (a probability, a choice or a score) and get structured answers back. The OpenAI SDK works with only the base URL and API key changed."},{"name":"System One","description":"TypeSafe AI's System One API through the gateway: ask typed questions about a state and get calibrated answers (a probability, a choice or a score) instead of text. The TypeSafe SDK works with its base URL set to the gateway and a virtual key as its API key."},{"name":"Virtual keys","description":"A virtual key is the credential your applications send to the gateway instead of a provider API key. It holds your own provider keys (BYOK) or draws on VectorAxis credits (PLATFORM), and carries its own spend limits, rate limits, model allowlist and guardrails."},{"name":"Routing configs","description":"A routing config spreads requests across several virtual keys: one target (SINGLE), weighted load balancing (LOADBALANCE), fallback in order on chosen error statuses (FALLBACK), or rules on the request (CONDITIONAL). Strategies nest. Send the config's slug in the `x-config` header, with `x-organization`, instead of a virtual key."},{"name":"Prompts","description":"A prompt library: versioned prompt templates with `{{variable}}` placeholders, labels such as `production` and `staging`, test cases and analytics. Publish a version, then call the prompt by its slug with a virtual key instead of sending the messages yourself."},{"name":"Guardrails","description":"Guardrails check the text going to and coming back from a model: personal information, secrets, prompt injection, banned words, output format and more. Each guardrail is a list of checks that block, redact or only log what they find. Attach a guardrail to a virtual key, or name it per request with the `x-guardrail` header."},{"name":"Providers","description":"The model providers the gateway can call, for the provider of a virtual key credential or the `x-provider` header."},{"name":"Pricing","description":"What VectorAxis charges per token for requests made with a PLATFORM virtual key, by provider and model."},{"name":"Logs and analytics","description":"Every request that passes through the gateway is logged: provider, model, tokens, cost, latency, cache, guardrail and tool-scan results. Search the logs, read one in full, chart usage over time, break it down, and export it."},{"name":"Tool inventory","description":"Every tool your agents use, found in gateway traffic: tools declared on LLM requests, tools the model asked to call, and tools called through the MCP Gateway, with whether an MCP Gateway integration governs each one."},{"name":"MCP integrations","description":"Connectors to the upstream MCP servers and REST APIs your agents use through the MCP Gateway: credentials, capability sync, tool approval and policy, guardrails and which workspaces may use them."},{"name":"MCP servers","description":"The endpoints agents and MCP clients connect to, at mcp.vectoraxis.ai/s/{slug}: one per workspace and connector, with its own capability switches, guardrails, user access and limits on what the upstream may ask for."},{"name":"MCP keys","description":"The va_ keys agents present to the MCP Gateway. An MCP key belongs to one workspace, works only on the gateway, and carries a tool allowlist and rate limits."},{"name":"MCP runs","description":"The audit of every call through the MCP Gateway, across servers: the gateway's verdict, guardrail results, and calls held for a person's approval."},{"name":"MCP tool search","description":"Find the tools a workspace's MCP servers offer by what they do, ranked by relevance and recent health."},{"name":"Trust Pack","description":"The AI Trust Pack: reports on where your organization's AI data goes, what VectorAxis keeps of it and how much of your traffic your guardrails check, the approved provider policy with change alerts, signed evidence bundles, your public trust page and an AI vendor questionnaire with answers drawn from your records."},{"name":"Public trust pages","description":"Endpoints for your customers' reviewers, with no credentials: an organization's published trust page, and the public key that verifies a signed evidence bundle."},{"name":"Organization","description":"Your organization as a whole: its members and their roles, and closing the organization. An organization holds every workspace, key and resource you create."},{"name":"Workspaces","description":"Workspaces divide an organization into teams or projects. Virtual keys, prompts, routing configs, guardrails and logs belong to a workspace, and members are granted access per workspace."},{"name":"API keys","description":"Platform API keys (`va_...`) authenticate calls to the management API. Each key is scoped to the whole organization or to one workspace, with an admin or member role."},{"name":"Billing","description":"Your organization's plan, the limits and features it includes, and the credit balance that pays for platform-key (PLATFORM) inference. Purchases and plan changes are made by the organization owner in the dashboard."}],"paths":{"/v1/workspaces/{slug}":{"get":{"tags":["Workspaces"],"summary":"Get a workspace","description":"Get a workspace.\n\nRequires access to the workspace: an organization owner or admin, a member of the workspace, an organization-scoped `va_` key with the admin role, or a `va_` key scoped to this workspace. Errors: 403 without access; 404 when the organization has no workspace with this slug.","operationId":"getWorkspace","parameters":[{"name":"slug","in":"path","description":"the workspace's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"the slug of the organization the workspace belongs to","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/Workspace"}}}}},"security":[{"platformKey":[]}]},"put":{"tags":["Workspaces"],"summary":"Update a workspace","description":"Update a workspace.\n\nChanges the workspace's name, description and default routing config. `name` is changed only when sent; `description` and `default_routing_config_slug` are replaced on every update, so leaving one out clears it. The slug cannot be changed.\n\nRequires workspace admin access: an organization owner or admin, an admin of the workspace, an organization-scoped `va_` key with the admin role, or a `va_` key scoped to this workspace with the admin role. Errors: 403 without it; 404 when the workspace does not exist.","operationId":"updateWorkspace","parameters":[{"name":"slug","in":"path","description":"the workspace's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"the slug of the organization the workspace belongs to","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the new values","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWorkspaceRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/Workspace"}}}}},"security":[{"platformKey":[]}]},"delete":{"tags":["Workspaces"],"summary":"Delete a workspace","description":"Delete a workspace.\n\nDeletes the workspace and returns 204. An organization always keeps at least one workspace.\n\nRequires workspace admin access: an organization owner or admin, an admin of the workspace, an organization-scoped `va_` key with the admin role, or a `va_` key scoped to this workspace with the admin role. Errors: 403 without it; 404 when the workspace does not exist; 409 when it is the organization's last workspace.","operationId":"deleteWorkspace","parameters":[{"name":"slug","in":"path","description":"the workspace's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"the slug of the organization the workspace belongs to","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"}},"security":[{"platformKey":[]}]}},"/v1/virtual-keys/{slug}":{"get":{"tags":["Virtual keys"],"summary":"Get a virtual key","description":"Get a virtual key.\n\nAnswers the key's settings, limits, usage counters and status. Provider keys and the API key's secret are never returned: a credential shows only its last four characters (`key_hint`) and the API key only the end of its secret (`token_hint`).\n\nRequires a key of the key's organization with access to its workspace: a workspace key (member or admin) for that workspace, or an organization admin key. 403 without it; 404 when no key has this slug.","operationId":"getVirtualKey","parameters":[{"name":"slug","in":"path","description":"the key's slug (`vk-` followed by 16 hex characters)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VirtualKey"}}}}},"security":[{"platformKey":[]}]},"put":{"tags":["Virtual keys"],"summary":"Update a virtual key","description":"Update a virtual key.\n\nChanges the key's name, note, expiry, metadata, model allowlist, guardrails, credit settings and rate limits. The credential mode, provider keys, organization and workspace cannot be changed here (move a key with \"Transfer a virtual key\"; for other provider keys, create a new key).\n\nHow each field is applied:\n\n- `name`, `note` and `credit_reset_policy` change when present and are kept when left out. Setting `credit_reset_policy` also schedules its next reset from now.\n- The limits `credit_limit_usd`, `credit_alert_threshold_usd`, `rate_limit_rpm`, `rate_limit_tpm` and `rate_limit_rpd`: a number sets the limit, `null` removes it, and leaving the field out keeps it.\n- `guardrail_slugs`: a list replaces the attached guardrails (`[]` detaches them all); leaving it out keeps them.\n- `expires_at`, `metadata` and `model_allowlist`: a value replaces it, `null` removes it (the key no longer expires, has no metadata, or may call every model), and leaving the field out keeps it.\n\nWhen the credit limit changes, the status follows it: an `EXHAUSTED` key whose limit is removed, or raised above what it has spent, becomes `ACTIVE`; an `ACTIVE` key whose limit is lowered to what it has spent, or below, becomes `EXHAUSTED`. `DISABLED` and `EXPIRED` keys keep their status.\n\nRequires an organization admin key, or a workspace admin key for the key's workspace.\n\nErrors: 400 for a body that does not match the schema, or a guardrail slug that is unknown, duplicated or in another workspace; 403 without the required role; 404 when no key has this slug.","operationId":"updateVirtualKey","parameters":[{"name":"slug","in":"path","description":"the key's slug","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the fields to change","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVirtualKeyRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VirtualKey"}}}}},"security":[{"platformKey":[]}]},"delete":{"tags":["Virtual keys"],"summary":"Delete a virtual key","description":"Delete a virtual key.\n\nDeletes the key and its stored provider keys; its API key stops working at once. Answers 204 with no body.\n\nRequires an organization admin key, or a workspace admin key for the key's workspace.\n\nErrors: 403 without the required role; 404 when no key has this slug; 409 when a routing config uses the key as a target (the message names the configs: remove the key from them first).","operationId":"deleteVirtualKey","parameters":[{"name":"slug","in":"path","description":"the key's slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}},"security":[{"platformKey":[]}]}},"/v1/virtual-keys/{slug}/tool-scan":{"get":{"tags":["Virtual keys"],"summary":"Get a virtual key's tool-scan action","description":"Get a virtual key's tool-scan action.\n\nAnswers what the tool-result scan does on this key's requests: the key's own `action` (absent when it uses the platform default), the platform `default_action`, and the `effective_action` that applies. `MONITOR` records what it finds and lets the request through, `REDACT` removes the matched text from the tool result before the model sees it, and `BLOCK` refuses the request with 422.\n\nRequires a key of the key's organization with access to its workspace: a workspace key (member or admin) for that workspace, or an organization admin key. 403 without it; 404 when no key has this slug.","operationId":"getToolScan","parameters":[{"name":"slug","in":"path","description":"the key's slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ToolScanSettings"}}}}},"security":[{"platformKey":[]}]},"put":{"tags":["Virtual keys"],"summary":"Set a virtual key's tool-scan action","description":"Set a virtual key's tool-scan action.\n\nSets what the tool-result scan does on this key's requests: `MONITOR`, `REDACT` or `BLOCK`. `{\"action\": null}` goes back to the platform default. A body without `action` (`{}`) changes nothing and answers the current setting.\n\nRequires an organization admin key, or a workspace admin key for the key's workspace.\n\nErrors: 403 without the required role; 404 when no key has this slug.","operationId":"updateToolScan","parameters":[{"name":"slug","in":"path","description":"the key's slug","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the action to set","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateToolScanSettingsRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ToolScanSettings"}}}}},"security":[{"platformKey":[]}]}},"/v1/trust/questionnaire/answers/{questionId}":{"put":{"tags":["Trust Pack"],"summary":"Answer a questionnaire question","description":"Answer a questionnaire question.\n\nSaves the organization's own answer to one question, replacing any generated answer; a blank answer removes it, so the generated answer (if any) applies again. Answers 204 with no body. Each change is recorded in the Trust Pack audit trail.\n\nRequires an organization owner or admin and the Trust Pack controls in the plan. Errors: 400 for an answer over 10,000 characters; 402 when the plan does not include the Trust Pack controls; 403 for a caller who is not an organization owner or admin; 404 for an unknown question id.","operationId":"answerQuestion","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}},{"name":"questionId","in":"path","description":"the question's id, as `id` in the questionnaire (for example `log-retention`)","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the answer","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateQuestionAnswerRequest"}}},"required":true},"responses":{"200":{"description":"OK"}},"security":[{"platformKey":[]}]}},"/v1/trust/profile":{"get":{"tags":["Trust Pack"],"summary":"Get the trust page settings","description":"Get the trust page settings.\n\nThe organization's public trust page settings: its address, whether it is published and indexable, the name and contact shown, the sections and the workspace it reports on. An organization that never saved settings gets the defaults: unpublished, a slug made from the organization slug, the organization's name, and the sections `SUBPROCESSORS`, `DATA_HANDLING` and `POLICY`.\n\nRequires an organization owner or admin (403 otherwise). Readable on every plan, so an organization can always see and unpublish its page; `entitled` says whether the plan includes publishing.","operationId":"profile","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrustProfileResponse"}}}}},"security":[{"platformKey":[]}]},"put":{"tags":["Trust Pack"],"summary":"Update the trust page settings","description":"Update the trust page settings.\n\nChanges the public trust page settings; a field left out is unchanged. Publishing makes the page readable by anyone at `GET /v1/public/trust/{public_slug`} (and in the VectorAxis web app at `/trust/{public_slug`}). The public page can take up to ten minutes to reflect a change.\n\nRequires an organization owner or admin. Publishing, or changing the address of a published page, needs the Trust Pack controls in the plan; unpublishing never does.\n\nErrors: 400 for a slug that is not 3 to 63 lower-case letters, digits or dashes (not starting or ending with a dash) or is reserved, a display name over 120 characters, an invalid contact email, publishing with no section, or a workspace that is not the organization's; 402 when publishing needs the Trust Pack controls and the plan does not include them; 403 for a caller who is not an organization owner or admin; 409 when another organization already uses the slug.","operationId":"updateProfile","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the fields to change","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTrustProfileRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrustProfileResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/trust/policy":{"get":{"tags":["Trust Pack"],"summary":"Get the approved provider policy","description":"Get the approved provider policy.\n\nReturns the organization's approved sub-processor policy (whether calls to providers outside the approved list are refused, and the list) and where sub-processor change alerts go (email, webhook). The webhook signing secret itself is never returned here, only whether one is set.\n\nRequires an organization owner or admin (403 otherwise). Readable on every plan, so an organization whose plan no longer includes the Trust Pack controls can still see, and turn off, what it set; `entitled` says whether the plan includes them.","operationId":"policy","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrustPolicyResponse"}}}}},"security":[{"platformKey":[]}]},"put":{"tags":["Trust Pack"],"summary":"Update the approved provider policy","description":"Update the approved provider policy.\n\nChanges the approved provider list, turns enforcement on or off, and sets where change alerts go. A field left out is unchanged. While the policy is on, a call to a provider outside `approved_providers` is refused before it is made. Setting or changing `webhook_url`, or `rotate_webhook_secret: true`, issues a new webhook signing secret, returned once in `webhook_secret` of this response; store it then, it is not shown again. Removing the webhook URL deletes its secret.\n\nRequires an organization owner or admin. Turning the policy on, setting a webhook URL or rotating the secret needs the Trust Pack controls in the plan; turning things off or clearing them never does.\n\nErrors: 400 for an unknown provider id, for turning the policy on with no approved provider, or for a webhook URL that is not allowed (it must be a public https address); 402 when the change needs the Trust Pack controls and the plan does not include them; 403 for a caller who is not an organization owner or admin.","operationId":"updatePolicy","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the fields to change","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTrustPolicyRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrustPolicyResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/prompts/{slug}":{"get":{"tags":["Prompts"],"summary":"Get a prompt","description":"Get a prompt.\n\nReturns the prompt with its default version: the one the `production` label points at, else the PUBLISHED version. Requires membership of the prompt's workspace (organization admins have it). 404 when the organization has no prompt with this slug.","operationId":"getPrompt","parameters":[{"name":"slug","in":"path","description":"the prompt's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PromptDetail"}}}}},"security":[{"platformKey":[]}]},"put":{"tags":["Prompts"],"summary":"Update a prompt","description":"Update a prompt.\n\nChanges the prompt's name and description; versions are not affected. The description is always replaced, so leaving it out clears it. Requires an admin of the prompt's workspace, or an organization admin. 404 when the prompt does not exist.","operationId":"updatePrompt","parameters":[{"name":"slug","in":"path","description":"the prompt's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the new name and description","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePromptRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/Prompt"}}}}},"security":[{"platformKey":[]}]},"delete":{"tags":["Prompts"],"summary":"Delete a prompt","description":"Delete a prompt.\n\nDeletes the prompt. Requires an admin of the prompt's workspace, or an organization admin. 404 when the prompt does not exist.","operationId":"deletePrompt","parameters":[{"name":"slug","in":"path","description":"the prompt's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"}},"security":[{"platformKey":[]}]}},"/v1/prompts/{slug}/labels/{label}":{"put":{"tags":["Prompts"],"summary":"Set a prompt label","description":"Set a prompt label.\n\nPoints the label at a version, creating the label or moving it from the version it pointed at. A request picks a labelled version with `version_ref: \"@label\"`; the `production` label decides the default version. Requires an admin of the prompt's workspace, or an organization admin.\n\nErrors: 404 when the prompt or version does not exist; 409 when the version is not PUBLISHED.","operationId":"setLabel","parameters":[{"name":"slug","in":"path","description":"the prompt's slug","required":true,"schema":{"type":"string"}},{"name":"label","in":"path","description":"the label's name, for example `production` or `staging`","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the version to point at","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetLabelRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PromptLabel"}}}}},"security":[{"platformKey":[]}]},"delete":{"tags":["Prompts"],"summary":"Delete a prompt label","description":"Delete a prompt label.\n\nRemoves the label; the version it pointed at is unchanged. Requires an admin of the prompt's workspace, or an organization admin. 404 when the prompt or label does not exist.","operationId":"deleteLabel","parameters":[{"name":"slug","in":"path","description":"the prompt's slug","required":true,"schema":{"type":"string"}},{"name":"label","in":"path","description":"the label's name","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"}},"security":[{"platformKey":[]}]}},"/v1/mcp-servers/{slug}":{"get":{"tags":["MCP servers"],"summary":"Get an MCP server","description":"Get an MCP server.\n\nRequires an organization admin key, or a key of the server's workspace (any role). Returns 404 when the server does not exist in the organization.","operationId":"get","parameters":[{"name":"slug","in":"path","description":"The MCP server's slug (`mcps-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpServer"}}}}},"security":[{"platformKey":[]}]},"put":{"tags":["MCP servers"],"summary":"Update an MCP server","description":"Update an MCP server.\n\nA partial update: absent fields are left unchanged. Sending `guardrail_slugs` replaces the list.\n\nRequires an organization admin key, or a workspace admin key for the server's workspace. Returns 400 for an unknown guardrail or one of another workspace. Returns 402 when the organization's plan does not include the MCP Gateway. Returns 404 when the server does not exist in the organization.","operationId":"update","parameters":[{"name":"slug","in":"path","description":"The MCP server's slug (`mcps-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the fields to change","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMcpServerRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpServer"}}}}},"security":[{"platformKey":[]}]},"delete":{"tags":["MCP servers"],"summary":"Delete an MCP server","description":"Delete an MCP server.\n\nDeletes the server; agents can no longer reach it. The connector is not affected. Requires an organization admin key, or a workspace admin key for the server's workspace. Returns 404 when the server does not exist in the organization.","operationId":"delete","parameters":[{"name":"slug","in":"path","description":"The MCP server's slug (`mcps-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"}},"security":[{"platformKey":[]}]}},"/v1/mcp-servers/{slug}/user-access":{"get":{"tags":["MCP servers"],"summary":"Get an MCP server's user access","description":"Get an MCP server's user access.\n\nWho may use the server as themselves, through an MCP client they connected with OAuth: the default for people with no entry, and the per-person entries. Agents on an MCP key are governed by the key instead.\n\nRequires an organization admin key, or a key of the server's workspace (any role). Returns 404 when the server does not exist in the organization.","operationId":"userAccess","parameters":[{"name":"slug","in":"path","description":"The MCP server's slug (`mcps-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpUserAccessSettings"}}}}},"security":[{"platformKey":[]}]},"put":{"tags":["MCP servers"],"summary":"Update an MCP server's user access","description":"Update an MCP server's user access.\n\nSets `default_user_access` and, when `users` is sent, replaces the per-person entries. A denied person is refused on their next call. Every listed person must be a member of the server's workspace.\n\nRequires an organization admin key, or a workspace admin key for the server's workspace. Returns 400 for a duplicate user or one outside the workspace. Returns 402 when the organization's plan does not include the MCP Gateway. Returns 404 when the server does not exist in the organization.","operationId":"updateUserAccess","parameters":[{"name":"slug","in":"path","description":"The MCP server's slug (`mcps-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the access to set","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpUserAccessSettings"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpUserAccessSettings"}}}}},"security":[{"platformKey":[]}]}},"/v1/mcp-servers/{slug}/policy":{"get":{"tags":["MCP servers"],"summary":"Get an MCP server's request policy","description":"Get an MCP server's request policy.\n\nWhat the upstream may ask for while it answers a call: sampling (LLM completions run on a virtual key, with a model, token cap and monthly budget), elicitation (input from the person), roots and the nesting depth, with this month's sampling spend.\n\nRequires an organization admin key, or a key of the server's workspace (any role). Returns 404 when the server does not exist in the organization.","operationId":"policy_1","parameters":[{"name":"slug","in":"path","description":"The MCP server's slug (`mcps-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpServerRequestPolicy"}}}}},"security":[{"platformKey":[]}]},"put":{"tags":["MCP servers"],"summary":"Update an MCP server's request policy","description":"Update an MCP server's request policy.\n\nA partial update: absent fields are left unchanged; `clear_sampling_max_tokens` and `clear_sampling_budget` remove those caps. When sampling is on, the server needs `sampling_virtual_key` (a virtual key of the server's workspace, not disabled or expired) and `sampling_model` (allowed by that key); sampling completions are billed to that key.\n\nRequires an organization admin key, or a workspace admin key for the server's workspace. Returns 400 when sampling is on without a usable key and model, or for an invalid root URI. Returns 402 when the organization's plan does not include the MCP Gateway. Returns 404 when the server does not exist in the organization.","operationId":"updatePolicy_1","parameters":[{"name":"slug","in":"path","description":"The MCP server's slug (`mcps-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the fields to change","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpServerRequestPolicy"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpServerRequestPolicy"}}}}},"security":[{"platformKey":[]}]}},"/v1/mcp-servers/{slug}/capabilities":{"get":{"tags":["MCP servers"],"summary":"List an MCP server's capabilities","description":"List an MCP server's capabilities.\n\nThe connector's capabilities as seen from this server: `server_enabled` says whether the server has each switched on, and `effective_enabled` whether a call through this server would be allowed. Not paginated.\n\nRequires an organization admin key, or a key of the server's workspace (any role). Returns 404 when the server does not exist in the organization.","operationId":"listCapabilities","parameters":[{"name":"slug","in":"path","description":"The MCP server's slug (`mcps-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpCapabilityListResponse"}}}}},"security":[{"platformKey":[]}]},"put":{"tags":["MCP servers"],"summary":"Update an MCP server's capabilities","description":"Update an MCP server's capabilities.\n\nSwitches capabilities on or off for this server only, with `enabled`. A server can only narrow its connector: a capability off on the connector stays off. Pinning, releasing and the call policy are set on the connector; `pin` is refused here and the other fields are ignored. Returns the updated list.\n\nRequires an organization admin key, or a workspace admin key for the server's workspace. Returns 400 for `pin` or a capability of another connector. Returns 402 when the organization's plan does not include the MCP Gateway. Returns 404 when the server does not exist in the organization.","operationId":"updateCapabilities","parameters":[{"name":"slug","in":"path","description":"The MCP server's slug (`mcps-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the changes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMcpCapabilitiesRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpCapabilityListResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/mcp-keys/{id}":{"put":{"tags":["MCP keys"],"summary":"Update an MCP key","description":"Update an MCP key.\n\nA partial update of the name, tool allowlist and rate limits; `clear_tool_allowlist` and `clear_rate_limits` remove them. The secret is changed by rotating.\n\nRequires an organization admin key, or a workspace admin key for the key's workspace. Returns 400 for an invalid allowlist entry. Returns 402 when the organization's plan does not include the MCP Gateway. Returns 404 when the key does not exist in the organization.","operationId":"update_1","parameters":[{"name":"id","in":"path","description":"The MCP key's ID (UUID).","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the fields to change","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMcpKeyRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpKey"}}}}},"security":[{"platformKey":[]}]},"delete":{"tags":["MCP keys"],"summary":"Revoke an MCP key","description":"Revoke an MCP key.\n\nThe key stops working at once. Revoking an already revoked key does nothing. Returns 204.\n\nRequires an organization admin key, or a workspace admin key for the key's workspace. Returns 404 when the key does not exist in the organization.","operationId":"revoke","parameters":[{"name":"id","in":"path","description":"The MCP key's ID (UUID).","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"}},"security":[{"platformKey":[]}]}},"/v1/mcp-integrations/{slug}":{"get":{"tags":["MCP integrations"],"summary":"Get a connector","description":"Get a connector.\n\nRequires read access to the connector: for a workspace-owned connector, an organization admin key or a key of that workspace; for an organization-level connector, any organization member. Returns 404 when the connector does not exist in the organization.","operationId":"get_1","parameters":[{"name":"slug","in":"path","description":"The connector's slug (`mcpi-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpIntegration"}}}}},"security":[{"platformKey":[]}]},"put":{"tags":["MCP integrations"],"summary":"Update a connector","description":"Update a connector.\n\nA partial update: absent fields are left unchanged. Changing the URL, the spec or the credentials marks a synced connector `STALE` until it is synced again. Sending `guardrail_slugs` replaces the list.\n\nRequires an organization admin key, or a workspace admin key for the owning workspace (an organization-level connector needs an organization admin). Changing `org_connection_for_users` also requires an organization admin key. Returns 400 for settings that do not fit the connector's kind or auth type. Returns 402 when the organization's plan does not include the MCP Gateway. Returns 404 when the connector does not exist in the organization.","operationId":"update_2","parameters":[{"name":"slug","in":"path","description":"The connector's slug (`mcpi-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the fields to change","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMcpIntegrationRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpIntegration"}}}}},"security":[{"platformKey":[]}]},"delete":{"tags":["MCP integrations"],"summary":"Delete a connector","description":"Delete a connector.\n\nDeletes the connector. Requires an organization admin key, or a workspace admin key for the owning workspace (an organization-level connector needs an organization admin). Returns 409 while MCP servers are built on it: delete them first. Returns 404 when the connector does not exist in the organization.","operationId":"delete_1","parameters":[{"name":"slug","in":"path","description":"The connector's slug (`mcpi-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"}},"security":[{"platformKey":[]}]}},"/v1/mcp-integrations/{slug}/workspaces":{"get":{"tags":["MCP integrations"],"summary":"Get which workspaces may use a connector","description":"Get which workspaces may use a connector.\n\nRequires read access to the connector: for a workspace-owned connector, an organization admin key or a key of that workspace; for an organization-level connector, any organization member. Returns 404 when the connector does not exist in the organization.","operationId":"getWorkspaceAccess","parameters":[{"name":"slug","in":"path","description":"The connector's slug (`mcpi-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpWorkspaceAccess"}}}}},"security":[{"platformKey":[]}]},"put":{"tags":["MCP integrations"],"summary":"Update which workspaces may use a connector","description":"Update which workspaces may use a connector.\n\nFor organization-level connectors: sets `global_workspace_access` and adds or updates per-workspace entries; workspaces not listed keep their setting. A workspace that loses access keeps its MCP servers on the connector, but they cannot be used.\n\nRequires an organization admin key, or a workspace admin key for the owning workspace (an organization-level connector needs an organization admin). Returns 400 for a workspace-owned connector, or a workspace outside the organization. Returns 402 when the organization's plan does not include the MCP Gateway. Returns 404 when the connector does not exist in the organization.","operationId":"updateWorkspaceAccess","parameters":[{"name":"slug","in":"path","description":"The connector's slug (`mcpi-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the access to set","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMcpWorkspaceAccessRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpWorkspaceAccess"}}}}},"security":[{"platformKey":[]}]}},"/v1/mcp-integrations/{slug}/capabilities":{"get":{"tags":["MCP integrations"],"summary":"List a connector's capabilities","description":"List a connector's capabilities.\n\nEvery tool, prompt, resource and resource template found by sync, with its definition, pin and drift state, scan findings and quarantine, call policy and whether calls to it would be allowed (`effective_enabled`). Not paginated.\n\nRequires read access to the connector: for a workspace-owned connector, an organization admin key or a key of that workspace; for an organization-level connector, any organization member. Returns 404 when the connector does not exist in the organization.","operationId":"listCapabilities_1","parameters":[{"name":"slug","in":"path","description":"The connector's slug (`mcpi-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpCapabilityListResponse"}}}}},"security":[{"platformKey":[]}]},"put":{"tags":["MCP integrations"],"summary":"Update a connector's capabilities","description":"Update a connector's capabilities.\n\nApplies several changes at once: switch capabilities on or off, `pin` the current definition (clears drift), `release` a quarantined definition despite its scan findings, and set the call policy of a tool: `is_privileged` (refused for a caller that received untrusted content recently, unless a person approves the call), `requires_approval` (every call waits for a person's approval; the agent's identical retry then goes ahead once) and `trusted_output` (its results do not make the caller untrusted). Returns the updated list.\n\nRequires an organization admin key, or a workspace admin key for the owning workspace (an organization-level connector needs an organization admin). Returns 400 for a capability of another connector, `release` on a definition that is not quarantined, or `is_privileged` / `requires_approval` on something other than a tool. Returns 402 when the organization's plan does not include the MCP Gateway. Returns 404 when the connector does not exist in the organization.","operationId":"updateCapabilities_1","parameters":[{"name":"slug","in":"path","description":"The connector's slug (`mcpi-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the changes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMcpCapabilitiesRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpCapabilityListResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/guardrails/{slug}":{"get":{"tags":["Guardrails"],"summary":"Get a guardrail","description":"Get a guardrail.\n\nReturns the guardrail with its checks and the virtual keys that apply it. Requires membership of the guardrail's workspace (organization admins have it). 404 when the organization has no guardrail with this slug.","operationId":"get_2","parameters":[{"name":"slug","in":"path","description":"the guardrail's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GuardrailDetail"}}}}},"security":[{"platformKey":[]}]},"put":{"tags":["Guardrails"],"summary":"Update a guardrail","description":"Update a guardrail.\n\nChanges the fields present in the body; `checks`, when present, replaces the whole list. Requests that apply the guardrail use the new version within a minute. Requires an admin of the guardrail's workspace, or an organization admin.\n\nErrors: 400 and 402 for checks, as on create; 403 without access; 404 when the guardrail does not exist.","operationId":"update_3","parameters":[{"name":"slug","in":"path","description":"the guardrail's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the fields to change","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateGuardrailRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GuardrailDetail"}}}}},"security":[{"platformKey":[]}]},"delete":{"tags":["Guardrails"],"summary":"Delete a guardrail","description":"Delete a guardrail.\n\nDeletes the guardrail. Requires an admin of the guardrail's workspace, or an organization admin. 409 while a virtual key, or an MCP connector or endpoint, still applies it: the message names them, and they must be detached first. 404 when the guardrail does not exist.","operationId":"delete_2","parameters":[{"name":"slug","in":"path","description":"the guardrail's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"}},"security":[{"platformKey":[]}]}},"/v1/configs/{slug}":{"get":{"tags":["Routing configs"],"summary":"Get a routing config","description":"Get a routing config.\n\nAnswers the config with its full target tree, conditions and settings.\n\nRequires a key of the organization with access to the config's workspace: a workspace key (member or admin) for that workspace, or an organization admin key. 403 without it; 404 when the organization has no config with this slug.","operationId":"get_3","parameters":[{"name":"slug","in":"path","description":"the config's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RoutingConfigDetail"}}}}},"security":[{"platformKey":[]}]},"put":{"tags":["Routing configs"],"summary":"Update a routing config","description":"Update a routing config.\n\nChanges the config. `name`, `description`, `strategy_mode`, `conditional_default_target_name`, `cache`, `retry` and `request_timeout_ms` change when present and are kept when left out. `on_status_codes` is replaced on every update: leaving it out resets it to the default statuses.\n\n`targets` is required: the update validates the config (as \"Validate a routing config\") and replaces the whole target tree, and the conditions with it, by what you send. Send the full tree each time.\n\nRequires an organization admin key, or a workspace admin key for the config's workspace.\n\nErrors: 403 without the required role; 404 when the organization has no config with this slug; 422 when the config is not valid, including when `targets` is missing or empty.","operationId":"update_4","parameters":[{"name":"slug","in":"path","description":"the config's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the fields to change","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRoutingConfigRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RoutingConfigDetail"}}}}},"security":[{"platformKey":[]}]},"delete":{"tags":["Routing configs"],"summary":"Delete a routing config","description":"Delete a routing config.\n\nDeletes the config. Requests that still send its slug in `x-config` fail from then on. The virtual keys it used are not affected. Answers 204 with no body.\n\nRequires an organization admin key, or a workspace admin key for the config's workspace.\n\nErrors: 403 without the required role; 404 when the organization has no config with this slug.","operationId":"delete_3","parameters":[{"name":"slug","in":"path","description":"the config's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"}},"security":[{"platformKey":[]}]}},"/v2/embed":{"post":{"tags":["Embeddings"],"summary":"Create embeddings in Cohere's format","description":"Create embeddings in Cohere's format.\n\nCompatible with Cohere's Embed API (v2): the Cohere SDK works with its base URL set to the gateway. The body is forwarded to Cohere as sent and Cohere's answer is returned in its own format. Only a Cohere credential is accepted here; any other provider's key is a 422 (use `POST /v1/embeddings` for those).\n\nAuthenticate with a Cohere virtual key or with `x-provider: cohere` and `x-api-key`. The key's checks, the plan's limits and the organization's approved-provider policy (403) apply. INPUT guardrails run over `texts` and the text items of `inputs`; a REDACT changes what is embedded and a BLOCK is a 422. `x-cache-mode: simple` serves an identical earlier request from the cache; `semantic` is not used. You are charged for Cohere's billed input tokens at the model's input rate (`x-operation-cost-usd`). Without `x-retry-count` a failed call is retried up to 3 times on 429 and 5xx. Cohere's own errors are returned unchanged. A request without `model` is a 400.","operationId":"cohereEmbed","parameters":[{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-cache-mode","in":"header","description":"Turns on the response cache for this request: `simple` (exact match) or `semantic` (a similar earlier request). Without it nothing is read from or written to the cache. The outcome is in the `x-cache-status` response header.","required":false,"schema":{"type":"string"}},{"name":"x-cache-ttl","in":"header","description":"How long, in seconds, a response stored by this request stays in the cache. When the organization has a cache TTL set, this can shorten it but not extend it.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-cache-force-refresh","in":"header","description":"`true` skips the cache lookup, calls the provider and replaces the stored response (`x-cache-status: REFRESH`).","required":false,"schema":{"type":"boolean"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}},{"name":"x-guardrail","in":"header","description":"A guardrail slug (`gr-...`) to apply to this request, in addition to any the virtual key carries. A BLOCK is a 422 with `x-guardrail-status: BLOCK`.","required":false,"schema":{"type":"string"}},{"name":"x-request-timeout-ms","in":"header","description":"How long to wait for the provider, in milliseconds, before giving up (at most 3600000, one hour).","required":false,"schema":{"type":"integer","format":"int32"}}],"requestBody":{"description":"the embed request, in Cohere's Embed v2 format","content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}],"x-wire-format":{"name":"Cohere Embed API (v2)","url":"https://docs.cohere.com/reference/embed"}}},"/v1/workspaces":{"get":{"tags":["Workspaces"],"summary":"List workspaces","description":"List workspaces.\n\nReturns every workspace in the organization, not paginated.\n\nRequires a member of the organization (any role), or an organization-scoped `va_` key with the admin or member role. A workspace-scoped key is refused with 403; it can read its own workspace with `GET /v1/workspaces/{slug`}.","operationId":"listWorkspaces","parameters":[{"name":"organization","in":"query","description":"the organization's slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WorkspaceListResponse"}}}}},"security":[{"platformKey":[]}]},"post":{"tags":["Workspaces"],"summary":"Create a workspace","description":"Create a workspace.\n\nCreates a workspace in `organization`. Without a `slug`, one is derived from the name: lower case, spaces as dashes, anything but letters, digits and dashes dropped (`workspace` if nothing is left). A signed-in user who creates a workspace becomes its admin. Returns 201 with the workspace.\n\nRequires an organization owner or admin, or an organization-scoped `va_` key with the admin role. Errors: 402 when the plan's workspace limit is reached; 409 when the slug is already used in the organization.","operationId":"createWorkspace","requestBody":{"description":"the workspace's organization, name, and optional slug and description","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkspaceRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/Workspace"}}}}},"security":[{"platformKey":[]}]}},"/v1/workspaces/{slug}/members":{"get":{"tags":["Workspaces"],"summary":"List workspace members","description":"List workspace members.\n\nReturns the people explicitly added to the workspace, with their workspace role, including pending invitations (`is_pending: true`). Organization owners and admins can use every workspace without being listed here. Not paginated. Fails with 404 when the workspace does not exist.\n\nRequires membership of the workspace (a member, or a `va_` key scoped to it), or organization admin. Anyone else gets 403.","operationId":"listWorkspaceMembers","parameters":[{"name":"slug","in":"path","description":"the workspace's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"the slug of the organization the workspace belongs to","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WorkspaceMemberListResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/virtual-keys":{"get":{"tags":["Virtual keys"],"summary":"List virtual keys","description":"List virtual keys.\n\nLists an organization's keys, or one workspace's, a page at a time. The filters combine. Each key is returned as by \"Get a virtual key\": provider keys are never included, only their hints.\n\nRequires a workspace key (member or admin) for `workspace_id` when it is given, or an organization admin key; an organization-wide list (no `workspace_id`) requires an organization admin key. 403 otherwise.","operationId":"listVirtualKeys","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"only keys in this workspace (UUID); omit for every key in the organization","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"provider","in":"query","description":"only keys with a credential for this provider, e.g. `OPENAI`","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","description":"only keys in this status: `ACTIVE`, `DISABLED`, `EXHAUSTED` or `EXPIRED`","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"the page number, starting at 1 (default 1)","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"page_size","in":"query","description":"keys per page (default 20, at most 100)","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VirtualKeyListResponse"}}}}},"security":[{"platformKey":[]}]},"post":{"tags":["Virtual keys"],"summary":"Create a virtual key","description":"Create a virtual key.\n\nCreates a key in a workspace and answers its API key (`api_key`: the slug, a dot, then a secret). The API key is shown only in this response: store it now. Send it as a bearer token in `Authorization` (or in `x-virtual-key`) on inference requests. A new key is `ACTIVE`.\n\nTwo credential modes:\n\n- `BYOK` (the default): you supply your provider keys in `credentials`. They are stored encrypted and only their last four characters are ever returned. `initial_credits_usd`, `provider_whitelist` and `markup_pct` are ignored.\n- `PLATFORM`: requests use VectorAxis's own provider accounts and are paid from your organization's credit balance, at the provider's price plus a markup. `initial_credits_usd` is required and must be greater than 0; it also becomes the key's credit limit (`credit_limit_usd` is ignored). `credentials` are ignored. A PLATFORM key cannot be created while a credit withdrawal is pending.\n\nEvery guardrail in `guardrail_slugs` must exist in the organization and, when the guardrail belongs to a workspace, in the key's workspace.\n\nRequires an organization admin key, or a workspace admin key for `workspace_id`.\n\nErrors: 400 when a PLATFORM key has no positive `initial_credits_usd`, `provider_whitelist` names an unknown provider, or a guardrail slug is unknown, duplicated or in another workspace; 403 without the required role; 409 when the organization already has a key with this `name`. The organization's subscription must be active and its plan's virtual key quota not yet reached.","operationId":"createVirtualKey","requestBody":{"description":"the key to create","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVirtualKeyRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VirtualKeyCreateResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/virtual-keys/{slug}/transfer":{"post":{"tags":["Virtual keys"],"summary":"Transfer a virtual key to another workspace","description":"Transfer a virtual key to another workspace.\n\nMoves the key to `target_workspace_id`. Its slug, API key, settings and usage are unchanged.\n\nRequires admin on both workspaces: an organization admin key, or a workspace admin key for the key's current workspace and for the target. The target must be a workspace of the key's own organization.\n\nErrors: 400 when `target_workspace_id` is missing or is the key's current workspace, or the key is `EXPIRED`; 403 without the required role, or when the target is not a workspace of the key's organization; 404 when no key has this slug.","operationId":"transferVirtualKey","parameters":[{"name":"slug","in":"path","description":"the key's slug","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the workspace to move the key to","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferVirtualKeyRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VirtualKey"}}}}},"security":[{"platformKey":[]}]}},"/v1/virtual-keys/{slug}/rotate":{"post":{"tags":["Virtual keys"],"summary":"Rotate a virtual key's API key","description":"Rotate a virtual key's API key.\n\nIssues a new API key and answers it once: store it now. The previous API key stops authenticating on the next request (for a key created before API keys existed, the bare slug stops working). The slug, settings, limits, usage and logs are unchanged, so routing configs that use the key keep working.\n\nRequires an organization admin key, or a workspace admin key for the key's workspace.\n\nErrors: 403 without the required role; 404 when no key has this slug; 409 when the key is `EXPIRED`.","operationId":"rotateVirtualKey","parameters":[{"name":"slug","in":"path","description":"the key's slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VirtualKeyRotateResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/virtual-keys/{slug}/enable":{"post":{"tags":["Virtual keys"],"summary":"Enable a virtual key","description":"Enable a virtual key.\n\nSets the key to `ACTIVE` and clears its disable reason, so a `DISABLED` key works again.\n\nRequires an organization admin key, or a workspace admin key for the key's workspace.\n\nErrors: 403 without the required role; 404 when no key has this slug; 409 when the key is `EXPIRED` (expiry is final).","operationId":"enableVirtualKey","parameters":[{"name":"slug","in":"path","description":"the key's slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VirtualKey"}}}}},"security":[{"platformKey":[]}]}},"/v1/virtual-keys/{slug}/disable":{"post":{"tags":["Virtual keys"],"summary":"Disable a virtual key","description":"Disable a virtual key.\n\nSets the key to `DISABLED`: requests made with it are refused with 403 (`VIRTUAL_KEY_DISABLED`, with your reason as the message) until it is enabled again. The body is optional. Disabling a key that is already disabled changes nothing and answers the key as it is.\n\nRequires an organization admin key, or a workspace admin key for the key's workspace.\n\nErrors: 403 without the required role; 404 when no key has this slug; 409 when the key is `EXPIRED`.","operationId":"disableVirtualKey","parameters":[{"name":"slug","in":"path","description":"the key's slug","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"optional: the reason, shown on the key and in the error its callers receive","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DisableVirtualKeyRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VirtualKey"}}}}},"security":[{"platformKey":[]}]}},"/v1/trust/policy/webhook-test":{"post":{"tags":["Trust Pack"],"summary":"Send a test webhook delivery","description":"Send a test webhook delivery.\n\nPosts a signed test event to the organization's change-alert webhook so you can check your endpoint and your signature verification. The body is a JSON object with `type` (`trust.test`), `organization`, `sent_at` and an empty `events` list; a real delivery has `type` `trust.subprocessor_changes` and the changes in `events`. Every delivery carries `X-VectorAxis-Timestamp` (Unix seconds) and `X-VectorAxis-Signature: sha256=<hex>`, the HMAC-SHA256 of `\"<timestamp>.<body>\"` keyed with the webhook signing secret. The call times out after 10 seconds and does not follow redirects.\n\nRequires an organization owner or admin and the Trust Pack controls in the plan.\n\nErrors: 400 when no webhook URL is set, when the webhook answers with a status outside 200 to 299, or when it cannot be reached (the message says which); 402 when the plan does not include the Trust Pack controls; 403 for a caller who is not an organization owner or admin.","operationId":"testWebhook","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The webhook accepted the test delivery.","content":{"application/json":{"schema":{"type":"object","properties":{"delivered":{"type":"boolean","description":"Always true: a failed delivery is answered with a 400 instead."},"status":{"type":"integer","format":"int32","description":"The HTTP status your webhook answered with, from 200 to 299."}}}}}}},"security":[{"platformKey":[]}]}},"/v1/trust/evidence-exports":{"get":{"tags":["Trust Pack"],"summary":"List evidence bundles","description":"List evidence bundles.\n\nThe organization's evidence bundles, newest first, at most 50, in every status (including `FAILED` and `EXPIRED`).\n\nRequires an organization owner or admin (403 otherwise). Available on every plan, so bundles built earlier stay listed and downloadable until they expire.","operationId":"evidenceExports","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrustEvidenceExportListResponse"}}}}},"security":[{"platformKey":[]}]},"post":{"tags":["Trust Pack"],"summary":"Create an evidence bundle","description":"Create an evidence bundle.\n\nStarts building a signed evidence bundle for the period and answers 202 with the export in `PENDING`; poll `GET /v1/trust/evidence-exports/{id`} until it is `READY` (or `FAILED`), then download the zip. The bundle holds the period's sub-processor, data handling, guardrail coverage and change reports, the configuration audit trails (virtual keys, routing configs, guardrails, prompts, MCP, Trust Pack) and the metadata of the requests logged in the region that builds the bundle (at most 50,000 rows each), plus a readable `report.html`. `manifest.json` records each file's SHA-256 and size and is signed with Ed25519 (`manifest.sig`); verify it against the key from `GET /v1/public/trust/evidence-signing-key`. A ready bundle is kept for 30 days, then deleted (`EXPIRED`).\n\nThe body is optional: without it the period is the 90 days up to now. The period can be at most 366 days long. Requires an organization owner or admin and the Trust Pack controls in the plan. One bundle is built at a time per organization.\n\nErrors: 400 when `start_time` is not before `end_time` or the period is longer than 366 days; 402 when the plan does not include the Trust Pack controls; 403 for a caller who is not an organization owner or admin; 409 while another bundle for the organization is pending or running; 503 when evidence bundles are not available on this deployment (no signing key or file storage).","operationId":"startEvidenceExport","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the period to cover (optional)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceExportRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrustEvidenceExport"}}}}},"security":[{"platformKey":[]}]}},"/v1/systemone":{"post":{"tags":["System One"],"summary":"Answer questions with System One","description":"Answer questions with System One.\n\nCompatible with TypeSafe System One's answer endpoint: send a `state` and named `questions`, get one typed answer per question. `model`, `state` and `questions` are required (400 without them). With a virtual key a `provider/` prefix on `model` is removed before the call.\n\nAuthenticate with a TypeSafe virtual key or with `x-provider: typesafe` and `x-api-key`; any other provider is a 422, and a PLATFORM virtual key is a 400. The key's checks, the plan's limits and the organization's approved-provider policy (403) apply. INPUT guardrails (the key's and `x-guardrail`) run over every text in `state` and each question's `instructions`; a REDACT rewrites the text and a BLOCK is a 422. Usage is priced per token from TypeSafe's reported usage. Without `x-retry-count` a failed call is retried up to 3 times on 429 and 5xx (including TypeSafe's 529). TypeSafe's own errors are returned unchanged: status, body and `Retry-After`.","operationId":"answer","parameters":[{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}},{"name":"x-guardrail","in":"header","description":"A guardrail slug (`gr-...`) to apply to this request, in addition to any the virtual key carries. A BLOCK is a 422 with `x-guardrail-status: BLOCK`.","required":false,"schema":{"type":"string"}}],"requestBody":{"description":"the questions to answer, in TypeSafe's format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SystemOneRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SystemOneResponse"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}]}},"/v1/responses":{"post":{"tags":["Responses"],"summary":"Create a model response","description":"Create a model response.\n\nDrop-in compatible with OpenAI's Responses API, for every provider the gateway serves: the body is a Responses request and the answer a Responses object (or, with `\"stream\": true`, a `text/event-stream` of Responses events: `response.created`, `response.output_item.added`, `response.output_text.delta`, `response.function_call_arguments.delta`, ..., `response.completed`). With an OpenAI key the request goes to OpenAI as sent (apart from what the gateway sets: the model, guardrail redactions, routing overrides), so every Responses feature works. With a key for another provider (Anthropic, Gemini, Vertex AI, Groq, Mistral, ...) it is translated: text, images, files, function tools and their calls and outputs, `tool_choice`, `max_output_tokens`, `temperature`, `top_p`, `reasoning.effort` and `text.format` carry over, and Claude's thinking comes back as `reasoning` items to send back on the next turn. What only OpenAI can do is a 400 naming it on another provider: built-in tools (`web_search`, `file_search`, ...), their call items, `previous_response_id`, `conversation`, `prompt` and `background`. A response from another provider is not stored (`store` is `false`).\n\n**Credentials**, in this order: `x-virtual-key`; `Authorization: Bearer vk-...` (what the OpenAI SDK sends from `OPENAI_API_KEY`); `x-config` (a routing config, with `x-organization`); `x-api-key`; any other `Authorization: Bearer` token. A value starting `vk-` is a virtual key's API key, BYOK or PLATFORM; anything else is the provider's own key (OpenAI, unless `x-provider` names another provider). No credential is a 401.\n\n**What the gateway adds** is the same as on chat completions: the virtual key's checks and the plan's limits, the response cache (`x-cache-mode`), retries and fallbacks (`x-retry-*`, `x-fallback-*`, which can cross providers), routing configs (`x-config`), the tool-result scan on `function_call_output` items, and guardrails (the virtual key's plus `x-guardrail`) on the input and the answer. The response carries `x-cache-status`, `x-retry-count`, `x-fallback-provider` (when a fallback answered), `x-virtual-key-slug` and `x-guardrail-status` (when guardrails apply). `file_id` values that are VectorAxis file ids (`vxf-...`) uploaded with the same virtual key are replaced by the provider's file id.\n\n**Streaming.** Retries and fallbacks apply until the first event, and a cache hit is replayed as events. A failure after the first event (a provider error mid-answer, an output guardrail BLOCK) ends the stream with an `error` event. On a stream, `x-guardrail-status` reports the input checks only.\n\n**Errors** are in OpenAI's shape, `{\"error\":{\"message\",\"type\",\"param\",\"code\"`}}: 400 for an invalid request or one the provider cannot take, 401 for a missing or invalid credential, 403 when the virtual key is disabled, expired or out of credit or the model is not allowed, 422 when a guardrail blocks (`code: guardrail_blocked`, with `x-guardrail-status: BLOCK`), 429 for a rate limit. A provider's error keeps its status and message.","operationId":"createResponse","parameters":[{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-cache-mode","in":"header","description":"Turns on the response cache for this request: `simple` (exact match) or `semantic` (a similar earlier request). Without it nothing is read from or written to the cache. The outcome is in the `x-cache-status` response header.","required":false,"schema":{"type":"string"}},{"name":"x-cache-ttl","in":"header","description":"How long, in seconds, a response stored by this request stays in the cache. When the organization has a cache TTL set, this can shorten it but not extend it.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-cache-force-refresh","in":"header","description":"`true` skips the cache lookup, calls the provider and replaces the stored response (`x-cache-status: REFRESH`).","required":false,"schema":{"type":"boolean"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}},{"name":"x-fallback-1-provider","in":"header","description":"The provider to try when the request fails after its retries. Up to five fallbacks, tried in order: `x-fallback-1-*` to `x-fallback-5-*`. The provider that answered is in the `x-fallback-provider` response header.","required":false,"schema":{"type":"string"}},{"name":"x-fallback-1-api-key","in":"header","description":"The API key for fallback 1's provider.","required":false,"schema":{"type":"string"}},{"name":"x-fallback-1-model","in":"header","description":"The model fallback 1 uses. Optional: the request's own model otherwise.","required":false,"schema":{"type":"string"}},{"name":"x-guardrail","in":"header","description":"A guardrail slug (`gr-...`) to apply to this request, in addition to any the virtual key carries. A BLOCK is a 422 with `x-guardrail-status: BLOCK`.","required":false,"schema":{"type":"string"}},{"name":"x-config","in":"header","description":"A routing config slug: the config chooses the provider, model and key (load balancing, fallback or conditional routing). Without a virtual key, send `x-organization` with it to name the config's organization.","required":false,"schema":{"type":"string"}},{"name":"x-organization","in":"header","description":"The organization slug. Required with `x-config`; with a virtual key the key's organization is used.","required":false,"schema":{"type":"string"}},{"name":"x-workspace-id","in":"header","description":"Workspace id (UUID) to attribute the request to in logs and analytics.","required":false,"schema":{"type":"string"}},{"name":"x-metadata","in":"header","description":"A JSON object of your own string key/value pairs, stored with the request's log entry for filtering.","required":false,"schema":{"type":"string"}},{"name":"x-prompt-slug","in":"header","description":"Attributes the request to a prompt from the prompt library, for its analytics.","required":false,"schema":{"type":"string"}},{"name":"x-prompt-version","in":"header","description":"The prompt version the request used, with `x-prompt-slug`.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-vertex-project","in":"header","description":"Google Vertex AI keys only: the GCP project to call, instead of the one stored with the key.","required":false,"schema":{"type":"string"}},{"name":"x-vertex-region","in":"header","description":"Google Vertex AI keys only: the region to call (or `global`), instead of the one stored with the key.","required":false,"schema":{"type":"string"}},{"name":"anthropic-beta","in":"header","description":"Anthropic beta features, comma-separated (for example `context-management-2025-06-27`). Forwarded to Anthropic and Claude on Vertex only; at most 32 names of lower-case letters, digits and dashes.","required":false,"schema":{"type":"string"}}],"requestBody":{"description":"the response request, in OpenAI's Responses format","content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"The response. With `stream: true`, a stream of Responses events ending with `response.completed`.","content":{"application/json":{"schema":{"type":"object"}},"text/event-stream":{"schema":{"type":"string"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}],"x-wire-format":{"name":"OpenAI Responses API","url":"https://platform.openai.com/docs/api-reference/responses/create"}}},"/v1/prompts":{"get":{"tags":["Prompts"],"summary":"List prompts","description":"List prompts.\n\nReturns a page of the organization's prompts. With `workspace_id` the list holds that workspace's prompts and needs membership of the workspace; without it the list covers the whole organization and needs an organization admin.","operationId":"listPrompts","parameters":[{"name":"organization","in":"query","description":"slug of the organization","required":true,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"id (UUID) of a workspace, to list only its prompts","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"search","in":"query","description":"keeps the prompts on the returned page whose name or description contains this text (any case). It filters the page, not the whole list: `total` still counts every prompt","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"page number, from 1. Default 1","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"page_size","in":"query","description":"prompts per page. Default 20, at most 100","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PromptListResponse"}}}}},"security":[{"platformKey":[]}]},"post":{"tags":["Prompts"],"summary":"Create a prompt","description":"Create a prompt.\n\nCreates an empty prompt (no versions yet) in a workspace and returns it with its slug. Add versions with `POST /v1/prompts/{slug`/versions}. Requires an organization admin, or an admin of the workspace in `workspace_id`.\n\nErrors: 402 when the plan's prompt limit for the workspace is reached; 403 without access; 409 when the organization already has a prompt with this name.","operationId":"createPrompt","requestBody":{"description":"the prompt to create","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePromptRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/Prompt"}}}}},"security":[{"platformKey":[]}]}},"/v1/prompts/{slug}/versions":{"get":{"tags":["Prompts"],"summary":"List prompt versions","description":"List prompt versions.\n\nReturns every version of the prompt, newest first, without their messages. Requires membership of the prompt's workspace (organization admins have it). 404 when the prompt does not exist.","operationId":"listVersions","parameters":[{"name":"slug","in":"path","description":"the prompt's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PromptVersionListResponse"}}}}},"security":[{"platformKey":[]}]},"post":{"tags":["Prompts"],"summary":"Create a prompt version","description":"Create a prompt version.\n\nSaves a new version as a DRAFT, numbered one above the prompt's highest version. Versions are never edited: save a new one instead. Requires an admin of the prompt's workspace, or an organization admin. 404 when the prompt does not exist.","operationId":"saveVersion","parameters":[{"name":"slug","in":"path","description":"the prompt's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the version's messages, model, parameters, variables and tools","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePromptVersionRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PromptVersion"}}}}},"security":[{"platformKey":[]}]}},"/v1/prompts/{slug}/versions/{versionNumber}/rollback":{"post":{"tags":["Prompts"],"summary":"Roll back to a prompt version","description":"Roll back to a prompt version.\n\nCopies an earlier version into a new DRAFT version, numbered one above the highest. Publish the new version to make it the default. Requires an admin of the prompt's workspace, or an organization admin. 404 when the prompt or version does not exist.","operationId":"rollbackVersion","parameters":[{"name":"slug","in":"path","description":"the prompt's slug","required":true,"schema":{"type":"string"}},{"name":"versionNumber","in":"path","description":"the version to copy","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PromptVersion"}}}}},"security":[{"platformKey":[]}]}},"/v1/prompts/{slug}/versions/{versionNumber}/publish":{"post":{"tags":["Prompts"],"summary":"Publish a prompt version","description":"Publish a prompt version.\n\nMakes this version the prompt's PUBLISHED version; the one published before it becomes ARCHIVED. Labels in the body are pointed at this version. The body is optional. Requires an admin of the prompt's workspace, or an organization admin.\n\nErrors: 404 when the prompt or version does not exist; 409 when the version is ARCHIVED.","operationId":"publishVersion","parameters":[{"name":"slug","in":"path","description":"the prompt's slug","required":true,"schema":{"type":"string"}},{"name":"versionNumber","in":"path","description":"the version to publish","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"optional labels to point at the version","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishVersionRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PromptVersion"}}}}},"security":[{"platformKey":[]}]}},"/v1/prompts/{slug}/test-cases":{"get":{"tags":["Prompts"],"summary":"List prompt test cases","description":"List prompt test cases.\n\nReturns the prompt's test cases. Requires membership of the prompt's workspace (organization admins have it). 404 when the prompt does not exist.","operationId":"listTestCases","parameters":[{"name":"slug","in":"path","description":"the prompt's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PromptTestCaseListResponse"}}}}},"security":[{"platformKey":[]}]},"post":{"tags":["Prompts"],"summary":"Create a prompt test case","description":"Create a prompt test case.\n\nAdds a test case: variables to render the prompt with and an optional pattern the answer must match. Run them with `POST /v1/prompts/{slug`/test-cases/run}. Requires an admin of the prompt's workspace, or an organization admin. 404 when the prompt does not exist.","operationId":"createTestCase","parameters":[{"name":"slug","in":"path","description":"the prompt's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the test case","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePromptTestCaseRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PromptTestCase"}}}}},"security":[{"platformKey":[]}]}},"/v1/prompts/{slug}/test-cases/run":{"post":{"tags":["Prompts"],"summary":"Run a prompt's test cases","description":"Run a prompt's test cases.\n\nRenders the prompt's default version (the `production` label, else the PUBLISHED version, else the highest version) with each test case's variables and sends it to the model on the given virtual key, one test case after another. A test case passes when its answer matches its `expected_pattern` (a regular expression, any case; plain text when it is not a valid one), or has no pattern. Each call is billed to the virtual key. A test case whose call fails is reported as failed with its error; the run itself still succeeds. Requires an admin of the prompt's workspace, or an organization admin.\n\nErrors: 400 when the virtual key is unknown or not usable in the prompt's workspace, or the version has no model and no `model_override` is given; 404 when the prompt has no versions.","operationId":"runTestSuite","parameters":[{"name":"slug","in":"path","description":"the prompt's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the virtual key, and an optional model override","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunTestSuiteRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TestRunResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/prompts/{slug}/render":{"post":{"tags":["Prompts"],"summary":"Render a prompt","description":"Render a prompt.\n\nFills a version's `{{name`}} placeholders with the given variables and returns the messages, without calling a model. A placeholder with no value is left as written. Requires membership of the prompt's workspace (organization admins have it).\n\nErrors: 400 for an invalid `version_ref`; 404 when the prompt, version or label does not exist, or the prompt has no default version and none is named.","operationId":"renderPrompt","parameters":[{"name":"slug","in":"path","description":"the prompt's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"the variables, and which version to render","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderPromptRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RenderPromptResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/prompts/{slug}/completions":{"post":{"tags":["Prompts"],"summary":"Run a prompt","description":"Run a prompt.\n\nRenders a version of the prompt with the given variables and sends it to the model as a chat completion, with the version's model (or `model_override`), `temperature`, `max_tokens`, `top_p` and `stop`. The answer is a chat completion, as from `POST /v1/chat/completions`; with `stream: true` it is a stream of server-sent events, each a `chat.completion.chunk`, ending with `data: [DONE]`. The request is logged and billed like any chat completion on the key, and attributed to the prompt and version for its analytics.\n\nAuthenticate with a virtual key (`Authorization: Bearer <api_key>` or `x-virtual-key`); the prompt is looked up in the key's organization. A key bound to a workspace runs that workspace's prompts and the organization-level ones; another workspace's prompt is a 404. The response cache, guardrails and routing configs apply through their headers; the `x-retry-*` and `x-fallback-*` headers are not read. Response headers: `x-cache-status`, `x-retry-count`, `x-virtual-key-slug`, `x-fallback-provider` when a fallback answered, and `x-guardrail-status` when a guardrail applied.\n\nErrors: 400 for an invalid `version_ref`, or when the version has no model and no `model_override` is given; 401 for a missing or invalid virtual key; 404 when the prompt, version or label does not exist, or the prompt has no default version and none is named; 422 when a guardrail blocks the request (`x-guardrail-status: BLOCK`). Provider errors are returned as on `/v1/chat/completions`.","operationId":"promptCompletion","parameters":[{"name":"slug","in":"path","description":"the prompt's slug","required":true,"schema":{"type":"string"}},{"name":"x-cache-mode","in":"header","description":"Turns on the response cache for this request: `simple` (exact match) or `semantic` (a similar earlier request). Without it nothing is read from or written to the cache. The outcome is in the `x-cache-status` response header.","required":false,"schema":{"type":"string"}},{"name":"x-cache-ttl","in":"header","description":"How long, in seconds, a response stored by this request stays in the cache. When the organization has a cache TTL set, this can shorten it but not extend it.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-cache-force-refresh","in":"header","description":"`true` skips the cache lookup, calls the provider and replaces the stored response (`x-cache-status: REFRESH`).","required":false,"schema":{"type":"boolean"}},{"name":"x-guardrail","in":"header","description":"A guardrail slug (`gr-...`) to apply to this request, in addition to any the virtual key carries. A BLOCK is a 422 with `x-guardrail-status: BLOCK`.","required":false,"schema":{"type":"string"}},{"name":"x-config","in":"header","description":"A routing config slug: the config chooses the provider, model and key (load balancing, fallback or conditional routing). Without a virtual key, send `x-organization` with it to name the config's organization.","required":false,"schema":{"type":"string"}}],"requestBody":{"description":"the variables, the version and the streaming option","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromptCompletionRequest"}}},"required":true},"responses":{"200":{"description":"The model's answer, as a chat completion or, with `stream: true`, a stream of chat completion chunks.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionResponse"}},"text/event-stream":{"schema":{"type":"string"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}]}},"/v1/organizations/{organization}/members":{"get":{"tags":["Organization"],"summary":"List organization members","description":"List organization members.\n\nReturns every member of the organization with their organization role, including pending invitations (people invited by email who have not signed in yet, `is_pending: true`). The list is not paginated.\n\nRequires membership of the organization: a signed-in member, or an organization-scoped `va_` key of it. Anyone else gets 403.","operationId":"listOrgMembers","parameters":[{"name":"organization","in":"path","description":"the organization's slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OrgMemberListResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/messages":{"post":{"tags":["Claude Messages"],"summary":"Create a message","description":"Create a message.\n\nDrop-in compatible with Anthropic's Messages API: the body is a Messages request and the answer a Messages response, in Anthropic's format. With an Anthropic or Claude on Vertex key the request goes to Claude as sent (apart from what the gateway sets: the model the key allows, guardrail redactions); with a key for another provider it is translated, and a field that provider cannot take is a 400 naming it. Server tools, `mcp_servers` and `container` are not supported (400).\n\n**Credentials**, in this order: `x-virtual-key`; `Authorization: Bearer vk-...`; `x-config` (a routing config, with `x-organization`); `x-api-key`, which is what the Claude SDKs send from `ANTHROPIC_API_KEY`; any other `Authorization: Bearer` token. A value starting `vk-` is a virtual key's API key; anything else is the provider's own key (Anthropic, unless `x-provider` names another provider). No credential is a 401.\n\n**What the gateway adds** is the same as on chat completions: the response cache (`x-cache-mode`), retries and fallbacks (`x-retry-*`, `x-fallback-*`), and guardrails (the virtual key's plus `x-guardrail`) on the input and the answer. The response carries `x-cache-status`, `x-retry-count`, `x-fallback-provider` (when a fallback answered), `x-virtual-key-slug` and `x-guardrail-status` (when guardrails apply). `anthropic-beta` is forwarded to Anthropic and Claude on Vertex.\n\n**Streaming.** With `stream: true` the response is `text/event-stream` with Anthropic's events (`message_start`, `content_block_start`, `content_block_delta`, `content_block_stop`, `message_delta`, `message_stop`). A failure after the stream has started ends it with an `error` event.\n\n**Errors** are in Anthropic's shape, `{\"type\":\"error\",\"error\":{\"type\":...,\"message\":...`}}, so the SDK raises the matching exception: 400 for an invalid request, 401 for a missing or invalid credential, 403 when the virtual key is disabled, expired or out of credit or the model is not allowed, 422 when a guardrail blocks (with `x-guardrail-status: BLOCK`), 429 for a rate limit.","operationId":"createMessage","parameters":[{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-cache-mode","in":"header","description":"Turns on the response cache for this request: `simple` (exact match) or `semantic` (a similar earlier request). Without it nothing is read from or written to the cache. The outcome is in the `x-cache-status` response header.","required":false,"schema":{"type":"string"}},{"name":"x-cache-ttl","in":"header","description":"How long, in seconds, a response stored by this request stays in the cache. When the organization has a cache TTL set, this can shorten it but not extend it.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-cache-force-refresh","in":"header","description":"`true` skips the cache lookup, calls the provider and replaces the stored response (`x-cache-status: REFRESH`).","required":false,"schema":{"type":"boolean"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}},{"name":"x-fallback-1-provider","in":"header","description":"The provider to try when the request fails after its retries. Up to five fallbacks, tried in order: `x-fallback-1-*` to `x-fallback-5-*`. The provider that answered is in the `x-fallback-provider` response header.","required":false,"schema":{"type":"string"}},{"name":"x-fallback-1-api-key","in":"header","description":"The API key for fallback 1's provider.","required":false,"schema":{"type":"string"}},{"name":"x-fallback-1-model","in":"header","description":"The model fallback 1 uses. Optional: the request's own model otherwise.","required":false,"schema":{"type":"string"}},{"name":"x-guardrail","in":"header","description":"A guardrail slug (`gr-...`) to apply to this request, in addition to any the virtual key carries. A BLOCK is a 422 with `x-guardrail-status: BLOCK`.","required":false,"schema":{"type":"string"}},{"name":"x-config","in":"header","description":"A routing config slug: the config chooses the provider, model and key (load balancing, fallback or conditional routing). Without a virtual key, send `x-organization` with it to name the config's organization.","required":false,"schema":{"type":"string"}},{"name":"x-organization","in":"header","description":"The organization slug. Required with `x-config`; with a virtual key the key's organization is used.","required":false,"schema":{"type":"string"}},{"name":"x-workspace-id","in":"header","description":"Workspace id (UUID) to attribute the request to in logs and analytics.","required":false,"schema":{"type":"string"}},{"name":"x-metadata","in":"header","description":"A JSON object of your own string key/value pairs, stored with the request's log entry for filtering.","required":false,"schema":{"type":"string"}},{"name":"x-prompt-slug","in":"header","description":"Attributes the request to a prompt from the prompt library, for its analytics.","required":false,"schema":{"type":"string"}},{"name":"x-prompt-version","in":"header","description":"The prompt version the request used, with `x-prompt-slug`.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-vertex-project","in":"header","description":"Google Vertex AI keys only: the GCP project to call, instead of the one stored with the key.","required":false,"schema":{"type":"string"}},{"name":"x-vertex-region","in":"header","description":"Google Vertex AI keys only: the region to call (or `global`), instead of the one stored with the key.","required":false,"schema":{"type":"string"}},{"name":"anthropic-beta","in":"header","description":"Anthropic beta features, comma-separated (for example `context-management-2025-06-27`). Forwarded to Anthropic and Claude on Vertex only; at most 32 names of lower-case letters, digits and dashes.","required":false,"schema":{"type":"string"}}],"requestBody":{"description":"the Messages request, in Anthropic's format","content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"The message. With `stream: true`, a stream of Anthropic Messages events.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicChatResponse"}},"text/event-stream":{"schema":{"type":"string"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}],"x-wire-format":{"name":"Anthropic Messages API","url":"https://docs.anthropic.com/en/api/messages"}}},"/v1/messages/count_tokens":{"post":{"tags":["Claude Messages"],"summary":"Count the tokens in a message","description":"Count the tokens in a message.\n\nCompatible with Anthropic's Count Message Tokens API: the body is a Messages request (without `max_tokens`) and the answer is `{\"input_tokens\": N`}, the input tokens that request would use, from Anthropic's own counter (Anthropic, or Claude on Vertex). Same credentials and virtual key checks as creating a message. Nothing is generated, so nothing is billed or logged, and no cache, retries, fallbacks or guardrails apply.\n\n**Errors** are in Anthropic's shape: 400 for an invalid request, a key for any other provider, or a routing config (`x-config`); 401 for a missing or invalid credential; 403 when the virtual key is disabled, expired or the model is not allowed.","operationId":"countTokens","parameters":[{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-vertex-project","in":"header","description":"Google Vertex AI keys only: the GCP project to call, instead of the one stored with the key.","required":false,"schema":{"type":"string"}},{"name":"x-vertex-region","in":"header","description":"Google Vertex AI keys only: the region to call (or `global`), instead of the one stored with the key.","required":false,"schema":{"type":"string"}},{"name":"anthropic-beta","in":"header","description":"Anthropic beta features, comma-separated (for example `context-management-2025-06-27`). Forwarded to Anthropic and Claude on Vertex only; at most 32 names of lower-case letters, digits and dashes.","required":false,"schema":{"type":"string"}}],"requestBody":{"description":"the Messages request to count, in Anthropic's format","content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}],"x-wire-format":{"name":"Anthropic Count Message Tokens API","url":"https://docs.anthropic.com/en/api/messages-count-tokens"}}},"/v1/messages/batches":{"get":{"tags":["Claude Message Batches"],"summary":"List message batches","description":"List message batches.\n\nCompatible with Anthropic's List Message Batches API: the batches this virtual key created, newest first, each read live from Anthropic, as `{\"data\", \"has_more\", \"first_id\", \"last_id\"`}. A batch deleted at Anthropic directly is left out. Needs a virtual key: with a raw Anthropic key, list batches at Anthropic (400 here).\n\n**Errors** are in Anthropic's shape: 400 for a `limit` outside 1 to 100, both `before_id` and `after_id` set, a non-Anthropic or PLATFORM key, or `x-config`; 401 for a missing or invalid credential; 403 for a disabled or expired key.","operationId":"list","parameters":[{"name":"before_id","in":"query","description":"page cursor: return the batches just before (newer than) this batch id","required":false,"schema":{"type":"string"}},{"name":"after_id","in":"query","description":"page cursor: return the batches just after (older than) this batch id","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"how many batches to return, 1 to 100 (default 20)","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"anthropic-beta","in":"header","description":"Anthropic beta features, comma-separated (for example `context-management-2025-06-27`). Forwarded to Anthropic and Claude on Vertex only; at most 32 names of lower-case letters, digits and dashes.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}],"x-wire-format":{"name":"Anthropic Message Batches API","url":"https://docs.anthropic.com/en/api/listing-message-batches"}},"post":{"tags":["Claude Message Batches"],"summary":"Create a message batch","description":"Create a message batch.\n\nCompatible with Anthropic's Message Batches API: the body is `{\"requests\": [{\"custom_id\",  \"params\"`]}}, where each `params` is a Messages request, and the answer is Anthropic's batch object. At most 100,000 requests; each `custom_id` is 1 to 64 letters, digits, `-` or `_` and unique in the batch; `stream` is not allowed. `results_url` points at this gateway's results endpoint.\n\n**Credentials:** as for creating a message, but only for Anthropic: a virtual key with its own Anthropic key (not a PLATFORM key, since a batch is billed after it runs) or a raw Anthropic key. Claude on Vertex, other providers and routing configs (`x-config`) are a 400.\n\n**Before the batch reaches Anthropic**, with a virtual key: the key is checked for each model the batch uses (status, expiry, model allowlist, rate limits; the batch counts as one request), the plan's limits apply, and every request is checked by the tool-result scan and the input guardrails (the key's plus `x-guardrail`). A BLOCK on any request refuses the whole batch with a 422 naming its `custom_id`; a REDACT is sent redacted. Output guardrails do not run, since Anthropic answers later. The batch is billed to the virtual key, at the batch rate, once it has ended, and attributed to the workspace in `x-workspace-id` (else the key's). With a raw Anthropic key only the tool-result scan runs (no guardrails), and nothing is recorded or billed.\n\n**Errors** are in Anthropic's shape: 400 for an invalid batch (naming `requests[i]`), 401 for a missing or invalid credential, 403 for a disabled or expired key or a model it does not allow, 422 for a guardrail BLOCK, 429 for a rate limit.","operationId":"create","parameters":[{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-guardrail","in":"header","description":"A guardrail slug (`gr-...`) to apply to this request, in addition to any the virtual key carries. A BLOCK is a 422 with `x-guardrail-status: BLOCK`.","required":false,"schema":{"type":"string"}},{"name":"anthropic-beta","in":"header","description":"Anthropic beta features, comma-separated (for example `context-management-2025-06-27`). Forwarded to Anthropic and Claude on Vertex only; at most 32 names of lower-case letters, digits and dashes.","required":false,"schema":{"type":"string"}}],"requestBody":{"description":"the batch: `requests`, each with a `custom_id` and Messages `params`","content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}],"x-wire-format":{"name":"Anthropic Message Batches API","url":"https://docs.anthropic.com/en/api/creating-message-batches"}}},"/v1/messages/batches/{batchId}/cancel":{"post":{"tags":["Claude Message Batches"],"summary":"Cancel a message batch","description":"Cancel a message batch.\n\nCompatible with Anthropic's Cancel Message Batch API: asks Anthropic to stop processing the batch and returns the batch object. Requests already processed are kept and billed; canceled ones are not billed. With a virtual key, only a batch that key created is found; any other id is a 404.\n\n**Errors** are in Anthropic's shape: 400 for a non-Anthropic or PLATFORM key or `x-config`; 401 for a missing or invalid credential; 403 for a disabled or expired key; 404 for an unknown batch.","operationId":"cancel","parameters":[{"name":"batchId","in":"path","description":"the batch id (`msgbatch_...`)","required":true,"schema":{"type":"string"}},{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"anthropic-beta","in":"header","description":"Anthropic beta features, comma-separated (for example `context-management-2025-06-27`). Forwarded to Anthropic and Claude on Vertex only; at most 32 names of lower-case letters, digits and dashes.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}],"x-wire-format":{"name":"Anthropic Message Batches API","url":"https://docs.anthropic.com/en/api/canceling-message-batches"}}},"/v1/mcp-servers":{"get":{"tags":["MCP servers"],"summary":"List MCP servers","description":"List MCP servers.\n\nWith `workspace_id`, the servers of that workspace; without, every server in the organization. Paginated.\n\nWith `workspace_id`, requires an organization admin key or a key of that workspace; without, an organization admin key.","operationId":"list_1","parameters":[{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"Only this workspace's servers (UUID).","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","description":"The page number, starting at 1. Default 1.","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"page_size","in":"query","description":"Servers per page. Default 20, at most 100.","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpServerListResponse"}}}}},"security":[{"platformKey":[]}]},"post":{"tags":["MCP servers"],"summary":"Create an MCP server","description":"Create an MCP server.\n\nCreates a workspace's endpoint on a connector. Agents and MCP clients reach it at the returned `url` (`https://mcp.vectoraxis.ai/s/{slug}`); it uses the connector's URL, credentials and capabilities, and can only narrow them. People may use it by default (`default_user_access: ALLOW`).\n\nRequires an organization admin key, or a workspace admin key for `workspace_id`. Returns 403 when the connector is not available to the workspace, 404 when the connector does not exist, 409 when it is disabled, 400 for an unknown guardrail or one of another workspace. Returns 402 when the organization's plan does not include the MCP Gateway.","operationId":"create_1","requestBody":{"description":"the server to create","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMcpServerRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpServer"}}}}},"security":[{"platformKey":[]}]}},"/v1/mcp-servers/{slug}/test":{"post":{"tags":["MCP servers"],"summary":"Test an MCP server's connection","description":"Test an MCP server's connection.\n\nTests the server's connector, as the connector test does: a failed check is a 200 with `ok: false`.\n\nRequires an organization admin key, or a workspace admin key for the server's workspace. Returns 402 when the organization's plan does not include the MCP Gateway. Returns 404 when the server does not exist in the organization.","operationId":"test","parameters":[{"name":"slug","in":"path","description":"The MCP server's slug (`mcps-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpTestResult"}}}}},"security":[{"platformKey":[]}]}},"/v1/mcp-keys":{"get":{"tags":["MCP keys"],"summary":"List MCP keys","description":"List MCP keys.\n\nA workspace's MCP keys, newest first, revoked ones included. Secrets are never returned, only `key_hint`.\n\nRequires an organization admin key, or a key of that workspace (any role).","operationId":"list_2","parameters":[{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"The workspace (UUID).","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpKeyListResponse"}}}}},"security":[{"platformKey":[]}]},"post":{"tags":["MCP keys"],"summary":"Create an MCP key","description":"Create an MCP key.\n\nCreates a `va_` key for agents to present to the MCP Gateway. It works only there (never on the VectorAxis API), it reaches the MCP servers of its workspace, and it may carry a tool allowlist and its own rate limits. The full key is returned once, in `api_key`; only its hash is stored.\n\nRequires an organization admin key, or a workspace admin key for `workspace_id`. Returns 400 for an invalid or duplicate allowlist entry, or one naming a server outside the workspace. Returns 402 when the organization's plan does not include the MCP Gateway.","operationId":"create_2","requestBody":{"description":"the key to create","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMcpKeyRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpKeyCreated"}}}}},"security":[{"platformKey":[]}]}},"/v1/mcp-keys/{id}/rotate":{"post":{"tags":["MCP keys"],"summary":"Rotate an MCP key","description":"Rotate an MCP key.\n\nIssues a new secret, returned once in `api_key`; the old one stops working at once. The key's ID, name, allowlist and limits stay, so only the secret changes in the agents' configuration. Allowed whatever the plan.\n\nRequires an organization admin key, or a workspace admin key for the key's workspace. Returns 409 when the key is revoked or expired, 404 when it does not exist in the organization.","operationId":"rotate","parameters":[{"name":"id","in":"path","description":"The MCP key's ID (UUID).","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpKeyCreated"}}}}},"security":[{"platformKey":[]}]}},"/v1/mcp-integrations":{"get":{"tags":["MCP integrations"],"summary":"List connectors","description":"List connectors.\n\nWith `workspace_id`, lists the connectors that workspace may use: its own, those shared with every workspace, and organization-level ones enabled for it. Without, lists every connector in the organization. Paginated.\n\nWith `workspace_id`, requires an organization admin key or a key of that workspace; without, an organization admin key.","operationId":"list_3","parameters":[{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"Only the connectors this workspace (UUID) may use.","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","description":"The page number, starting at 1. Default 1.","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"page_size","in":"query","description":"Connectors per page. Default 20, at most 100.","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpIntegrationListResponse"}}}}},"security":[{"platformKey":[]}]},"post":{"tags":["MCP integrations"],"summary":"Create a connector","description":"Create a connector.\n\nRegisters an upstream for the MCP Gateway: an MCP server (`kind: MCP`, the default), a REST API described by an OpenAPI document (`OPENAPI`) or a REST API with hand-declared endpoints (`HTTP`). Credentials (headers, query parameters, OAuth client secret) are stored encrypted and never returned. The URL, spec URL and token endpoint must pass the egress policy (public addresses only). The connector starts with `sync_status: NEVER`: sync it to discover its capabilities. Without `workspace_id` it is an organization-level connector that can be shared with workspaces.\n\nRequires an organization admin key, or a workspace admin key for `workspace_id` (an organization-level connector needs an organization admin). Returns 400 when the settings do not fit together (for example headers with an OAuth auth type, a spec on an `MCP` connector, an unknown guardrail). Returns 402 when the organization's plan does not include the MCP Gateway.","operationId":"create_3","requestBody":{"description":"the connector to create","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMcpIntegrationRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpIntegration"}}}}},"security":[{"platformKey":[]}]}},"/v1/mcp-integrations/{slug}/test":{"post":{"tags":["MCP integrations"],"summary":"Test a connector's connection","description":"Test a connector's connection.\n\nConnects to the upstream with the stored credentials and reports what it is, then disconnects. For an `OAUTH_AUTO` connector it uses the caller's own connected account, else the organization connection. For an `OPENAPI` or `HTTP` connector it reads the spec or the declared endpoints into tools; the API itself is not called. A failed check is a 200 with `ok: false`.\n\nRequires an organization admin key, or a workspace admin key for the owning workspace (an organization-level connector needs an organization admin). (a test sends the stored credentials upstream). Returns 402 when the organization's plan does not include the MCP Gateway. Returns 404 when the connector does not exist in the organization.","operationId":"test_1","parameters":[{"name":"slug","in":"path","description":"The connector's slug (`mcpi-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpTestResult"}}}}},"security":[{"platformKey":[]}]}},"/v1/mcp-integrations/{slug}/sync":{"post":{"tags":["MCP integrations"],"summary":"Sync a connector's capabilities","description":"Sync a connector's capabilities.\n\nLists the upstream's tools, prompts, resources and resource templates (for a REST connector: reads the spec or the declared endpoints) and reconciles them with the stored capabilities. A new capability is pinned at its current definition; after the first sync new capabilities arrive switched off, and every tool of an `OPENAPI` or `HTTP` connector arrives off (and privileged unless it is GET or HEAD). A changed definition is reported as drift and refused on calls until pinned again. Every new definition is scanned for tool poisoning, and a definition with findings is quarantined until an admin releases it. A capability no longer listed is marked `REMOVED`. A failed sync is a 200 with `sync_status: FAILED`; the capabilities from the last good sync are kept.\n\nRequires an organization admin key, or a workspace admin key for the owning workspace (an organization-level connector needs an organization admin). Returns 409 when the connector is disabled. Returns 402 when the organization's plan does not include the MCP Gateway. Returns 404 when the connector does not exist in the organization.","operationId":"sync","parameters":[{"name":"slug","in":"path","description":"The connector's slug (`mcpi-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpSyncResult"}}}}},"security":[{"platformKey":[]}]}},"/v1/mcp-integrations/{slug}/org-connection":{"get":{"tags":["MCP integrations"],"summary":"Get a connector's organization connection","description":"Get a connector's organization connection.\n\nFor an `OAUTH_AUTO` connector: the upstream account an organization admin connected, which agents on an MCP key use. Returns `connected: false` when there is none. Tokens are never returned.\n\nRequires read access to the connector: for a workspace-owned connector, an organization admin key or a key of that workspace; for an organization-level connector, any organization member. Returns 404 when the connector does not exist in the organization.","operationId":"getOrgConnection","parameters":[{"name":"slug","in":"path","description":"The connector's slug (`mcpi-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpOrgConnection"}}}}},"security":[{"platformKey":[]}]},"delete":{"tags":["MCP integrations"],"summary":"Remove a connector's organization connection","description":"Remove a connector's organization connection.\n\nDisconnects the organization's upstream account of an `OAUTH_AUTO` connector. Agents on an MCP key can no longer use the connector until an organization admin connects again.\n\nRequires an organization admin key, whoever owns the connector. Returns 404 when the connector does not exist or has no organization connection.","operationId":"removeOrgConnection","parameters":[{"name":"slug","in":"path","description":"The connector's slug (`mcpi-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"}},"security":[{"platformKey":[]}]}},"/v1/mcp-integrations/spec-preview":{"post":{"tags":["MCP integrations"],"summary":"Preview an OpenAPI document as a connector","description":"Preview an OpenAPI document as a connector.\n\nReads an OpenAPI 3.0 or 3.1 document (from `spec_url`, or given in `spec_content`) and returns what an `OPENAPI` connector would make of it: its title, suggested base URLs, the tools, the operations that would be skipped and the security schemes with the auth type each suggests. Nothing is stored.\n\nWith `workspace_id`, requires a key of that workspace (any role) or an organization admin key; without, any organization member. Returns 400 when the document cannot be read or is not OpenAPI 3.0 or 3.1. Returns 402 when the organization's plan does not include the MCP Gateway.","operationId":"specPreview","requestBody":{"description":"the document to read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpSpecPreviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpSpecPreview"}}}}},"security":[{"platformKey":[]}]}},"/v1/logs/export":{"post":{"tags":["Logs and analytics"],"summary":"Start a log export","description":"Start a log export.\n\nStarts exporting the organization's logs that match the filters, newest first, as CSV or JSON, and returns 202 with the job at once. Poll the job until its status is `DONE`, then download the file. At most `max_rows` rows are exported (default 10,000, at most 50,000). A job and its file are kept for one hour.\n\nRequires an organization owner or admin, or an organization-scoped `va_` key with the admin role. Fails with 400 when `max_rows` is over 50,000.","operationId":"createExportJob","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportJobRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ExportJobResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/images/generations":{"post":{"tags":["Images"],"summary":"Create an image","description":"Create an image.\n\nCompatible with OpenAI's create-image endpoint: the body is forwarded to the provider as sent (with a virtual key, a `provider/` prefix on `model` is removed first) and the generated images are returned. `model` is required (400 without it). OpenAI credentials only; any other provider is a 422.\n\nAuthenticate with a BYOK virtual key or with `x-provider` and `x-api-key`; a PLATFORM virtual key is a 400. The key's checks, the plan's limits and the organization's approved-provider policy (403) apply. The call is priced per image from the model, `size`, `quality` and `n`, and the cost is in the `x-operation-cost-usd` response header. Without `x-retry-count` a failed call is retried up to 3 times on 429 and 5xx.","operationId":"generateImage","parameters":[{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}}],"requestBody":{"description":"the image request, in OpenAI's format","content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ImageGenerationResponse"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}],"x-wire-format":{"name":"OpenAI Images API (create image)","url":"https://platform.openai.com/docs/api-reference/images/create"}}},"/v1/images/edits":{"post":{"tags":["Images"],"summary":"Create an image edit","description":"Create an image edit.\n\nCompatible with OpenAI's create-image-edit endpoint: send one or more source images and a prompt as `multipart/form-data` and get the edited images back. Send a single image as `image`, or several (up to 16) as repeated `image[]` parts, as the OpenAI SDKs do for a list. Each image must have an `image/*` content type. `model`, `prompt` and at least one image are required, and `n` must be an integer; otherwise a 400. OpenAI credentials only; any other provider is a 422.\n\nAuthenticate with a BYOK virtual key or with `x-provider` and `x-api-key`; a PLATFORM virtual key is a 400. The key's checks, the plan's limits and the organization's approved-provider policy (403) apply. Without `x-retry-count` a failed call is retried up to 3 times on 429 and 5xx.","operationId":"editImage","parameters":[{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"image":{"type":"string","format":"binary","description":"The image to edit. Send several as repeated `image[]` parts instead."},"image[]":{"type":"string","format":"binary","description":"One of several images to edit (gpt-image models, up to 16)."},"mask":{"type":"string","format":"binary","description":"Optional mask whose fully transparent areas mark where the image is edited."},"prompt":{"type":"string","description":"A text description of the edit."},"model":{"type":"string","description":"The image model, for example `gpt-image-1` or `dall-e-2`."},"n":{"type":"integer","description":"How many images to generate. Optional; the provider's default otherwise."},"size":{"type":"string","description":"The size of the generated images, for example `1024x1024`. Optional."},"response_format":{"type":"string","description":"`url` or `b64_json`: how the images are returned. Optional."}}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ImageGenerationResponse"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}]}},"/v1/guardrails":{"get":{"tags":["Guardrails"],"summary":"List guardrails","description":"List guardrails.\n\nReturns a page of the organization's guardrails, without their checks. With `workspace_id` the list holds that workspace's guardrails and needs membership of the workspace; without it the list covers the whole organization and needs an organization admin.","operationId":"list_4","parameters":[{"name":"organization","in":"query","description":"slug of the organization","required":true,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"id (UUID) of a workspace, to list only its guardrails","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"enabled","in":"query","description":"not applied at present: guardrails are listed whether enabled or not","required":false,"schema":{"type":"boolean"}},{"name":"search","in":"query","description":"only guardrails whose name contains this text (case-sensitive)","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"page number, from 1. Default 1","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"page_size","in":"query","description":"guardrails per page. Default 20, at most 100","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GuardrailListResponse"}}}}},"security":[{"platformKey":[]}]},"post":{"tags":["Guardrails"],"summary":"Create a guardrail","description":"Create a guardrail.\n\nCreates a guardrail in a workspace and returns it with a new slug (`gr-...`). Each check names a validator from `GET /v1/guardrail-validators` and its settings. Requires an organization admin, or an admin of the workspace in `workspace_id`.\n\nErrors: 400 when a check's `type` is not a validator id or its `config` is rejected; 402 when the plan's guardrail limit for the workspace is reached, or a check uses an `LLM_JUDGE` validator on a plan without AI guardrails; 403 without access; 409 when the organization already has a guardrail with this name.","operationId":"create_4","requestBody":{"description":"the guardrail to create","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGuardrailRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GuardrailDetail"}}}}},"security":[{"platformKey":[]}]}},"/v1/guardrails/{slug}/enable":{"post":{"tags":["Guardrails"],"summary":"Enable a guardrail","description":"Enable a guardrail.\n\nTurns the guardrail on, so its checks run wherever it is applied. Enabling an enabled guardrail changes nothing. Requires an admin of the guardrail's workspace, or an organization admin. 404 when the guardrail does not exist.","operationId":"enable","parameters":[{"name":"slug","in":"path","description":"the guardrail's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GuardrailDetail"}}}}},"security":[{"platformKey":[]}]}},"/v1/guardrails/{slug}/disable":{"post":{"tags":["Guardrails"],"summary":"Disable a guardrail","description":"Disable a guardrail.\n\nTurns the guardrail off without detaching it: requests that apply it skip its checks (status `BYPASS` when no other guardrail runs). Disabling a disabled guardrail changes nothing. Requires an admin of the guardrail's workspace, or an organization admin. 404 when the guardrail does not exist.","operationId":"disable","parameters":[{"name":"slug","in":"path","description":"the guardrail's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GuardrailDetail"}}}}},"security":[{"platformKey":[]}]}},"/v1/files":{"get":{"tags":["Files"],"summary":"List files","description":"List files.\n\nLists the files uploaded with your virtual key, a page at a time. Requires a virtual key: with direct provider credentials this is a 400. A PLATFORM virtual key is a 400.","operationId":"listFiles","parameters":[{"name":"purpose","in":"query","description":"only files with this purpose (`batch`, `fine-tune`, `assistants`, `vision`); all files when omitted","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"the page number, starting at 1; default 1","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"page_size","in":"query","description":"files per page; default 20, at most 100","required":false,"schema":{"type":"integer","format":"int32","default":20}},{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/FileListResponse"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}]},"post":{"tags":["Files"],"summary":"Upload a file","description":"Upload a file.\n\nCompatible with OpenAI's upload-file endpoint: send the file as `multipart/form-data`. The file is uploaded to the provider and recorded against your virtual key, and the response carries its VectorAxis id (`vxf-...`), which batch jobs, the Responses API and chat `file` parts accept in place of the provider's id. Returns 201.\n\nAccepted content types are common image, document (PDF, text, CSV, Markdown, HTML, Word, Excel), audio, video and JSONL types and `application/octet-stream`; any other is a 400. Size limits by `purpose`: `fine-tune` 512 MB, `batch` 500 MB, anything else 20 MB (400 when exceeded).\n\nAuthenticate with a BYOK virtual key or with `x-provider` and `x-api-key`; a PLATFORM virtual key is a 400. OpenAI credentials only; any other provider is a 422. The key's checks, the plan's limits and the organization's approved-provider policy (403) apply. Without `x-retry-count` a failed upload is retried up to 3 times on 429 and 5xx.","operationId":"uploadFile","parameters":[{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"the file to upload"},"purpose":{"type":"string","description":"what the file is for: `batch`, `fine-tune`, `assistants` or `vision`; `assistants` when\n                omitted"}},"required":["file"]}}}},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VectorAxisFile"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}]}},"/v1/embeddings":{"post":{"tags":["Embeddings"],"summary":"Create embeddings","description":"Create embeddings.\n\nCompatible with OpenAI's Embeddings API: send the same body to the same path and get OpenAI's response back. The provider is the one behind your credential. With a Cohere key the request is translated to Cohere's Embed API and the answer back to OpenAI's shape (a token-array `input` is a 400); a Voyage AI key goes to Voyage's own endpoint, which takes the same shape (Voyage's own fields such as `input_type` pass through); Azure OpenAI and other OpenAI-compatible providers receive the body as sent. A provider without an embeddings API (Anthropic, Vertex AI, TypeSafe) is a 422.\n\nAuthenticate with a virtual key (BYOK or PLATFORM) or with `x-provider` and `x-api-key`. With a virtual key a `provider/` prefix on `model` is removed before the call. The key's status, model allowlist and rate limits and the plan's limits apply, and an organization that restricts its approved providers gets a 403 for a provider it has not approved. INPUT guardrails (the key's and `x-guardrail`) run over every text to embed; a REDACT changes what is embedded and a BLOCK is a 422. The response cache is exact-match only: `x-cache-mode: simple` serves an identical earlier request from the cache, at no cost, and `semantic` is not used (`x-cache-status: BYPASS`).\n\nYou are charged for the input tokens at the model's input rate; the cost is in the `x-operation-cost-usd` response header (`0.0` on a cache hit, with the saving in `x-cache-saved-usd`). Without `x-retry-count` a failed provider call is retried up to 3 times on 429 and 5xx. A provider error is returned unchanged: its status, body and `Retry-After`. A request without `model` is a 400.","operationId":"embeddings","parameters":[{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-cache-mode","in":"header","description":"Turns on the response cache for this request: `simple` (exact match) or `semantic` (a similar earlier request). Without it nothing is read from or written to the cache. The outcome is in the `x-cache-status` response header.","required":false,"schema":{"type":"string"}},{"name":"x-cache-ttl","in":"header","description":"How long, in seconds, a response stored by this request stays in the cache. When the organization has a cache TTL set, this can shorten it but not extend it.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-cache-force-refresh","in":"header","description":"`true` skips the cache lookup, calls the provider and replaces the stored response (`x-cache-status: REFRESH`).","required":false,"schema":{"type":"boolean"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}},{"name":"x-guardrail","in":"header","description":"A guardrail slug (`gr-...`) to apply to this request, in addition to any the virtual key carries. A BLOCK is a 422 with `x-guardrail-status: BLOCK`.","required":false,"schema":{"type":"string"}},{"name":"x-request-timeout-ms","in":"header","description":"How long to wait for the provider, in milliseconds, before giving up (at most 3600000, one hour).","required":false,"schema":{"type":"integer","format":"int32"}}],"requestBody":{"description":"the embeddings request, in OpenAI's format","content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}],"x-wire-format":{"name":"OpenAI Embeddings API","url":"https://platform.openai.com/docs/api-reference/embeddings/create"}}},"/v1/decisions":{"post":{"tags":["Decisions"],"summary":"Create a decision","description":"Create a decision.\n\nCompatible with OpenAI's Decisions API: the body is forwarded to OpenAI as sent and OpenAI's answer is returned as is. A request without `model` is a 400. With a virtual key a `provider/` prefix on `model` is removed before the call.\n\nAuthenticate with an OpenAI virtual key (BYOK or PLATFORM) or with `x-provider: openai` and `x-api-key`; any other provider is a 422. The key's checks, the plan's limits and the organization's approved-provider policy (403) apply. Tool outputs in `input` (`function_call_output`, `custom_tool_call_output`) are scanned for injected instructions at the key's tool-scan action: a BLOCK is a 422 with `x-tool-scan-status: BLOCK` and nothing is sent. INPUT guardrails (the key's and `x-guardrail`) run over every text the model reads, including each question's `instructions`; a REDACT rewrites the text and a BLOCK is a 422. You are charged for the input tokens only, cached input at the model's cache rates. Without `x-retry-count` a failed call is retried up to 3 times on 429 and 5xx. OpenAI's own errors are returned unchanged: status, body and `Retry-After`.","operationId":"decide_1","parameters":[{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}},{"name":"x-guardrail","in":"header","description":"A guardrail slug (`gr-...`) to apply to this request, in addition to any the virtual key carries. A BLOCK is a 422 with `x-guardrail-status: BLOCK`.","required":false,"schema":{"type":"string"}}],"requestBody":{"description":"the decision request, in OpenAI's format","content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}],"x-wire-format":{"name":"OpenAI Decisions API","url":"https://platform.openai.com/docs/api-reference/decisions"}}},"/v1/configs":{"get":{"tags":["Routing configs"],"summary":"List routing configs","description":"List routing configs.\n\nLists an organization's configs, or one workspace's, a page at a time, as summaries (without their targets). Get a config for its full target tree.\n\nRequires a workspace key (member or admin) for `workspace_id` when it is given, or an organization admin key; an organization-wide list (no `workspace_id`) requires an organization admin key. 403 otherwise.","operationId":"list_5","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"only configs in this workspace (UUID); omit for every config in the organization","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"search","in":"query","description":"only configs whose name contains this text","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"the page number, starting at 1 (default 1)","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"page_size","in":"query","description":"configs per page (default 20, at most 100)","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RoutingConfigListResponse"}}}}},"security":[{"platformKey":[]}]},"post":{"tags":["Routing configs"],"summary":"Create a routing config","description":"Create a routing config.\n\nCreates a config in a workspace and answers it with its generated slug (the name in lower case, with a random suffix). The config is validated as by \"Validate a routing config\" before it is saved.\n\nRequires an organization admin key, or a workspace admin key for `workspace_id`.\n\nErrors: 400 when a required field is missing; 403 without the required role; 409 when the organization already has a config with this `name`; 422 when the config is not valid (the message lists each problem with its path, e.g. `[targets[0].weight] Weight must be greater than 0`).","operationId":"create_5","requestBody":{"description":"the config to create","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoutingConfigRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RoutingConfigDetail"}}}}},"security":[{"platformKey":[]}]}},"/v1/configs/validate":{"post":{"tags":["Routing configs"],"summary":"Validate a routing config","description":"Validate a routing config.\n\nChecks a config without saving it, with the same rules as create and update, and answers whether it is valid. Problems are reported with a 200 and `valid: false`, not as an error status: `errors` then holds one entry whose message lists each problem with its path.\n\nThe rules:\n\n- At least one target; a CONDITIONAL strategy needs at least one condition.\n- Each target is either a leaf (`virtual_key_slug`) or a nested strategy (`strategy_mode` with its own `targets`), never both and never neither. Strategies nest at most 3 levels below the top.\n- `weight`, when set, is greater than 0; `retry.attempts` is from 1 to 10.\n- `override_params`: `temperature` 0 to 2, `top_p` 0 to 1, `max_tokens` at least 1, `frequency_penalty` and `presence_penalty` -2 to 2, `seed` at least 0.\n- Every condition's `then_target_name` names a target at its level; in a nested CONDITIONAL target, `conditional_default_target_name` names one of its targets too.\n- A condition's `query` is not empty and uses only `metadata.*` and `params.*` fields (`params.model`, `temperature`, `max_tokens`, `top_p`, `stream`), the operators `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$in`, `$nin`, `$regex` and `$exists`, and `$and` / `$or` arrays of such queries.\n- Every virtual key exists in `organization` and is not `EXPIRED`. A key of another organization is reported exactly as one that does not exist.\n\nRequires membership of `organization`, or of the workspace named by `workspace_id`; anyone else gets 403. A body without `organization` is a 400.","operationId":"validate","requestBody":{"description":"the config to check","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoutingConfigValidateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RoutingConfigValidateResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/chat/completions":{"post":{"tags":["Chat completions"],"summary":"Create a chat completion","description":"Create a chat completion.\n\nDrop-in compatible with OpenAI's Chat Completions API: the body is an OpenAI chat request and the answer an OpenAI chat completion, whichever provider serves it. Fields the schema does not list are passed on to the provider as sent.\n\n**Credentials**, one of: a virtual key's API key as `Authorization: Bearer vk-...` (what the OpenAI SDK sends) or in `x-virtual-key`; direct credentials, the provider's own key in `x-api-key` with the provider named in `x-provider`; or a routing config slug in `x-config` with `x-organization`, which chooses the provider, model and key. With a virtual key, an `x-provider` that does not match the key's provider is a 400.\n\n**What the gateway adds:** the response cache (`x-cache-mode`, off unless sent), retries and a fallback chain (`x-retry-*`, `x-fallback-*`), and guardrails: those the virtual key carries plus any named in `x-guardrail`, run on the input before the provider call and on the answer after it. The response carries `x-cache-status` (`HIT`, `SEMANTIC_HIT`, `MISS`, `REFRESH`, `BYPASS` or `DISABLED`) and `x-retry-count` (retries made); `x-fallback-provider` names the fallback provider that answered, when one did; `x-virtual-key-slug` names the virtual key that served the request; and `x-guardrail-status` gives the guardrails' outcome (`PASS`, `REDACT`, `MONITOR` or `BYPASS`) when guardrails apply.\n\n**Streaming.** With `stream: true` the response is `text/event-stream`: one `data:` event per OpenAI `chat.completion.chunk`, then `data: [DONE]`. Retries and fallbacks apply until the first chunk is sent, and a cache hit is replayed as chunks. A failure after the first chunk (a provider error mid-answer, or an output guardrail BLOCK) ends the stream with an `error` chunk followed by `[DONE]`. On a stream, `x-guardrail-status` reports the input checks only.\n\n**Errors:** 400 for a malformed body or message content, missing credentials, or an invalid `anthropic-beta` value; 401 for an invalid virtual key; 403 when the virtual key is disabled, expired or out of credit, or the model or provider is not allowed for it; 422 when a guardrail blocks the request or the answer (with `x-guardrail-status: BLOCK`); 429 when a rate limit is reached.","operationId":"chatCompletions","parameters":[{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-cache-mode","in":"header","description":"Turns on the response cache for this request: `simple` (exact match) or `semantic` (a similar earlier request). Without it nothing is read from or written to the cache. The outcome is in the `x-cache-status` response header.","required":false,"schema":{"type":"string"}},{"name":"x-cache-ttl","in":"header","description":"How long, in seconds, a response stored by this request stays in the cache. When the organization has a cache TTL set, this can shorten it but not extend it.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-cache-force-refresh","in":"header","description":"`true` skips the cache lookup, calls the provider and replaces the stored response (`x-cache-status: REFRESH`).","required":false,"schema":{"type":"boolean"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}},{"name":"x-fallback-1-provider","in":"header","description":"The provider to try when the request fails after its retries. Up to five fallbacks, tried in order: `x-fallback-1-*` to `x-fallback-5-*`. The provider that answered is in the `x-fallback-provider` response header.","required":false,"schema":{"type":"string"}},{"name":"x-fallback-1-api-key","in":"header","description":"The API key for fallback 1's provider.","required":false,"schema":{"type":"string"}},{"name":"x-fallback-1-model","in":"header","description":"The model fallback 1 uses. Optional: the request's own model otherwise.","required":false,"schema":{"type":"string"}},{"name":"x-guardrail","in":"header","description":"A guardrail slug (`gr-...`) to apply to this request, in addition to any the virtual key carries. A BLOCK is a 422 with `x-guardrail-status: BLOCK`.","required":false,"schema":{"type":"string"}},{"name":"x-config","in":"header","description":"A routing config slug: the config chooses the provider, model and key (load balancing, fallback or conditional routing). Without a virtual key, send `x-organization` with it to name the config's organization.","required":false,"schema":{"type":"string"}},{"name":"x-organization","in":"header","description":"The organization slug. Required with `x-config`; with a virtual key the key's organization is used.","required":false,"schema":{"type":"string"}},{"name":"x-workspace-id","in":"header","description":"Workspace id (UUID) to attribute the request to in logs and analytics.","required":false,"schema":{"type":"string"}},{"name":"x-metadata","in":"header","description":"A JSON object of your own string key/value pairs, stored with the request's log entry for filtering.","required":false,"schema":{"type":"string"}},{"name":"x-prompt-slug","in":"header","description":"Attributes the request to a prompt from the prompt library, for its analytics.","required":false,"schema":{"type":"string"}},{"name":"x-prompt-version","in":"header","description":"The prompt version the request used, with `x-prompt-slug`.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-vertex-project","in":"header","description":"Google Vertex AI keys only: the GCP project to call, instead of the one stored with the key.","required":false,"schema":{"type":"string"}},{"name":"x-vertex-region","in":"header","description":"Google Vertex AI keys only: the region to call (or `global`), instead of the one stored with the key.","required":false,"schema":{"type":"string"}},{"name":"anthropic-beta","in":"header","description":"Anthropic beta features, comma-separated (for example `context-management-2025-06-27`). Forwarded to Anthropic and Claude on Vertex only; at most 32 names of lower-case letters, digits and dashes.","required":false,"schema":{"type":"string"}}],"requestBody":{"description":"the chat completion request, in OpenAI's format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionRequest"}}},"required":true},"responses":{"200":{"description":"The completion. With `stream: true`, a stream of `chat.completion.chunk` events ending with `[DONE]`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionResponse"}},"text/event-stream":{"schema":{"type":"string"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}]}},"/v1/batches":{"get":{"tags":["Batches"],"summary":"List batches","description":"List batches.\n\nCompatible with OpenAI's list-batches endpoint, newest first with cursor pagination. With a virtual key, the batches that key created, each read live from the provider (`limit` 1 to 100); with `x-provider` and `x-api-key`, the provider account's own list (`after` and `limit` passed through).\n\nAuthenticate with a BYOK virtual key or with `x-provider` and `x-api-key`; a PLATFORM virtual key is a 400. OpenAI credentials only; any other provider is a 422. Without `x-retry-count` a failed call is retried up to 3 times on 429 and 5xx.","operationId":"listBatches","parameters":[{"name":"after","in":"query","description":"a batch id from a previous page: the list starts after it; omit for the first page","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"how many batches to return; default 20","required":false,"schema":{"type":"integer","format":"int32","default":20}},{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/BatchListResponse"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}]},"post":{"tags":["Batches"],"summary":"Create a batch","description":"Create a batch.\n\nCompatible with OpenAI's create-batch endpoint: starts a batch job at the provider over the requests in an uploaded JSONL file. `input_file_id` may be the VectorAxis id (`vxf-...`) of a file uploaded with the same virtual key; it is replaced by the provider's file id. Returns the batch as the provider reports it, with `input_file_id` answered as your `vxf-...` id. With a virtual key, the batch belongs to that key: only it can list, read, cancel or download it.\n\nAuthenticate with a BYOK virtual key or with `x-provider` and `x-api-key`; a PLATFORM virtual key is a 400. OpenAI credentials only; any other provider is a 422. Without `x-retry-count` a failed call is retried up to 3 times on 429 and 5xx. The key's checks, the plan's limits and the organization's approved-provider policy (403) apply.","operationId":"createBatch","parameters":[{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}}],"requestBody":{"description":"the batch to create","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBatchRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/BatchObject"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}]}},"/v1/batches/{id}/cancel":{"post":{"tags":["Batches"],"summary":"Cancel a batch","description":"Cancel a batch.\n\nCompatible with OpenAI's cancel-batch endpoint: asks the provider to cancel an in-progress batch. The returned batch shows its new status (`cancelling`, then `cancelled`). With a virtual key, only batches that key created are reachable; any other batch id is a 404.\n\nAuthenticate with a BYOK virtual key or with `x-provider` and `x-api-key`; a PLATFORM virtual key is a 400. OpenAI credentials only; any other provider is a 422. Without `x-retry-count` a failed call is retried up to 3 times on 429 and 5xx.","operationId":"cancelBatch","parameters":[{"name":"id","in":"path","description":"the provider's batch id, for example `batch_...`","required":true,"schema":{"type":"string"}},{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/BatchObject"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}]}},"/v1/audio/translations":{"post":{"tags":["Audio"],"summary":"Create a translation","description":"Create a translation.\n\nCompatible with OpenAI's create-translation endpoint: upload an audio file as `multipart/form-data` and get its English translation back as text. Supported on OpenAI and OpenAI-compatible providers and on Sarvam; another provider is a 501. The file must have an `audio/*` content type and be at most 25 MB, else a 400.\n\nAuthenticate with a BYOK virtual key or with `x-provider` and `x-api-key`; a PLATFORM virtual key is a 400. The key's checks, the plan's limits and the organization's approved-provider policy (403) apply. Without `x-retry-count` a failed call is retried up to 3 times on 429 and 5xx.","operationId":"createTranslation","parameters":[{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"the file to upload"},"model":{"type":"string","description":"the model, for example `whisper-1` or `gpt-4o-transcribe`"},"prompt":{"type":"string","description":"text to guide the model's style or continue a previous segment; optional"},"response_format":{"type":"string","description":"`json` (the default) or `verbose_json`, which adds the language, duration, segments and\n                       words (transcriptions only)"},"temperature":{"type":"string","description":"sampling temperature from 0 to 1; optional"}},"required":["file","model"]}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TranslationResponse"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}]}},"/v1/audio/transcriptions":{"post":{"tags":["Audio"],"summary":"Create a transcription","description":"Create a transcription.\n\nCompatible with OpenAI's create-transcription endpoint: upload an audio file as `multipart/form-data` and get its text back. The provider is the one behind your credential; Sarvam and ElevenLabs answers are returned in the same shape. The file must have an `audio/*` content type and be at most 25 MB (1 GB on ElevenLabs), else a 400. With `stream=true` the response is a `text/event-stream` of the provider's transcription events (OpenAI only; another provider is a 501).\n\nAuthenticate with a BYOK virtual key or with `x-provider` and `x-api-key`; a PLATFORM virtual key is a 400. The key's checks, the plan's limits and the organization's approved-provider policy (403) apply. The call is priced on the audio's duration (the `audio_duration_seconds` you send, else the duration the provider reports) and the cost is in the `x-operation-cost-usd` response header. Without `x-retry-count` a failed call is retried up to 3 times on 429 and 5xx; a stream is not retried.","operationId":"createTranscription","parameters":[{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"the file to upload"},"model":{"type":"string","description":"the model, for example `whisper-1` or `gpt-4o-transcribe`"},"language":{"type":"string","description":"the audio's language as an ISO-639-1 code, for example `en`; optional"},"prompt":{"type":"string","description":"text to guide the model's style or continue a previous segment; optional"},"response_format":{"type":"string","description":"`json` (the default) or `verbose_json`, which adds the language, duration, segments and\n                       words (transcriptions only)"},"temperature":{"type":"string","description":"sampling temperature from 0 to 1; optional"},"timestamp_granularities":{"type":"string","description":"`word` or `segment`, with `verbose_json`: the timestamps to include"},"audio_duration_seconds":{"type":"string","description":"the audio's length in seconds, used to price the call when the provider does not\n                               report it (always on a stream); optional"},"stream":{"type":"string","description":"`true` to stream the transcription as server-sent events; default false"}},"required":["file","model"]}}}},"responses":{"200":{"description":"The transcription, or a stream of transcription events with stream=true","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TranscriptionResponse"}},"text/event-stream":{"schema":{"type":"string"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}]}},"/v1/audio/speech":{"post":{"tags":["Audio"],"summary":"Create speech","description":"Create speech.\n\nCompatible with OpenAI's create-speech endpoint: send `model`, `input` (the text) and `voice` and get the audio back as a binary body. Its content type follows `response_format`: `mp3` (the default, `audio/mpeg`), `opus`, `aac`, `flac`, `wav` or `pcm`. Sarvam always answers in WAV. The body is forwarded to OpenAI and OpenAI-compatible providers as sent, and translated for Sarvam and ElevenLabs.\n\nAuthenticate with a BYOK virtual key or with `x-provider` and `x-api-key`; a PLATFORM virtual key is a 400. The key's checks, the plan's limits and the organization's approved-provider policy (403) apply. The call is priced on the length of `input` and the cost is in the `x-operation-cost-usd` response header. This call is not retried.","operationId":"createSpeech","parameters":[{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}}],"requestBody":{"description":"the speech request, in OpenAI's format","content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"The generated audio, in the requested format","content":{"audio/mpeg":{"schema":{"type":"string","format":"binary"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}],"x-wire-format":{"name":"OpenAI Audio API (create speech)","url":"https://platform.openai.com/docs/api-reference/audio/createSpeech"}}},"/v1/api-keys":{"get":{"tags":["API keys"],"summary":"List platform API keys","description":"List platform API keys.\n\nReturns the organization's management keys (never the secret, only `key_hint`), revoked ones included. With `workspace_id`: the keys scoped to that workspace plus the organization-scoped keys, which also act in it. Not paginated.\n\nWith `workspace_id`, requires access to that workspace: an organization owner or admin, a member of the workspace, an organization-scoped `va_` key with the admin role, or a `va_` key scoped to the workspace. Without it, requires an organization owner or admin, or an organization-scoped `va_` key with the admin role.","operationId":"listKeys","parameters":[{"name":"organization","in":"query","description":"the organization's slug","required":true,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"a workspace id (UUID) to limit the list to the keys that act in that workspace","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlatformApiKeyListResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/virtual-keys/tool-scan-settings":{"get":{"tags":["Virtual keys"],"summary":"List virtual keys with their own tool-scan action","description":"List virtual keys with their own tool-scan action.\n\nThe tool-result scan checks the tool results your application sends back to the model (tool-role messages) for injected instructions. A key uses the platform default action unless it sets its own. This answers the default (`default_action`) and every key of the organization, or of one workspace, that sets its own action; a key not listed uses the default.\n\nRequires a workspace key (member or admin) for `workspace_id` when it is given, or an organization admin key; an organization-wide list requires an organization admin key. 403 otherwise.","operationId":"listToolScan","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"only keys in this workspace (UUID); omit for the whole organization","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ToolScanSettingsListResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/trust/subprocessors":{"get":{"tags":["Trust Pack"],"summary":"Get the sub-processor report","description":"Get the sub-processor report.\n\nLists every party your organization's AI data reached in the window, or can reach through its configuration: model providers (one entry per legal entity, with the models used and the provider's published data terms), tool servers your agents called through the MCP Gateway, and the services VectorAxis itself runs on. Each entry is `OBSERVED` (it received data in the window) or `CONFIGURED` (it is set up, through a virtual key, an MCP integration or a guardrail, but received nothing in the window). Requests answered from the response cache are not counted.\n\nThe window defaults to the 90 days up to now and can be at most 366 days long. Without `workspace_id` the report covers the whole organization and requires an organization owner or admin; with it, the report covers that workspace and any member of the workspace may call it.\n\nErrors: 400 when `start_time` is not before `end_time` or the window is longer than 366 days; 402 when the organization's plan does not include the AI Trust Pack; 403 without the access above.","operationId":"subprocessors","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"limit the report to this workspace (UUID); omit for the whole organization","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"start_time","in":"query","description":"start of the window, ISO 8601 date-time; default 90 days before `end_time`","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"end_time","in":"query","description":"end of the window, ISO 8601 date-time; default now","required":false,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrustSubprocessorsResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/trust/questionnaire":{"get":{"tags":["Trust Pack"],"summary":"Get the AI questionnaire","description":"Get the AI questionnaire.\n\nAbout 40 questions buyers commonly ask an AI vendor in a security review, grouped by category, each with its answer. Where the records can answer, the answer is generated when you read it, from the organization-wide reports for the trailing 90 days and the organization's settings, so it is never stale. Your own written answer replaces the generated one; questions with neither are `NEEDS_ANSWER` and carry guidance on what a good answer covers.\n\nRequires an organization owner or admin and the Trust Pack controls in the plan. Errors: 402 when the plan does not include them; 403 for a caller who is not an organization owner or admin.","operationId":"questionnaire","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrustQuestionnaireResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/trust/questionnaire/export":{"get":{"tags":["Trust Pack"],"summary":"Export the AI questionnaire","description":"Export the AI questionnaire.\n\nDownloads the questionnaire with its current answers as a file for a reviewer's form: CSV (`text/csv`, the default) or Excel (`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`). One row per question with the columns Category, Question, Answer, Status, Answered by and Answered at. The file is named `ai-questionnaire-<organization>-<date>.csv` (or `.xlsx`).\n\nRequires an organization owner or admin and the Trust Pack controls in the plan. Errors: 400 for a format other than `csv` or `xlsx`; 402 when the plan does not include the Trust Pack controls; 403 for a caller who is not an organization owner or admin.","operationId":"exportQuestionnaire","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}},{"name":"format","in":"query","description":"the file format: `csv` (default) or `xlsx`","required":false,"schema":{"type":"string","default":"csv"}}],"responses":{"200":{"description":"The questionnaire file.","content":{"text/csv":{"schema":{"type":"string","format":"binary"}},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"type":"string","format":"binary"}}}}},"security":[{"platformKey":[]}]}},"/v1/trust/profile/preview":{"get":{"tags":["Trust Pack"],"summary":"Preview the public trust page","description":"Preview the public trust page.\n\nBuilds exactly what the public trust page shows, or would show once published, from the current settings and the trailing 90 days: only the chosen sections, and no request counts, volumes, dates seen or tool server hosts. Works whether or not the page is published.\n\nRequires an organization owner or admin (403 otherwise).","operationId":"previewProfile","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicTrustPage"}}}}},"security":[{"platformKey":[]}]}},"/v1/trust/guardrail-coverage":{"get":{"tags":["Trust Pack"],"summary":"Get the guardrail coverage report","description":"Get the guardrail coverage report.\n\nHow much of your organization's traffic its guardrails checked in the window and what they caught: totals (requests, requests checked, blocked, redacted, monitored, streamed requests, MCP Gateway tool calls), each guardrail that ran in the window or is enabled now with its checks and outcomes, the personal data types an enabled check redacts or blocks, and the tool-result scan. `statements` restates the main figures as plain sentences.\n\nThe window defaults to the 90 days up to now and can be at most 366 days long. Without `workspace_id` it requires an organization owner or admin; with it, any member of that workspace.\n\nErrors: 400 when `start_time` is not before `end_time` or the window is longer than 366 days; 402 when the organization's plan does not include the AI Trust Pack; 403 without the access above.","operationId":"guardrailCoverage","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"limit the report to this workspace (UUID); omit for the whole organization","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"start_time","in":"query","description":"start of the window, ISO 8601 date-time; default 90 days before `end_time`","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"end_time","in":"query","description":"end of the window, ISO 8601 date-time; default now","required":false,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrustGuardrailCoverageResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/trust/evidence-exports/{id}":{"get":{"tags":["Trust Pack"],"summary":"Get an evidence bundle","description":"Get an evidence bundle.\n\nOne evidence bundle: its status, period, and once `READY` its SHA-256, size, signing key id, expiry and download path. Poll this after creating a bundle.\n\nRequires an organization owner or admin. Errors: 403 for a caller who is not an organization owner or admin; 404 when the organization has no bundle with this id.","operationId":"evidenceExport","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","description":"the evidence bundle id (UUID)","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrustEvidenceExport"}}}}},"security":[{"platformKey":[]}]}},"/v1/trust/evidence-exports/{id}/download":{"get":{"tags":["Trust Pack"],"summary":"Download an evidence bundle","description":"Download an evidence bundle.\n\nStreams the bundle's zip (`application/zip`) as an attachment named `evidence-<organization>-<start>-<end>.zip`. Check the file against the export's `sha256`, and the signature in `manifest.sig` against the key from `GET /v1/public/trust/evidence-signing-key`.\n\nRequires an organization owner or admin. Errors: 403 for a caller who is not an organization owner or admin; 404 when the organization has no bundle with this id; 409 when the bundle is not `READY` (still being built, failed or expired), or is stored in another region (download it from that region's API).","operationId":"downloadEvidenceExport","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","description":"the evidence bundle id (UUID)","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The bundle's zip file.","content":{"application/zip":{"schema":{"type":"string","format":"binary"}}}}},"security":[{"platformKey":[]}]}},"/v1/trust/data-handling":{"get":{"tags":["Trust Pack"],"summary":"Get the data handling report","description":"Get the data handling report.\n\nWhat VectorAxis keeps of your organization's AI data and for how long, read from its current settings: request log retention (age and count rules, whether request and response bodies are stored, the monthly logging limit and the regions that hold the logs), the response caches (how long entries live and where), and what you asked providers to keep (files not yet deleted, and batches and stored responses created in the window). `statements` restates the same facts as plain sentences, ready for a questionnaire.\n\nThe window (default the 90 days up to now, at most 366 days) applies to the provider-side counts; the retention and cache settings are those in force when the report is generated. Without `workspace_id` it requires an organization owner or admin; with it, any member of that workspace.\n\nErrors: 400 when `start_time` is not before `end_time` or the window is longer than 366 days; 402 when the organization's plan does not include the AI Trust Pack; 403 without the access above.","operationId":"dataHandling","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"limit the provider-side counts to this workspace's keys (UUID); omit for the whole organization","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"start_time","in":"query","description":"start of the window, ISO 8601 date-time; default 90 days before `end_time`","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"end_time","in":"query","description":"end of the window, ISO 8601 date-time; default now","required":false,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrustDataHandlingResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/trust/changes":{"get":{"tags":["Trust Pack"],"summary":"List sub-processor changes","description":"List sub-processor changes.\n\nChanges to your organization's sub-processors found by the daily check, newest first, at most 500: a sub-processor added, removed or used for the first time, a new region, or a model provider serving a new model. The daily check compares the sub-processors used in the last 90 days or configured now with the previous check; the first check of an organization records a baseline and reports nothing. Organization-wide only.\n\nRequires an organization owner or admin. The window defaults to the 90 days up to now and can be at most 366 days long.\n\nErrors: 400 when `start_time` is not before `end_time` or the window is longer than 366 days; 402 when the organization's plan does not include the Trust Pack controls; 403 for a caller who is not an organization owner or admin.","operationId":"changes","parameters":[{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}},{"name":"start_time","in":"query","description":"start of the window, ISO 8601 date-time; default 90 days before `end_time`","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"end_time","in":"query","description":"end of the window, ISO 8601 date-time; default now","required":false,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrustChangesResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/tool-inventory":{"get":{"tags":["Tool inventory"],"summary":"Get the tool inventory","description":"Get the tool inventory.\n\nLists every tool name seen in the window, most used first, merged from three sources: tools declared in `tools` on LLM requests, tools the model asked to call, and `tools/call` requests through the MCP Gateway. Each tool says whether an MCP Gateway integration in the organization exposes a tool of that name (`registered: false` marks a shadow tool) and whether it was declared under more than one definition. The window defaults to the 30 days before `end_time` (default now). Each source contributes at most 500 tool names; `truncated` says when more exist. The summary counts are not capped.\n\nWith `workspace_id`, requires access to that workspace: an organization owner or admin, a member of the workspace, an organization-scoped `va_` key with the admin role, or a `va_` key scoped to the workspace. Without it, requires an organization owner or admin, or an organization-scoped `va_` key with the admin role. Errors: 400 when `start_time` is not before `end_time`; 402 when the organization's plan does not include the tool inventory.","operationId":"inventory","parameters":[{"name":"organization","in":"query","description":"the organization's slug","required":true,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"a workspace id (UUID) to limit the inventory to that workspace's traffic and servers","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"start_time","in":"query","description":"start of the window, inclusive (ISO 8601 date-time with offset); default 30 days before `end_time`","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"end_time","in":"query","description":"end of the window, exclusive (ISO 8601 date-time with offset); default now","required":false,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ToolInventoryResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/responses/{id}":{"get":{"tags":["Responses"],"summary":"Get a model response","description":"Get a model response.\n\nCompatible with OpenAI's retrieve-response endpoint: fetches a stored response from the provider by id and returns it as the provider sends it. Authenticate as for creating a response. Without `x-retry-count` a failed call is retried up to 3 times on 429 and 5xx.","operationId":"retrieveResponse","parameters":[{"name":"id","in":"path","description":"the provider's response id, for example `resp_...`","required":true,"schema":{"type":"string"}},{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}],"x-wire-format":{"name":"OpenAI Responses API","url":"https://platform.openai.com/docs/api-reference/responses/get"}},"delete":{"tags":["Responses"],"summary":"Delete a model response","description":"Delete a model response.\n\nCompatible with OpenAI's delete-response endpoint: deletes a stored response at the provider and returns the provider's confirmation. Authenticate as for creating a response. This call is not retried.","operationId":"deleteResponse","parameters":[{"name":"id","in":"path","description":"the provider's response id, for example `resp_...`","required":true,"schema":{"type":"string"}},{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}],"x-wire-format":{"name":"OpenAI Responses API","url":"https://platform.openai.com/docs/api-reference/responses/delete"}}},"/v1/responses/{id}/input_items":{"get":{"tags":["Responses"],"summary":"List a model response's input items","description":"List a model response's input items.\n\nCompatible with OpenAI's list-input-items endpoint: returns the items that made up a stored response's input, as the provider lists them. Authenticate as for creating a response. Without `x-retry-count` a failed call is retried up to 3 times on 429 and 5xx.","operationId":"listInputItems","parameters":[{"name":"id","in":"path","description":"the provider's response id, for example `resp_...`","required":true,"schema":{"type":"string"}},{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}],"x-wire-format":{"name":"OpenAI Responses API","url":"https://platform.openai.com/docs/api-reference/responses/input-items"}}},"/v1/public/trust/{slug}":{"get":{"tags":["Public trust pages"],"summary":"Get a published trust page","description":"Get a published trust page.\n\nAn organization's public trust page, built from its records for the trailing 90 days with only the sections it chose: its sub-processors and their terms, data handling statements, guardrail coverage, sub-processor changes and the approved provider policy. It holds no request counts, volumes, dates seen or tool server hosts. No credentials needed. The page is cached for up to ten minutes, so a change can take that long to show.\n\nErrors: 404 when the slug is unknown, the page is unpublished, or the organization's plan no longer includes publishing.","operationId":"trustPage","parameters":[{"name":"slug","in":"path","description":"the page's address, as set in the trust page settings (`public_slug`); case-insensitive","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicTrustPage"}}}}},"security":[]}},"/v1/public/trust/evidence-signing-key":{"get":{"tags":["Public trust pages"],"summary":"Get the evidence signing key","description":"Get the evidence signing key.\n\nThe Ed25519 public key that verifies evidence bundles. A reviewer who receives a bundle checks `manifest.sig` (base64) against the exact bytes of `manifest.json` with this key, and that `key_id` matches the one in the manifest; then each file's SHA-256 against the manifest. Fetch the key from here rather than trusting the copy inside the bundle. No credentials needed.\n\nErrors: 404 when no signing key is configured on this deployment.","operationId":"signingKey","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrustSigningKeyResponse"}}}}},"security":[]}},"/v1/providers":{"get":{"tags":["Providers"],"summary":"List supported providers","description":"List supported providers.\n\nAnswers every provider the gateway can serve on at least one endpoint, as a sorted array of provider ids (e.g. `ANTHROPIC`, `OPENAI`). Use these values for a virtual key credential's `provider` and the `x-provider` header. Not every provider serves every endpoint: some serve only audio, `TYPESAFE` only `/v1/systemone`, and `VOYAGE` only `/v1/embeddings`.\n\nNo credentials are needed.","operationId":"getProviders","responses":{"200":{"description":"The supported provider ids, sorted.","content":{"application/json":{"schema":{"type":"array","items":{"type":"string","enum":["AI21","AIML","AMAZON_NOVA","ANTHROPIC","ANYSCALE","ASSEMBLYAI","AWS_POLLY","AZURE","AZURE_AI","BASETEN","BEDROCK","BLACK_FOREST_LABS","CEREBRAS","CLOUDFLARE","CODESTRAL","COHERE","CRUSOE","DASHSCOPE","DATABRICKS","DEEPBRICKS","DEEPGRAM","DEEPINFRA","DEEPSEEK","ELEVENLABS","FAL_AI","FEATHERLESS_AI","FIREWORKS_AI","FRIENDLIAI","GEMINI","GITHUB_COPILOT","GMI","GRADIENT_AI","GROQ","HEROKU","HYPERBOLIC","INCEPTION","INFERENCE_NET","IOINTELLIGENCE","JINA_AI","KLUSTER_AI","KRUTRIM","LAMBDA_AI","LEMONADE","LEMONFOX_AI","LEPTON","LINGYI","LLAMAGATE","META_LLAMA","MINIMAX","MISTRAL","MODAL","MOONSHOT","MORPH","NEBIUS","NLP_CLOUD","NOVITA","NSCALE","NVIDIA_NIM","OCI","OLLAMA","OPENAI","OPENROUTER","OVHCLOUD","PERPLEXITY","PUBLICAI","RECRAFT","REPLICATE","RUNWAYML","SAGEMAKER","SAMBANOVA","SARVAM","SILICONFLOW","SNOWFLAKE","SONIOX","STABILITY","TOGETHER_AI","TYPESAFE","UPSTAGE","V0","VERCEL_AI_GATEWAY","VERTEX_AI","VOLCENGINE","VOYAGE","WANDB","WATSONX","XAI","ZAI","ZHIPU"]}}}}}},"security":[]}},"/v1/prompts/{slug}/versions/{versionRef}":{"get":{"tags":["Prompts"],"summary":"Get a prompt version","description":"Get a prompt version.\n\nReturns one version with its messages and labels. Requires membership of the prompt's workspace (organization admins have it).\n\nErrors: 400 when `versionRef` is not a number, `latest` or `@label`; 404 when the prompt, version or label does not exist.","operationId":"getVersion","parameters":[{"name":"slug","in":"path","description":"the prompt's slug","required":true,"schema":{"type":"string"}},{"name":"versionRef","in":"path","description":"which version: a version number (for example `3`), `latest` (the highest number, whatever its status) or `@` and a label (for example `@staging`)","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PromptVersion"}}}}},"security":[{"platformKey":[]}]}},"/v1/prompts/{slug}/labels":{"get":{"tags":["Prompts"],"summary":"List prompt labels","description":"List prompt labels.\n\nReturns the prompt's labels and the version each one points at. Requires membership of the prompt's workspace (organization admins have it). 404 when the prompt does not exist.","operationId":"listLabels","parameters":[{"name":"slug","in":"path","description":"the prompt's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PromptLabel"}}}}}},"security":[{"platformKey":[]}]}},"/v1/prompts/{slug}/audit-log":{"get":{"tags":["Prompts"],"summary":"List a prompt's audit log","description":"List a prompt's audit log.\n\nReturns the changes made to the prompt (creation, versions saved and published, labels, rollbacks, test runs), newest first. Requires membership of the prompt's workspace (organization admins have it). 404 when the prompt does not exist.","operationId":"listAuditLog","parameters":[{"name":"slug","in":"path","description":"the prompt's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}},{"name":"page","in":"query","description":"page number, from 1. Default 1","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"page_size","in":"query","description":"entries per page. Default 50, at most 200","required":false,"schema":{"type":"integer","format":"int32","default":50}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PromptAuditLogResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/prompts/{slug}/analytics":{"get":{"tags":["Prompts"],"summary":"Get prompt analytics","description":"Get prompt analytics.\n\nReturns the requests attributed to the prompt in a time window (prompt completions, and other requests sent with `x-prompt-slug`): count, cost, latency and cache hit rate, in total and per version. Only the prompt's own organization's requests made with a virtual key or a routing config count. Requires membership of the prompt's workspace (organization admins have it). 404 when the prompt does not exist.","operationId":"getAnalytics","parameters":[{"name":"slug","in":"path","description":"the prompt's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}},{"name":"from","in":"query","description":"start of the window (ISO 8601 date-time, inclusive). Default: 30 days before `to`","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","description":"end of the window (ISO 8601 date-time, exclusive). Default: now","required":false,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PromptAnalyticsSummary"}}}}},"security":[{"platformKey":[]}]}},"/v1/pricing":{"get":{"tags":["Pricing"],"summary":"List PLATFORM key prices","description":"List PLATFORM key prices.\n\nAnswers the per-token price of each model a PLATFORM virtual key can use, in USD, with the platform markup already included (`markup_pct` says how much it is). Only token-priced models of the chat, image generation, transcription, speech and System One kinds are listed, sorted by provider, then model. A key with its own markup is charged at that markup instead.\n\nNo credentials are needed.","operationId":"getPlatformPricing","parameters":[{"name":"providers","in":"query","description":"only these providers: a comma-separated list of provider ids, matched exactly, e.g. `OPENAI,ANTHROPIC`; omit for every provider","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GetPlatformPricing200Response"}}}}},"security":[]}},"/v1/organizations/{organization}/closure-eligibility":{"get":{"tags":["Organization"],"summary":"Check whether the organization can be closed","description":"Check whether the organization can be closed.\n\nReports whether `DELETE /v1/organizations/{organization`} would be allowed now, and if not, why. Closing is blocked while the organization's credit account holds a positive balance (`ORG_HAS_CREDIT_BALANCE`) or while a credit withdrawal is still being refunded (`WITHDRAWAL_IN_PROGRESS`). An organization with no credit account is closeable, with a balance of 0.\n\nRequires a member of the organization (any role), or an organization-scoped `va_` key with the admin or member role. A workspace-scoped key is refused with 403.","operationId":"getClosureEligibility","parameters":[{"name":"organization","in":"path","description":"the organization's slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OrgClosureEligibility"}}}}},"security":[{"platformKey":[]}]}},"/v1/models":{"get":{"tags":["System One"],"summary":"List System One models","description":"List System One models.\n\nCompatible with TypeSafe System One's model list: returns the models your TypeSafe credential can use. Requires a TypeSafe credential (a TypeSafe virtual key, or `x-provider: typesafe` and `x-api-key`); any other provider is a 422. Without `x-retry-count` a failed call is retried up to 3 times on 429 and 5xx.","operationId":"models","parameters":[{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SystemOneModelList"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}]}},"/v1/messages/batches/{batchId}":{"get":{"tags":["Claude Message Batches"],"summary":"Get a message batch","description":"Get a message batch.\n\nCompatible with Anthropic's Retrieve Message Batch API: the batch object, read live from Anthropic, with `results_url` pointing at this gateway once the batch has ended. With a virtual key, only a batch that key created is found; any other id is a 404. An out-of-credit key can still read its batches.\n\n**Errors** are in Anthropic's shape: 400 for a non-Anthropic or PLATFORM key or `x-config`; 401 for a missing or invalid credential; 403 for a disabled or expired key; 404 for an unknown batch.","operationId":"retrieve","parameters":[{"name":"batchId","in":"path","description":"the batch id (`msgbatch_...`)","required":true,"schema":{"type":"string"}},{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"anthropic-beta","in":"header","description":"Anthropic beta features, comma-separated (for example `context-management-2025-06-27`). Forwarded to Anthropic and Claude on Vertex only; at most 32 names of lower-case letters, digits and dashes.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}],"x-wire-format":{"name":"Anthropic Message Batches API","url":"https://docs.anthropic.com/en/api/retrieving-message-batches"}},"delete":{"tags":["Claude Message Batches"],"summary":"Delete a message batch","description":"Delete a message batch.\n\nCompatible with Anthropic's Delete Message Batch API: deletes an ended batch and its results at Anthropic and returns Anthropic's answer. With a virtual key, the batch is billed first if it has not been yet; a batch that cannot be billed is not deleted. Only a batch the key created is found; any other id is a 404.\n\n**Errors** are in Anthropic's shape: 400 for a non-Anthropic or PLATFORM key or `x-config`; 401 for a missing or invalid credential; 403 for a disabled or expired key; 404 for an unknown batch.","operationId":"delete_4","parameters":[{"name":"batchId","in":"path","description":"the batch id (`msgbatch_...`)","required":true,"schema":{"type":"string"}},{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"anthropic-beta","in":"header","description":"Anthropic beta features, comma-separated (for example `context-management-2025-06-27`). Forwarded to Anthropic and Claude on Vertex only; at most 32 names of lower-case letters, digits and dashes.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}],"x-wire-format":{"name":"Anthropic Message Batches API","url":"https://docs.anthropic.com/en/api/deleting-message-batches"}}},"/v1/messages/batches/{batchId}/results":{"get":{"tags":["Claude Message Batches"],"summary":"Get the results of a message batch","description":"Get the results of a message batch.\n\nCompatible with Anthropic's Retrieve Message Batch Results API: the ended batch's results as JSONL (`application/x-jsonl`), one line per request with its `custom_id` and `result`, as Anthropic sends them. Reading results bills nothing (the batch is billed once it ends, whether or not the results are read). With a virtual key, only a batch that key created is found; any other id is a 404.\n\n**Errors** are in Anthropic's shape: 400 for a non-Anthropic or PLATFORM key or `x-config`; 401 for a missing or invalid credential; 403 for a disabled or expired key; 404 for an unknown batch.","operationId":"results","parameters":[{"name":"batchId","in":"path","description":"the batch id (`msgbatch_...`)","required":true,"schema":{"type":"string"}},{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"anthropic-beta","in":"header","description":"Anthropic beta features, comma-separated (for example `context-management-2025-06-27`). Forwarded to Anthropic and Claude on Vertex only; at most 32 names of lower-case letters, digits and dashes.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"string","format":"binary"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}],"x-wire-format":{"name":"Anthropic Message Batches API","url":"https://docs.anthropic.com/en/api/retrieving-message-batch-results"}}},"/v1/mcp-tool-search":{"get":{"tags":["MCP tool search"],"summary":"Search a workspace's MCP tools","description":"Search a workspace's MCP tools.\n\nFinds tools by meaning: the query is embedded and compared with the tools' names and descriptions. Only tools the registry would allow a call to are returned (for example, not switched off, drifted or quarantined), best match first; a tool that has been failing lately ranks lower. Each result carries the tool's recent health. A caller's own narrowing (an MCP key's allowlist) is not applied here.\n\nRequires an organization admin key, or a key of that workspace (any role). Returns 400 when `q` is empty or longer than 1000 characters. Returns 402 when the organization's plan does not include the MCP Gateway. Returns 503 when tool search is turned off.","operationId":"search","parameters":[{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"The workspace whose tools to search (UUID).","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"q","in":"query","description":"What the tool should do, in plain language. Up to 1000 characters.","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"How many tools to return. Default 10, at most 20.","required":false,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpToolSearchResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/mcp-servers/{slug}/runs":{"get":{"tags":["MCP servers"],"summary":"List an MCP server's calls","description":"List an MCP server's calls.\n\nThe calls through this server, newest first, with the gateway's verdict, guardrail results and approval state. Paginated. For filters across servers use the MCP runs list.\n\nRequires an organization admin key, or a key of the server's workspace (any role). Returns 400 for an unknown `status`. Returns 404 when the server does not exist in the organization.","operationId":"runs","parameters":[{"name":"slug","in":"path","description":"The MCP server's slug (`mcps-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}},{"name":"status","in":"query","description":"Only calls with this verdict: `COMPLETED`, `FAILED`, `BLOCKED` or `TIMED_OUT`.","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"The page number, starting at 1. Default 1.","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"page_size","in":"query","description":"Calls per page. Default 50, at most 200.","required":false,"schema":{"type":"integer","format":"int32","default":50}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpToolRunListResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/mcp-servers/{slug}/connections":{"get":{"tags":["MCP servers"],"summary":"List an MCP server's connections","description":"List an MCP server's connections.\n\nThe live connections on this server: each person's consent for one MCP client, with when it was last used.\n\nRequires an organization admin key, or a key of the server's workspace (any role). Returns 404 when the server does not exist in the organization.","operationId":"connections","parameters":[{"name":"slug","in":"path","description":"The MCP server's slug (`mcps-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpConnectionListResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/mcp-servers/{slug}/audit-log":{"get":{"tags":["MCP servers"],"summary":"List an MCP server's audit log","description":"List an MCP server's audit log.\n\nChanges to the server, newest first: created, updated, capability switches, policy and user access changes, revoked connections. The connector has its own log. Paginated.\n\nRequires an organization admin key, or a key of the server's workspace (any role). Returns 404 when the server does not exist in the organization.","operationId":"auditLog","parameters":[{"name":"slug","in":"path","description":"The MCP server's slug (`mcps-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}},{"name":"page","in":"query","description":"The page number, starting at 1. Default 1.","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"page_size","in":"query","description":"Entries per page. Default 50, at most 200.","required":false,"schema":{"type":"integer","format":"int32","default":50}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpAuditResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/mcp-runs":{"get":{"tags":["MCP runs"],"summary":"List MCP Gateway calls","description":"List MCP Gateway calls.\n\nCalls through the gateway, newest first, filtered by workspace, server, verdict, caller, approval state and time. Paginated. A call held for approval appears with `approval_status: PENDING`; once a person approves it in the dashboard, the agent's identical retry goes ahead once.\n\nWith `workspace_id`, requires an organization admin key or a key of that workspace; without, an organization admin key. Returns 400 for an unknown `status` or `approval_status`.","operationId":"list_6","parameters":[{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"Only calls through this workspace's servers (UUID).","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"server","in":"query","description":"Only calls through this MCP server (slug).","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","description":"Only calls with this verdict: `COMPLETED`, `FAILED`, `BLOCKED` or `TIMED_OUT`.","required":false,"schema":{"type":"string"}},{"name":"user_id","in":"query","description":"Only calls made by this person (through an MCP client connected with OAuth).","required":false,"schema":{"type":"string"}},{"name":"approval_status","in":"query","description":"Only calls in this approval state: `PENDING`, `APPROVED`, `REJECTED` or `USED`. (`EXPIRED` is worked out when a call is read, so it cannot be filtered on.)","required":false,"schema":{"type":"string"}},{"name":"parent_run_id","in":"query","description":"Only the requests and retries that belong to this call (UUID).","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"start_time","in":"query","description":"Only calls made at or after this time (ISO 8601).","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"end_time","in":"query","description":"Only calls made before this time (ISO 8601).","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"page","in":"query","description":"The page number, starting at 1. Default 1.","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"page_size","in":"query","description":"Calls per page. Default 50, at most 200.","required":false,"schema":{"type":"integer","format":"int32","default":50}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpToolRunListResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/mcp-runs/{id}":{"get":{"tags":["MCP runs"],"summary":"Get an MCP Gateway call","description":"Get an MCP Gateway call.\n\nOne call, with its approval state worked out (`EXPIRED` when it was not decided, or not used, in time).\n\nRequires an organization admin key, or a key of the call's workspace. Returns 404 when the organization has no such call.","operationId":"get_4","parameters":[{"name":"id","in":"path","description":"The call's ID (UUID).","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpToolRun"}}}}},"security":[{"platformKey":[]}]}},"/v1/mcp-integrations/{slug}/audit-log":{"get":{"tags":["MCP integrations"],"summary":"List a connector's audit log","description":"List a connector's audit log.\n\nChanges to the connector, newest first: created, updated, synced, quarantined, capability changes, workspace access, organization connection, and approvals of calls to its tools. Paginated.\n\nRequires read access to the connector: for a workspace-owned connector, an organization admin key or a key of that workspace; for an organization-level connector, any organization member. Returns 404 when the connector does not exist in the organization.","operationId":"auditLog_1","parameters":[{"name":"slug","in":"path","description":"The connector's slug (`mcpi-...`).","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}},{"name":"page","in":"query","description":"The page number, starting at 1. Default 1.","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"page_size","in":"query","description":"Entries per page. Default 50, at most 200.","required":false,"schema":{"type":"integer","format":"int32","default":50}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/McpAuditResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/logs":{"get":{"tags":["Logs and analytics"],"summary":"Search request logs","description":"Search request logs.\n\nReturns one page of log rows matching every filter given, newest first unless `sort_by` says otherwise, with the total count. A row covers one request: chat, Claude Messages, embeddings, audio, images, files, batches, Responses API, Decisions and System One calls. Request and response bodies are not in the rows; read one log for them. Text filters match exactly unless noted.\n\nWith `workspace_id`, requires access to that workspace: an organization owner or admin, a member of the workspace, an organization-scoped `va_` key with the admin role, or a `va_` key scoped to the workspace. Without it, requires an organization owner or admin, or an organization-scoped `va_` key with the admin role. Errors: 400 for a date-time that is not ISO 8601 with an offset, or an unknown `sort_by`.","operationId":"searchLogs","parameters":[{"name":"provider","in":"query","description":"only requests to this provider, as stored: upper case with underscores, e.g. `OPENAI`","required":false,"schema":{"type":"string"}},{"name":"model","in":"query","description":"only requests for this model id, as sent","required":false,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"the organization's slug","required":false,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"only this workspace's requests (UUID)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"user_id","in":"query","description":"only requests attributed to this end user (the request's `user` field)","required":false,"schema":{"type":"string"}},{"name":"virtual_key_slug","in":"query","description":"only requests made with this virtual key (`vk-...`)","required":false,"schema":{"type":"string"}},{"name":"config_slug","in":"query","description":"only requests routed through this routing config","required":false,"schema":{"type":"string"}},{"name":"guardrail_slug","in":"query","description":"only requests this guardrail applied to (`gr-...`), alone or with others","required":false,"schema":{"type":"string"}},{"name":"guardrail_status","in":"query","description":"only requests whose combined guardrail result is this: `PASS`, `MONITOR`, `REDACT`, `BLOCK` or `BYPASS`","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","description":"`success` (status code below 400) or `error` (400 and above); anything else is ignored","required":false,"schema":{"type":"string"}},{"name":"cache_status","in":"query","description":"only requests with this cache result: `HIT`, `SEMANTIC_HIT`, `MISS`, `BYPASS`, `DISABLED` or `REFRESH`","required":false,"schema":{"type":"string"}},{"name":"start_time","in":"query","description":"only requests at or after this time (ISO 8601 date-time with offset)","required":false,"schema":{"type":"string"}},{"name":"end_time","in":"query","description":"only requests before this time (ISO 8601 date-time with offset)","required":false,"schema":{"type":"string"}},{"name":"search","in":"query","description":"text to find anywhere in the stored request or response body, case-insensitive; only matches logs whose bodies were stored","required":false,"schema":{"type":"string"}},{"name":"min_cost","in":"query","description":"only requests that cost at least this much, in USD","required":false,"schema":{"type":"number","format":"double"}},{"name":"max_cost","in":"query","description":"only requests that cost at most this much, in USD","required":false,"schema":{"type":"number","format":"double"}},{"name":"min_duration_ms","in":"query","description":"only requests that took at least this long, in milliseconds","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"max_duration_ms","in":"query","description":"only requests that took at most this long, in milliseconds","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"min_tokens","in":"query","description":"only requests with at least this many total tokens","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"max_tokens","in":"query","description":"only requests with at most this many total tokens","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"sort_by","in":"query","description":"the field to sort by: `created_at` (default), `provider`, `model`, `status_code`, `duration_ms`, `prompt_tokens`, `completion_tokens`, `total_tokens`, `cost`, `cache_status`, `retry_count`, `fallback_provider`, `virtual_key_slug`, `config_slug`, `guardrail_slug`, `guardrail_status`, `organization`, `workspace_id`, `user_id` or `streaming`","required":false,"schema":{"type":"string"}},{"name":"sort_dir","in":"query","description":"`asc` or `desc` (default)","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"the page to return, starting at 1 (default 1)","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"page_size","in":"query","description":"rows per page, default 50, at most 100 (a larger value is lowered to 100)","required":false,"schema":{"type":"integer","format":"int32","default":50}},{"name":"request_id","in":"query","description":"only the request with this request id (the `X-Request-ID` it ran under)","required":false,"schema":{"type":"string"}},{"name":"operation_type","in":"query","description":"only this kind of operation, e.g. `embedding`, `transcription`, `translation`, `image_generation`, `image_edit`, `file_upload`, `batch_create`, `response_create`, `message_batch`, `system_one` or `openai_decision` (chat and Claude Messages requests have none)","required":false,"schema":{"type":"string"}},{"name":"tool_scan_status","in":"query","description":"only requests whose tool-result scan had this result: `PASS`, `MONITOR`, `REDACT` or `BLOCK`; `FLAGGED` matches any of the last three","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LogSearchResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/logs/{id}":{"get":{"tags":["Logs and analytics"],"summary":"Get a request log","description":"Get a request log.\n\nReturns one log row in full: everything the search returns, plus the request and response bodies when the organization stores them, the error message of a failed request, the declared tools and the guardrail details. Fails with 404 when there is no log with this id.\n\nRequires access to the log's workspace: an organization owner or admin, a member of the workspace, an organization-scoped `va_` key with the admin role, or a `va_` key scoped to the workspace.","operationId":"getLogDetail","parameters":[{"name":"id","in":"path","description":"the log's id, as returned in `id` by the search","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LogDetail"}}}}},"security":[{"platformKey":[]}]}},"/v1/logs/export/{jobId}":{"get":{"tags":["Logs and analytics"],"summary":"Get a log export","description":"Get a log export.\n\nReturns the export job's status (`PENDING`, `RUNNING`, `DONE` or `FAILED`), the number of rows exported and, for a failed job, why. Once it is `DONE`, download the file. Fails with 404 for an unknown job, or one more than an hour old.\n\nRequires an organization owner or admin of the job's organization, or an organization-scoped `va_` key with the admin role.","operationId":"getExportJob","parameters":[{"name":"jobId","in":"path","description":"the job's id, as returned when it was started","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ExportJobResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/logs/export/{jobId}/download":{"get":{"tags":["Logs and analytics"],"summary":"Download a log export","description":"Download a log export.\n\nReturns the exported file as an attachment: CSV (`text/csv`, one header row then one row per log), or JSON, an array of log rows as the search returns them. Fails with 404 for an unknown job, or one more than an hour old, and with 409 while the job has not finished.\n\nRequires an organization owner or admin of the job's organization, or an organization-scoped `va_` key with the admin role.","operationId":"downloadExport","parameters":[{"name":"jobId","in":"path","description":"the job's id, as returned when it was started","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The exported file","content":{"text/csv":{"schema":{"type":"string"}},"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LogEntry"}}}}}},"security":[{"platformKey":[]}]}},"/v1/guardrails/{slug}/audit-log":{"get":{"tags":["Guardrails"],"summary":"List a guardrail's audit log","description":"List a guardrail's audit log.\n\nReturns the changes made to the guardrail (create, update, enable, disable), newest first. Requires membership of the guardrail's workspace. 404 when the guardrail does not exist.","operationId":"auditLog_2","parameters":[{"name":"slug","in":"path","description":"the guardrail's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}},{"name":"page","in":"query","description":"page number, from 1. Default 1","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"page_size","in":"query","description":"entries per page. Default 50, at most 200","required":false,"schema":{"type":"integer","format":"int32","default":50}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GuardrailAuditResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/guardrail-validators":{"get":{"tags":["Guardrails"],"summary":"List guardrail validators","description":"List guardrail validators.\n\nReturns every validator a guardrail check can use: its id (the check's `type`), category, whether it calls a model, the targets and actions it is meant for, a JSON Schema for its settings and a starting configuration. Needs no credentials.","operationId":"listValidators","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GuardrailValidatorListResponse"}}}}},"security":[]}},"/v1/files/{id}":{"get":{"tags":["Files"],"summary":"Get a file","description":"Get a file.\n\nReturns a file's record. With a virtual key, only files uploaded with that key are returned (403 for another key's file); an unknown id is a 404.\n\nAuthenticate with a BYOK virtual key or with `x-provider` and `x-api-key`; a PLATFORM virtual key is a 400. OpenAI credentials only; any other provider is a 422.","operationId":"retrieveFile","parameters":[{"name":"id","in":"path","description":"the file's VectorAxis id (`vxf-...`); the provider's file id is accepted too","required":true,"schema":{"type":"string"}},{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VectorAxisFile"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}]},"delete":{"tags":["Files"],"summary":"Delete a file","description":"Delete a file.\n\nDeletes the file at the provider and in VectorAxis. With a virtual key, only files uploaded with that key can be deleted (403 for another key's file); an unknown id is a 404. The organization's approved-provider policy does not apply, so you can always remove a file from a provider.\n\nAuthenticate with a BYOK virtual key or with `x-provider` and `x-api-key`; a PLATFORM virtual key is a 400. OpenAI credentials only; any other provider is a 422. Without `x-retry-count` a failed call is retried up to 3 times on 429 and 5xx.","operationId":"deleteFile","parameters":[{"name":"id","in":"path","description":"the file's VectorAxis id (`vxf-...`); the provider's file id is accepted too","required":true,"schema":{"type":"string"}},{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/DeleteFileResponse"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}]}},"/v1/files/{id}/content":{"get":{"tags":["Files"],"summary":"Get a file's content","description":"Get a file's content.\n\nDownloads the file's bytes (`application/octet-stream`). With a virtual key, only files uploaded with that key are returned (403 for another key's file); an unknown id is a 404.\n\nAuthenticate with a BYOK virtual key or with `x-provider` and `x-api-key`; a PLATFORM virtual key is a 400. OpenAI credentials only; any other provider is a 422.","operationId":"retrieveFileContent","parameters":[{"name":"id","in":"path","description":"the file's VectorAxis id (`vxf-...`); the provider's file id is accepted too","required":true,"schema":{"type":"string"}},{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The file's bytes.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}]}},"/v1/configs/{slug}/audit-log":{"get":{"tags":["Routing configs"],"summary":"List a routing config's audit log","description":"List a routing config's audit log.\n\nLists who created and updated the config, and when, newest first, a page at a time.\n\nRequires a key of the organization with access to the config's workspace: a workspace key (member or admin) for that workspace, or an organization admin key. 403 without it; 404 when the organization has no config with this slug.","operationId":"auditLog_3","parameters":[{"name":"slug","in":"path","description":"the config's slug","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"the organization slug","required":true,"schema":{"type":"string"}},{"name":"page","in":"query","description":"the page number, starting at 1 (default 1)","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"page_size","in":"query","description":"entries per page (default 50, at most 200)","required":false,"schema":{"type":"integer","format":"int32","default":50}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RoutingConfigAuditResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/billing/subscription":{"get":{"tags":["Billing"],"summary":"Get the organization's subscription","description":"Get the organization's subscription.\n\nReturns the organization's plan and subscription status. An organization that has never subscribed is on the `free` plan, which this call records the first time it is read.\n\nRequires a member of the organization (any role), or an organization-scoped `va_` key with the admin or member role. A workspace-scoped key is refused with 403.","operationId":"getSubscription_1","parameters":[{"name":"organization","in":"query","description":"the organization's slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/Subscription"}}}}},"security":[{"platformKey":[]}]}},"/v1/billing/pricing-metadata":{"get":{"tags":["Billing"],"summary":"List plans and their prices","description":"List plans and their prices.\n\nReturns every plan with its limits and features, cheapest first, priced for the caller's pricing region: the region is taken from the country the request comes from, and is the default region (US, in USD) when the country is unknown or has no regional prices. Needs no credentials.","operationId":"pricingMetadata","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PricingMetadataResponse"}}}}},"security":[]}},"/v1/billing/entitlements":{"get":{"tags":["Billing"],"summary":"Get the organization's entitlements","description":"Get the organization's entitlements.\n\nReturns the limits and features the organization has now: its plan's values, with any adjustments made for the organization applied. A null limit means no limit. The values apply to the whole organization (limits named per workspace apply to each workspace); `workspace_id` is only echoed back.\n\nRequires a member of the organization (any role), or an organization-scoped `va_` key with the admin or member role. A workspace-scoped key is refused with 403.","operationId":"getEntitlements","parameters":[{"name":"organization","in":"query","description":"the organization's slug","required":true,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"a workspace id (UUID), returned as `workspace_id`; it does not change the values","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WorkspaceEntitlements"}}}}},"security":[{"platformKey":[]}]}},"/v1/billing/credits":{"get":{"tags":["Billing"],"summary":"Get the organization's credit balance","description":"Get the organization's credit balance.\n\nReturns the organization's credit account: the USD balance that PLATFORM virtual keys draw on, what was bought and consumed, the auto-recharge settings and any pending withdrawal. An organization that has never bought credits gets an account with a balance of 0.\n\nRequires a member of the organization (any role), or an organization-scoped `va_` key with the admin or member role. A workspace-scoped key is refused with 403.","operationId":"getCredits","parameters":[{"name":"organization","in":"query","description":"the organization's slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OrgCreditAccount"}}}}},"security":[{"platformKey":[]}]}},"/v1/billing/credits/transactions":{"get":{"tags":["Billing"],"summary":"List credit transactions","description":"List credit transactions.\n\nReturns the organization's credit movements, newest first: purchases, plan allocations, consumption by PLATFORM keys, refunds, auto-recharges and withdrawals. Paginated with `page` (0-based, default 0) and `page_size` (default 50, at most 200; a larger value is lowered to 200).\n\nRequires a member of the organization (any role), or an organization-scoped `va_` key with the admin or member role. A workspace-scoped key is refused with 403.","operationId":"listTransactions","parameters":[{"name":"organization","in":"query","description":"the organization's slug","required":true,"schema":{"type":"string"}},{"name":"page","in":"query","description":"the page to return, starting at 0","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"page_size","in":"query","description":"transactions per page, 1 to 200","required":false,"schema":{"type":"integer","format":"int32","default":50}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreditTransactionListResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/batches/{id}":{"get":{"tags":["Batches"],"summary":"Get a batch","description":"Get a batch.\n\nCompatible with OpenAI's retrieve-batch endpoint: returns the batch's current status, request counts and file ids as the provider reports them. With a virtual key, only batches that key created are reachable; any other batch id is a 404.\n\nAuthenticate with a BYOK virtual key or with `x-provider` and `x-api-key`; a PLATFORM virtual key is a 400. OpenAI credentials only; any other provider is a 422. Without `x-retry-count` a failed call is retried up to 3 times on 429 and 5xx.","operationId":"retrieveBatch","parameters":[{"name":"id","in":"path","description":"the provider's batch id, for example `batch_...`","required":true,"schema":{"type":"string"}},{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/BatchObject"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}]}},"/v1/batches/{id}/output":{"get":{"tags":["Batches"],"summary":"Get a batch's output","description":"Get a batch's output.\n\nDownloads the results file of a batch (`application/octet-stream`, JSONL: one line per request). A batch with no output file yet is a 409 naming its status. With a virtual key, only batches that key created are reachable; any other batch id is a 404.\n\nAuthenticate with a BYOK virtual key or with `x-provider` and `x-api-key`; a PLATFORM virtual key is a 400. OpenAI credentials only; any other provider is a 422. Without `x-retry-count` a failed call is retried up to 3 times on 429 and 5xx.","operationId":"getBatchOutput","parameters":[{"name":"id","in":"path","description":"the provider's batch id, for example `batch_...`","required":true,"schema":{"type":"string"}},{"name":"x-provider","in":"header","description":"With direct credentials: the provider `x-api-key` belongs to, for example `openai` or `anthropic` (case and dashes are normalised). Not used with a virtual key.","required":false,"schema":{"type":"string"}},{"name":"x-retry-count","in":"header","description":"How many times to retry a failed provider call, 0 to 5. Without the header, chat completions, Claude Messages and prompt completions do not retry, and the other endpoints retry up to 3 times. Retries back off exponentially from 1 second and honour a numeric `Retry-After`. The number made is in the `x-retry-count` response header.","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"x-retry-status-codes","in":"header","description":"Comma-separated provider status codes to retry on. Default `429,500,502,503,504,529`.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The batch's output file: one JSON result per line.","content":{"application/jsonl":{"schema":{"type":"string","format":"binary"}}}}},"security":[{"virtualKey":[]},{"virtualKeyHeader":[]},{"providerKey":[]}]}},"/v1/analytics/timeseries":{"get":{"tags":["Logs and analytics"],"summary":"Get a usage time series","description":"Get a usage time series.\n\nReturns one metric per time bucket over the requests matching the filters. Buckets are aligned to `tz` (local midnight for `day`) and every bucket in the window is returned, an empty one as 0. The window runs from `start_time` (default: the first retained log) to `end_time` (default now); it may hold at most 5000 buckets. With `split_by=model`, `series` also holds one series per model for the `series_limit` models with the most requests, plus one `other` series for the rest.\n\nWith `workspace_id`, requires access to that workspace: an organization owner or admin, a member of the workspace, an organization-scoped `va_` key with the admin role, or a `va_` key scoped to the workspace. Without it, requires an organization owner or admin, or an organization-scoped `va_` key with the admin role. Fails with 400 for an unknown metric, granularity, time zone or `split_by`, a date-time without an offset, or a window of more than 5000 buckets.","operationId":"getTimeSeries","parameters":[{"name":"metric","in":"query","description":"what to chart per bucket: `requests`, `tokens`, `cost` (USD), `cost_saved` (USD saved by cache hits), `latency` (average duration in milliseconds), `error_rate` or `cache_hit_rate` (each 0 to 1)","required":true,"schema":{"type":"string"}},{"name":"granularity","in":"query","description":"the bucket size: `hour`, `day` (default) or `week`","required":false,"schema":{"type":"string","default":"day"}},{"name":"tz","in":"query","description":"the IANA time zone buckets are aligned to, e.g. `America/Toronto`; default UTC. Fixed offsets such as `+05:30` are refused","required":false,"schema":{"type":"string"}},{"name":"start_time","in":"query","description":"start of the window, inclusive (ISO 8601 date-time with offset)","required":false,"schema":{"type":"string"}},{"name":"end_time","in":"query","description":"end of the window, exclusive (ISO 8601 date-time with offset)","required":false,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"the organization's slug","required":false,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"only this workspace's requests (UUID)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"provider","in":"query","description":"only requests to this provider, as stored: upper case with underscores, e.g. `OPENAI`","required":false,"schema":{"type":"string"}},{"name":"model","in":"query","description":"only requests for this model id","required":false,"schema":{"type":"string"}},{"name":"split_by","in":"query","description":"`model` to add a series per model; omit for the total only","required":false,"schema":{"type":"string"}},{"name":"series_limit","in":"query","description":"with `split_by=model`, how many models get their own series: default 6, 1 to 10","required":false,"schema":{"type":"integer","format":"int32","default":6}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TimeSeriesResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/analytics/summary":{"get":{"tags":["Logs and analytics"],"summary":"Get usage totals","description":"Get usage totals.\n\nReturns totals over every request matching the filters: requests, tokens, cost, the cost cache hits saved, error rate, cache hit rate, and average and percentile latency. Without `start_time` and `end_time` it covers every log still retained.\n\nWith `workspace_id`, requires access to that workspace: an organization owner or admin, a member of the workspace, an organization-scoped `va_` key with the admin role, or a `va_` key scoped to the workspace. Without it, requires an organization owner or admin, or an organization-scoped `va_` key with the admin role. Fails with 400 for a date-time that is not ISO 8601 with an offset.","operationId":"getSummary","parameters":[{"name":"start_time","in":"query","description":"only requests at or after this time (ISO 8601 date-time with offset)","required":false,"schema":{"type":"string"}},{"name":"end_time","in":"query","description":"only requests before this time (ISO 8601 date-time with offset)","required":false,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"the organization's slug","required":false,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"only this workspace's requests (UUID)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"provider","in":"query","description":"only requests to this provider, as stored: upper case with underscores, e.g. `OPENAI`","required":false,"schema":{"type":"string"}},{"name":"model","in":"query","description":"only requests for this model id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AnalyticsSummary"}}}}},"security":[{"platformKey":[]}]}},"/v1/analytics/latency":{"get":{"tags":["Logs and analytics"],"summary":"Get the latency graph","description":"Get the latency graph.\n\nReturns latency over time for the organization's requests: a summary of the whole window and one data point per time bucket, each with the total latency, the time spent waiting on the provider, the gateway's own overhead and, for streams, the time to the first chunk. Empty buckets are included with 0 requests. The window defaults to the 24 hours before `end_time` (default now) and can be at most 366 days, with at most 1500 buckets. Requests from every region that holds the organization's logs are included; a region that did not answer is listed in `unavailable_regions`.\n\nEvery list parameter takes comma-separated values (or the parameter repeated) and matches any of them.\n\nWith `workspace_id`, requires access to each workspace named: an organization owner or admin, a member of the workspace, an organization-scoped `va_` key with the admin role, or a `va_` key scoped to the workspace. Without it, covers every workspace (less `exclude_workspace_ids`) and requires an organization owner or admin, or an organization-scoped `va_` key with the admin role; a workspace-scoped key reads its own workspace. Errors: 400 for a missing organization, a window that is empty, too long or has too many buckets, an unknown granularity, time zone or status, a malformed `provider_model`, or `exclude_workspace_ids` together with `workspace_id`.","operationId":"graph","parameters":[{"name":"organization","in":"query","description":"the organization's slug; defaults to the `va_` key's organization","required":false,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"only these workspaces' requests (UUIDs)","required":false,"schema":{"type":"array","items":{"type":"string","format":"uuid"}}},{"name":"exclude_workspace_ids","in":"query","description":"without `workspace_id`, leave out these workspaces' requests (UUIDs)","required":false,"schema":{"type":"array","items":{"type":"string","format":"uuid"}}},{"name":"start_time","in":"query","description":"start of the window, inclusive (ISO 8601 date-time with offset); default 24 hours before `end_time`","required":false,"schema":{"type":"string"}},{"name":"end_time","in":"query","description":"end of the window, exclusive (ISO 8601 date-time with offset); default now","required":false,"schema":{"type":"string"}},{"name":"granularity","in":"query","description":"the bucket size: `minute`, `hour`, `day`, `week`, or `auto` (default: by minute up to 3 hours, by hour up to 7 days, by day up to 90 days, then by week)","required":false,"schema":{"type":"string"}},{"name":"tz","in":"query","description":"the IANA time zone buckets are aligned to, e.g. `America/Toronto`; default UTC","required":false,"schema":{"type":"string"}},{"name":"provider","in":"query","description":"only requests to these providers, e.g. `openai` or `OPENAI`","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"model","in":"query","description":"only requests for these model ids","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"provider_model","in":"query","description":"only these provider and model pairs, written `provider__model`, e.g. `openai__gpt-4o`","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"virtual_key_slug","in":"query","description":"only requests made with these virtual keys (`vk-...`)","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"config_slug","in":"query","description":"only requests routed through these routing configs","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"prompt_slug","in":"query","description":"only requests made from these prompts","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"guardrail_slug","in":"query","description":"only requests any of these guardrails applied to (`gr-...`)","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"guardrail_status","in":"query","description":"only requests whose combined guardrail result is one of these: `PASS`, `MONITOR`, `REDACT`, `BLOCK` or `BYPASS`","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"user_id","in":"query","description":"only requests attributed to these end users (the request's `user` field)","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"request_id","in":"query","description":"only the requests with these request ids","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"cache_status","in":"query","description":"only requests with one of these cache results: `HIT`, `SEMANTIC_HIT`, `MISS`, `BYPASS`, `DISABLED` or `REFRESH`","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"operation_type","in":"query","description":"only these kinds of operation, as on the log search (chat requests have none)","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"region","in":"query","description":"only requests served in these regions, e.g. `us-east-2`","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"status_code","in":"query","description":"only requests that ended with one of these HTTP status codes","required":false,"schema":{"type":"array","items":{"type":"integer","format":"int32"}}},{"name":"status","in":"query","description":"`success` (status code below 400) or `error` (400 and above)","required":false,"schema":{"type":"string"}},{"name":"streaming","in":"query","description":"`true` for streamed requests only, `false` for the others","required":false,"schema":{"type":"boolean"}},{"name":"tool_scan_status","in":"query","description":"only requests whose tool-result scan had this result: `PASS`, `MONITOR`, `REDACT` or `BLOCK`; `FLAGGED` matches any of the last three","required":false,"schema":{"type":"string"}},{"name":"search","in":"query","description":"text to find anywhere in the stored request or response body, case-insensitive; only matches logs whose bodies were stored","required":false,"schema":{"type":"string"}},{"name":"min_tokens","in":"query","description":"only requests with at least this many total tokens","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"max_tokens","in":"query","description":"only requests with at most this many total tokens","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"min_prompt_tokens","in":"query","description":"only requests with at least this many prompt (input) tokens","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"max_prompt_tokens","in":"query","description":"only requests with at most this many prompt (input) tokens","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"min_completion_tokens","in":"query","description":"only requests with at least this many completion (output) tokens","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"max_completion_tokens","in":"query","description":"only requests with at most this many completion (output) tokens","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"min_cost","in":"query","description":"only requests that cost at least this much, in USD","required":false,"schema":{"type":"number","format":"double"}},{"name":"max_cost","in":"query","description":"only requests that cost at most this much, in USD","required":false,"schema":{"type":"number","format":"double"}},{"name":"min_duration_ms","in":"query","description":"only requests that took at least this long, in milliseconds","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"max_duration_ms","in":"query","description":"only requests that took at most this long, in milliseconds","required":false,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LatencyGraphResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/analytics/breakdown":{"get":{"tags":["Logs and analytics"],"summary":"Get a usage breakdown","description":"Get a usage breakdown.\n\nGroups the requests matching the filters by one dimension and returns each group's requests, errors, tokens, cost, cost saved and average latency, highest cost first. Requests with no value for the dimension (no virtual key, for example) are left out.\n\nWith `workspace_id`, requires access to that workspace: an organization owner or admin, a member of the workspace, an organization-scoped `va_` key with the admin role, or a `va_` key scoped to the workspace. Without it, requires an organization owner or admin, or an organization-scoped `va_` key with the admin role. Fails with 400 for an unknown dimension or a date-time without an offset.","operationId":"getBreakdown","parameters":[{"name":"dimension","in":"query","description":"what to group by: `provider`, `model`, `organization`, `user_id`, `virtual_key_slug` or `cache_status`","required":true,"schema":{"type":"string"}},{"name":"start_time","in":"query","description":"only requests at or after this time (ISO 8601 date-time with offset)","required":false,"schema":{"type":"string"}},{"name":"end_time","in":"query","description":"only requests before this time (ISO 8601 date-time with offset)","required":false,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"the organization's slug","required":false,"schema":{"type":"string"}},{"name":"workspace_id","in":"query","description":"only this workspace's requests (UUID)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"provider","in":"query","description":"only requests to this provider, as stored: upper case with underscores, e.g. `OPENAI`","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"the most groups to return: default 20, at most 100","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}}}},"security":[{"platformKey":[]}]}},"/v1/prompts/{slug}/test-cases/{testCaseId}":{"delete":{"tags":["Prompts"],"summary":"Delete a prompt test case","description":"Delete a prompt test case.\n\nDeletes the test case. Requires an admin of the prompt's workspace, or an organization admin. 404 when the prompt or test case does not exist.","operationId":"deleteTestCase","parameters":[{"name":"slug","in":"path","description":"the prompt's slug","required":true,"schema":{"type":"string"}},{"name":"testCaseId","in":"path","description":"the test case's id (UUID)","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"organization","in":"query","description":"slug of the organization that owns it","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"}},"security":[{"platformKey":[]}]}},"/v1/mcp-servers/{slug}/connections/{userId}":{"delete":{"tags":["MCP servers"],"summary":"Revoke a person's connections to an MCP server","description":"Revoke a person's connections to an MCP server.\n\nRevokes every live connection the person has on this server, at once: their MCP clients are refused on their next call and must ask for consent again. Returns 204.\n\nRequires an organization admin key, or a workspace admin key for the server's workspace. Returns 404 when the server does not exist in the organization.","operationId":"revokeConnections","parameters":[{"name":"slug","in":"path","description":"The MCP server's slug (`mcps-...`).","required":true,"schema":{"type":"string"}},{"name":"userId","in":"path","description":"The person's user ID.","required":true,"schema":{"type":"string"}},{"name":"organization","in":"query","description":"The organization's identifier (slug).","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}},"security":[{"platformKey":[]}]}}},"components":{"schemas":{"UpdateWorkspaceRequest":{"type":"object","description":"Changes to a workspace. `name` is kept when omitted; `description` and `  default_routing_config_slug` are replaced by what is sent, so omitting either clears it.","properties":{"name":{"type":"string","description":"A new display name; omit to keep the current one."},"description":{"type":"string","description":"The description; omit or send null to clear it."},"default_routing_config_slug":{"type":"string","description":"The routing config the dashboard should select by default for this workspace; omit or send null to clear it."}}},"Workspace":{"type":"object","description":"A workspace: a team or project inside an organization that owns virtual keys, prompts, routing configs, guardrails and logs.","properties":{"id":{"type":"string","format":"uuid","description":"The workspace's id (UUID), used as `workspace_id` elsewhere in the API."},"organization":{"type":"string","description":"The slug of the organization the workspace belongs to."},"slug":{"type":"string","description":"The workspace's slug, unique within the organization, used in workspace URLs."},"name":{"type":"string","description":"The workspace's display name."},"description":{"type":"string","description":"A description of the workspace; absent when none was given."},"default_routing_config_slug":{"type":"string","description":"The routing config the dashboard selects by default for this workspace; absent when none is set."},"created_at":{"type":"string","format":"date-time","description":"When the workspace was created (ISO 8601 date-time)."},"updated_at":{"type":"string","format":"date-time","description":"When the workspace was last changed (ISO 8601 date-time)."}}},"WorkspaceMember":{"type":"object","description":"A person explicitly added to a workspace, or a pending invitation to it.","properties":{"user_id":{"type":"string","description":"The member's user id. For a pending invitation (someone who has not signed up yet) this is the invited email address until they sign in."},"email":{"type":"string","description":"The member's email address."},"name":{"type":"string","description":"The member's display name; absent until they have signed in."},"picture_url":{"type":"string","description":"A URL of the member's profile picture; absent when there is none."},"role":{"type":"string","description":"The member's workspace role: `admin` (manage the workspace's resources and members), `manager`, or `member` (read the workspace's resources).","enum":["admin","manager","member"]},"joined_at":{"type":"string","format":"date-time","description":"When the person was added or invited (ISO 8601 date-time)."},"is_pending":{"type":"boolean","description":"True for an invitation the person has not accepted yet by signing up with the invited email."}}},"UpdateVirtualKeyRequest":{"type":"object","description":"Changes to a virtual key. Every field is optional: a field left out is unchanged. For the limits, `expires_at`, `metadata` and `model_allowlist`, `null` removes the value; each field says what removing it means. The credential mode, provider keys, organization and workspace cannot be changed.","properties":{"name":{"type":"string","description":"The key's new name. Left out or `null`: unchanged."},"note":{"type":"string","description":"The key's new note. Left out or `null`: unchanged."},"expires_at":{"type":"string","format":"date-time","description":"When the key expires (ISO 8601 date-time). `null`: the key no longer expires. Left out: unchanged."},"metadata":{"type":"object","additionalProperties":{"type":"string"},"description":"Your own string key/value pairs, replacing the current ones. `null` or `{}` clears them. Left out: unchanged."},"model_allowlist":{"type":"array","description":"The models the key may call (see the key's `model_allowlist`), replacing the current list. `null` or `[]` allows every model. Left out: unchanged.","items":{"type":"string"}},"guardrail_slugs":{"type":"array","description":"Slugs of the guardrails to run on the key's requests. A list replaces the attached guardrails, `[]` detaches them all; left out or `null`: unchanged. Each must belong to the key's organization and, when it belongs to a workspace, to the key's workspace; no duplicates.","items":{"type":"string"}},"credit_limit_usd":{"type":"number","format":"double","description":"The most the key may spend, in USD. A number sets it, `null` removes the limit, left out: unchanged. The key's status follows the new limit (`ACTIVE` or `EXHAUSTED`)."},"credit_alert_threshold_usd":{"type":"number","format":"double","description":"The soft spend alert, in USD. A number sets it, `null` removes it, left out: unchanged."},"credit_reset_policy":{"type":"string","description":"When the key's spend goes back to zero: `MONTHLY`, `WEEKLY` or `NEVER`. Setting it schedules the next reset from now. Left out or `null`: unchanged.","enum":["MONTHLY","WEEKLY","NEVER"]},"rate_limit_rpm":{"type":"integer","format":"int32","description":"Requests per minute. A number sets the limit, `null` removes it, left out: unchanged."},"rate_limit_tpm":{"type":"integer","format":"int32","description":"Tokens per minute. A number sets the limit, `null` removes it, left out: unchanged."},"rate_limit_rpd":{"type":"integer","format":"int32","description":"Requests per UTC day. A number sets the limit, `null` removes it, left out: unchanged."}}},"VirtualKey":{"type":"object","description":"A virtual key: its settings, limits, usage and status. It never contains a provider key or the API key's secret: each credential shows only its last four characters, and the API key only its hint.","properties":{"slug":{"type":"string","description":"The key's stable identifier: `vk-` followed by 16 hex characters. Used in URLs, logs and routing configs."},"token_hint":{"type":"string","description":"The last characters of the API key's secret, to tell keys apart. Absent for a key with `legacy_auth`."},"legacy_auth":{"type":"boolean","description":"True for a key created before API keys existed: its bare slug still authenticates, until the key is rotated for the first time."},"rotated_at":{"type":"string","format":"date-time","description":"When the API key was last rotated (ISO 8601 date-time). Absent if it never was."},"name":{"type":"string","description":"The key's name, unique within the organization."},"note":{"type":"string","description":"A free-text note about the key. Absent when none was set."},"status":{"type":"string","description":"The key's status:\n\n- `ACTIVE`: requests are served.\n- `DISABLED`: turned off by an admin; requests are refused (403) until it is enabled.\n- `EXHAUSTED`: its spend reached `credit_limit_usd`; requests are refused (403) until the limit is raised or removed, the spend resets (`credit_reset_policy`) or, for a PLATFORM key, credit is added.\n- `EXPIRED`: past `expires_at`; final.","enum":["ACTIVE","DISABLED","EXHAUSTED","EXPIRED"]},"disable_reason":{"type":"string","description":"The reason given when the key was disabled. Absent unless the key is `DISABLED` with a reason."},"credential_mode":{"type":"string","description":"Where the provider credentials come from: `BYOK` (your provider keys, in `credentials`) or `PLATFORM` (VectorAxis's provider accounts, paid from your organization's credits).","enum":["BYOK","PLATFORM"]},"credentials":{"type":"array","description":"The key's provider credentials, as hints only. Empty for a PLATFORM key.","items":{"$ref":"#/components/schemas/VirtualKeyCredential"}},"organization":{"type":"string","description":"The slug of the organization the key belongs to."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace the key belongs to (UUID)."},"created_at":{"type":"string","format":"date-time","description":"When the key was created (ISO 8601 date-time)."},"updated_at":{"type":"string","format":"date-time","description":"When the key's settings or status last changed (ISO 8601 date-time)."},"expires_at":{"type":"string","format":"date-time","description":"When the key expires (ISO 8601 date-time). Absent: it never expires."},"last_used_at":{"type":"string","format":"date-time","description":"When the key last served a request (ISO 8601 date-time). Absent if it never has."},"total_requests":{"type":"integer","format":"int64","description":"How many requests the key has served."},"total_cost_usd":{"type":"number","format":"double","description":"What the key has spent, in USD, since it was created or since its last credit reset. This is the figure `credit_limit_usd` and `credit_alert_threshold_usd` are compared with."},"metadata":{"type":"object","additionalProperties":{"type":"string"},"description":"Your own string key/value pairs. Absent when none are set."},"model_allowlist":{"type":"array","description":"The models the key may call; others are refused (403 `MODEL_NOT_ALLOWED`). Absent: every model.","items":{"type":"string"}},"credit_limit_usd":{"type":"number","format":"double","description":"The most the key may spend, in USD, before it becomes `EXHAUSTED`. Absent: no limit."},"credit_alert_threshold_usd":{"type":"number","format":"double","description":"The soft spend alert, in USD: at or above it the key carries the `ALERT_THRESHOLD_EXCEEDED` warning. Absent: no alert."},"credit_reset_policy":{"type":"string","description":"When the key's spend goes back to zero: `MONTHLY` (the 1st of each month, 00:00 UTC), `WEEKLY` (each Monday, 00:00 UTC) or `NEVER`.","enum":["MONTHLY","WEEKLY","NEVER"]},"credit_next_reset_at":{"type":"string","format":"date-time","description":"When the next credit reset is due (ISO 8601 date-time). Absent when the policy is `NEVER`."},"rate_limit_rpm":{"type":"integer","format":"int32","description":"The most requests per minute (a 60-second window). Absent: no limit."},"rate_limit_tpm":{"type":"integer","format":"int32","description":"The most tokens per minute (a 60-second window). Absent: no limit."},"rate_limit_rpd":{"type":"integer","format":"int32","description":"The most requests per UTC calendar day. Absent: no limit."},"initial_credits_usd":{"type":"number","format":"double","description":"For a PLATFORM key: the credit in USD it was created with. Absent for a BYOK key."},"credit_balance_usd":{"type":"number","format":"double","description":"For a PLATFORM key: what it may still spend, in USD (`credit_limit_usd` minus `total_cost_usd`). Absent for a BYOK key, or when there is no limit."},"provider_whitelist":{"type":"array","description":"For a PLATFORM key: the only providers it may use, as provider ids. Absent: any provider.","items":{"type":"string"}},"guardrail_slugs":{"type":"array","description":"Slugs of the guardrails run on every request made with the key. Absent: none.","items":{"type":"string"}},"markup_pct":{"type":"number","format":"double","description":"For a PLATFORM key: its own markup on the provider's price, as a fraction (`0.06` is 6%). Absent: the platform default markup applies."},"warnings":{"type":"array","description":"Advisory warnings, computed when the key is read; they never block requests:\n\n- `ALERT_THRESHOLD_EXCEEDED`: `total_cost_usd` has reached `credit_alert_threshold_usd`.\n- `EXPIRING_SOON`: the key expires within the next few days.\n\nEmpty when there is nothing to report.","items":{"type":"string","enum":["ALERT_THRESHOLD_EXCEEDED","EXPIRING_SOON"]}}}},"VirtualKeyCredential":{"type":"object","description":"A provider credential held by a BYOK virtual key. The provider key itself is never returned.","properties":{"provider":{"type":"string","description":"The provider id, e.g. `OPENAI` (see \"List supported providers\")."},"key_hint":{"type":"string","description":"The last four characters of the provider key, to tell keys apart."},"vertex_project_id":{"type":"string","description":"For a `VERTEX_AI` credential: the Google Cloud project id. Absent for other providers."},"vertex_region":{"type":"string","description":"For a `VERTEX_AI` credential: the Vertex AI region, or `global`. Absent for other providers."}}},"UpdateToolScanSettingsRequest":{"type":"object","description":"Sets a virtual key's tool-result scan action. Send `{\"action\": null`} to go back to the platform default; a body without `action` (`{`}) changes nothing.","properties":{"action":{"type":"string","description":"What the scan does when a tool result matches: `MONITOR` records it, `REDACT` removes the matched text before the model reads it, `BLOCK` refuses the request with 422. `null` means the platform default.","enum":["MONITOR","REDACT","BLOCK"]}}},"ToolScanSettings":{"type":"object","description":"A virtual key's tool-result scan setting: its own action, or the platform default.","properties":{"virtual_key_slug":{"type":"string","description":"The virtual key's slug (`vk-...`)."},"action":{"type":"string","description":"The key's own action; absent when the key uses the platform default.","enum":["MONITOR","REDACT","BLOCK"]},"effective_action":{"type":"string","description":"What the scan does on this key's requests: `action`, else `default_action`.","enum":["MONITOR","REDACT","BLOCK"]},"default_action":{"type":"string","description":"The platform default, used when the key sets no action of its own.","enum":["MONITOR","REDACT","BLOCK"]}}},"UpdateQuestionAnswerRequest":{"type":"object","description":"The organization's own answer to one questionnaire question.","properties":{"answer":{"type":"string","description":"The answer text, at most 10,000 characters (surrounding whitespace is trimmed). A blank or absent answer removes the organization's answer, so the generated answer (if any) applies again."}}},"UpdateTrustProfileRequest":{"type":"object","description":"Changes to the public trust page. A field left out (null) is unchanged.","properties":{"public_slug":{"type":"string","description":"The page's address, /trust/{public_slug}: 3 to 63 lower-case letters, digits or dashes, not starting or ending with a dash, and not a reserved word. Must not be in use by another organization."},"published":{"type":"boolean","description":"True makes the page public (needs the Trust Pack controls in the plan and at least one section); false takes it down."},"indexable":{"type":"boolean","description":"Let search engines index the published page."},"display_name":{"type":"string","description":"The company name shown on the page, at most 120 characters. An empty string falls back to the organization slug."},"contact_email":{"type":"string","description":"An email address where a reviewer can ask questions, at most 255 characters; an empty string removes it."},"sections":{"type":"array","description":"The sections to show, in this order (duplicates are dropped). SUBPROCESSORS: the AI providers, tool servers and platform services the data reaches, with their terms. DATA_HANDLING: what VectorAxis keeps of the data, for how long and where. GUARDRAILS: what the guardrails check. CHANGES: sub-processor changes. POLICY: whether only approved providers can receive the data, and which.","items":{"type":"string","enum":["SUBPROCESSORS","DATA_HANDLING","GUARDRAILS","CHANGES","POLICY"]}},"workspace_id":{"type":"string","description":"Report on one workspace (its UUID) instead of the whole organization; an empty string means the whole organization. The workspace must belong to the organization."}}},"TrustProfileResponse":{"type":"object","description":"An organization's public trust page settings.","properties":{"organization":{"type":"string","description":"The organization slug."},"entitled":{"type":"boolean","description":"Whether the organization's plan includes publishing a trust page."},"public_slug":{"type":"string","description":"The page's address: the page is served at GET /v1/public/trust/{public_slug}."},"public_path":{"type":"string","description":"The page, relative to the VectorAxis web app: /trust/{public_slug}."},"published":{"type":"boolean","description":"Whether the page is public."},"indexable":{"type":"boolean","description":"Whether search engines may index the page."},"display_name":{"type":"string","description":"The company name shown on the page."},"contact_email":{"type":"string","description":"Where a reviewer can ask questions; absent when not set."},"sections":{"type":"array","description":"The sections the page shows, in order: SUBPROCESSORS, DATA_HANDLING, GUARDRAILS, CHANGES, POLICY. Default for a new page: SUBPROCESSORS, DATA_HANDLING and POLICY.","items":{"type":"string","enum":["SUBPROCESSORS","DATA_HANDLING","GUARDRAILS","CHANGES","POLICY"]}},"workspace_id":{"type":"string","format":"uuid","description":"The workspace the page reports on (UUID); absent for the whole organization."},"updated_by":{"type":"string","description":"Who last changed the settings: the user id, or api-key:{key id} for a platform API key; absent before the first change."},"updated_at":{"type":"string","format":"date-time","description":"When the settings were last changed (ISO 8601 date-time); absent before the first change."},"published_at":{"type":"string","format":"date-time","description":"When the page was last published (ISO 8601 date-time); absent while it is unpublished."}}},"UpdateTrustPolicyRequest":{"type":"object","description":"Changes to an organization's approved sub-processor policy and change alerts. A field left out (null) is unchanged.","properties":{"approved_providers_enabled":{"type":"boolean","description":"Turn the policy on (true) or off (false). While it is on, a call to a provider not in approved_providers is refused before it is made. Turning it on needs at least one approved provider and the Trust Pack controls in the plan."},"approved_providers":{"type":"array","description":"Provider ids, as GET /v1/providers lists them (for example OPENAI, ANTHROPIC, VERTEX_AI); case and dashes are normalised. Replaces the whole list. At most 200; an unknown id is a 400.","items":{"type":"string"},"maxItems":200,"minItems":0},"notify_email":{"type":"boolean","description":"Email the organization's owners and admins when a sub-processor change is found (a new model is not emailed)."},"webhook_url":{"type":"string","description":"An https URL on the public internet that receives every sub-processor change as a signed POST. At most 2048 characters; an empty string removes the webhook and its secret. Setting or changing it issues a new signing secret.","maxLength":2048,"minLength":0},"rotate_webhook_secret":{"type":"boolean","description":"True issues a new webhook signing secret, returned once in the response; the old one stops working. Ignored when no webhook URL is set."}}},"TrustPolicyResponse":{"type":"object","description":"The organization's approved sub-processor policy and where sub-processor change alerts go.","properties":{"organization":{"type":"string","description":"The organization slug."},"entitled":{"type":"boolean","description":"Whether the organization's plan includes the Trust Pack controls, needed to turn the policy or alerts on."},"approved_providers_enabled":{"type":"boolean","description":"Whether the policy is on: calls to a provider not in approved_providers are refused before they are made."},"approved_providers":{"type":"array","description":"The approved provider ids (for example OPENAI, ANTHROPIC); empty when none is set.","items":{"type":"string"}},"notify_email":{"type":"boolean","description":"Whether the organization's owners and admins are emailed about sub-processor changes."},"webhook_url":{"type":"string","description":"The URL that receives every sub-processor change as a signed POST; absent when no webhook is set."},"webhook_secret_set":{"type":"boolean","description":"Whether a webhook signing secret exists."},"webhook_secret":{"type":"string","description":"The webhook signing secret (whsec_...), only in the response that created or rotated it; store it then. Each delivery carries X-VectorAxis-Timestamp (Unix seconds) and X-VectorAxis-Signature: sha256={hex}, the HMAC-SHA256 of \"{timestamp}.{body}\" keyed with this secret."},"updated_by":{"type":"string","description":"Who last changed the policy: the user id, or api-key:{key id} for a platform API key; absent before the first change."},"updated_at":{"type":"string","format":"date-time","description":"When the policy was last changed (ISO 8601 date-time); absent before the first change."}}},"UpdatePromptRequest":{"type":"object","description":"New name and description for a prompt.","properties":{"name":{"type":"string","description":"New display name. Omit it to keep the current name."},"description":{"type":"string","description":"New description. It replaces the current one, so omitting it (or sending null) clears the description."}}},"Prompt":{"type":"object","description":"A prompt template in the prompt library. Its content (messages, model and parameters) lives in its versions.","properties":{"id":{"type":"string","description":"The prompt's unique id (UUID)."},"slug":{"type":"string","description":"The prompt's identifier in URLs and in the `x-prompt-slug` header. Generated at creation from the name (lower case, every run of other characters as one dash, at most 40 characters) plus a dash and 8 random hex characters, for example `support-reply-3f9a1c2b`. It never changes."},"name":{"type":"string","description":"Display name, unique within the organization."},"description":{"type":"string","description":"Free-text description. Null when none is set."},"organization":{"type":"string","description":"Slug of the organization that owns the prompt."},"workspace_id":{"type":"string","format":"uuid","description":"Id (UUID) of the workspace the prompt belongs to."},"created_at":{"type":"string","format":"date-time","description":"When the prompt was created (ISO 8601)."},"updated_at":{"type":"string","format":"date-time","description":"When the prompt was created or its name or description last changed (ISO 8601). Saving versions does not change it."}}},"SetLabelRequest":{"type":"object","description":"The version a label should point at.","properties":{"version_number":{"type":"integer","format":"int32","description":"The version to point the label at (required). It must be the prompt's PUBLISHED version (409 otherwise)."}},"required":["version_number"]},"PromptLabel":{"type":"object","description":"A label of a prompt, such as `production` or `staging`: a name that points at one version. Setting a label that exists moves it to the new version.","properties":{"prompt_id":{"type":"string","description":"Id (UUID) of the prompt."},"label":{"type":"string","description":"The label's name."},"version_number":{"type":"integer","format":"int32","description":"The version the label points at."},"organization":{"type":"string","description":"Slug of the organization that owns the prompt."},"updated_at":{"type":"string","format":"date-time","description":"Not filled in by the current API: always null."}}},"OrgMember":{"type":"object","description":"A member of the organization, or a pending invitation to it.","properties":{"user_id":{"type":"string","description":"The member's user id. For a pending invitation (someone who has not signed up yet) this is the invited email address until they sign in."},"email":{"type":"string","description":"The member's email address."},"name":{"type":"string","description":"The member's display name; absent until they have signed in."},"picture_url":{"type":"string","description":"A URL of the member's profile picture; absent when there is none."},"role":{"type":"string","description":"The member's organization role: `owner` (everything, including billing and closing the organization), `admin` (everything except billing management), or `member` (sees only the workspaces they are added to).","enum":["owner","admin","member"]},"joined_at":{"type":"string","format":"date-time","description":"When the person was added or invited (ISO 8601 date-time)."},"is_pending":{"type":"boolean","description":"True for an invitation the person has not accepted yet by signing up with the invited email."}}},"UpdateMcpServerRequest":{"type":"object","description":"A partial update of an MCP server: absent fields are left unchanged.","properties":{"name":{"type":"string","description":"New display name, up to 255 characters. A blank value is ignored.","maxLength":255,"minLength":0},"description":{"type":"string","description":"New description."},"status":{"type":"string","description":"`ACTIVE` or `DISABLED`.","enum":["ACTIVE","DISABLED"]},"guardrail_slugs":{"type":"array","description":"Replaces the server's guardrails (in order, at most 10); an empty list removes them all.","items":{"type":"string"},"maxItems":10,"minItems":0}}},"McpServer":{"type":"object","description":"An MCP server: a workspace's endpoint on a connector, which agents and MCP clients reach at `url`. It uses the connector's URL, credentials and capabilities, and can only narrow them.","properties":{"id":{"type":"string","format":"uuid","description":"The server's ID (UUID)."},"slug":{"type":"string","description":"The server's slug (`mcps-` followed by 16 characters), used in its URL and the API paths."},"organization":{"type":"string","description":"The organization that owns it."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace it belongs to (UUID)."},"integration_slug":{"type":"string","description":"The connector it serves. Absent if the connector is gone."},"integration_name":{"type":"string","description":"The connector's name."},"name":{"type":"string","description":"Display name."},"description":{"type":"string","description":"Description."},"status":{"type":"string","description":"`ACTIVE` or `DISABLED`.","enum":["ACTIVE","DISABLED"]},"default_user_access":{"type":"string","description":"`ALLOW` or `DENY`: whether a person with no explicit entry may use it (see the user access endpoint).","enum":["ALLOW","DENY"]},"integration_accessible":{"type":"boolean","description":"`false` when the workspace has lost access to the connector, or the connector is disabled: the server stays registered but cannot be used."},"created_by":{"type":"string","description":"The user who created it."},"created_at":{"type":"string","format":"date-time","description":"When it was created (ISO 8601)."},"updated_at":{"type":"string","format":"date-time","description":"When it was last changed (ISO 8601)."},"url":{"type":"string","description":"The gateway URL to configure in an MCP client, for example `https://mcp.vectoraxis.ai/s/{slug}`."},"guardrail_slugs":{"type":"array","description":"Guardrails run on every call through this server, after the connector's own. Empty when there are none.","items":{"type":"string"}}}},"McpUserAccessEntry":{"type":"object","description":"One person's explicit access to an MCP server, overriding its `default_user_access`.","properties":{"user_id":{"type":"string","description":"The person's user ID. They must be a member of the server's workspace.","minLength":1},"email":{"type":"string","description":"Read-only: the person's email, for display."},"enabled":{"type":"boolean","description":"`true` allows the person, `false` denies them."}},"required":["enabled","user_id"]},"McpUserAccessSettings":{"type":"object","description":"Who may use an MCP server as themselves, through an MCP client they connected with OAuth. A person must be a member of the server's workspace; then their entry, or without one `default_user_access`, decides. Agents on an MCP key are governed by the key instead. In an update an absent field is left unchanged.","properties":{"default_user_access":{"type":"string","description":"`ALLOW` or `DENY`: access for a person with no entry. Default `ALLOW`.","enum":["ALLOW","DENY"]},"users":{"type":"array","description":"Per-person entries, at most 1000, without duplicates. Replaces the whole list when sent.","items":{"$ref":"#/components/schemas/McpUserAccessEntry"},"maxItems":1000,"minItems":0}}},"McpServerRequestPolicy":{"type":"object","description":"What an MCP server lets its upstream ask for while it answers a call: sampling (an LLM completion, which the gateway runs on a virtual key), elicitation (input from the person, relayed to the client), roots (the folders or URIs the client works in, answered from an allowlist) and how many rounds of such requests one call may take. In an update every field is optional and an absent one is left unchanged; `sampling_spent_usd` is read-only.","properties":{"sampling_enabled":{"type":"boolean","description":"Whether the upstream may ask for LLM completions. Default `false`. Turning it on needs `sampling_virtual_key` and `sampling_model`."},"sampling_virtual_key":{"type":"string","description":"The slug of a virtual key in the server's workspace; sampling completions run, and are billed, on it. It must not be disabled or expired, and must allow `sampling_model`. Empty clears it.","maxLength":64,"minLength":0},"sampling_model":{"type":"string","description":"The model every sampling request runs on, up to 255 characters; the upstream's model preferences are ignored. Empty clears it.","maxLength":255,"minLength":0},"sampling_max_tokens":{"type":"integer","format":"int32","description":"Most tokens one sampling completion may produce, 1 to 32000. Absent: the gateway default (1024).","maximum":32000,"minimum":1},"clear_sampling_max_tokens":{"type":"boolean","description":"`true` in an update removes the server's token cap, back to the gateway default."},"sampling_budget_usd":{"type":"number","description":"Sampling spend allowed per calendar month (UTC), in USD. Absent: no cap. 0 stops all sampling.","minimum":0},"clear_sampling_budget":{"type":"boolean","description":"`true` in an update removes the budget."},"sampling_spent_usd":{"type":"number","description":"Read-only: what sampling has cost this calendar month (UTC), in USD."},"elicitation_enabled":{"type":"boolean","description":"Whether the upstream may ask the person for input. Default `true`. Requests that ask for a credential are always refused, and guardrails scan each request."},"elicitation_url_mode":{"type":"boolean","description":"Whether the upstream may send the person to a web page (an https URL) instead of a form. Default `false`."},"roots_enabled":{"type":"boolean","description":"Whether the upstream may ask which roots the client works in; it is answered with `allowed_roots`. Default `false`."},"allowed_roots":{"type":"array","description":"The root URIs the upstream may learn, for example `file:///home/agent/project`, at most 20. Absolute URIs with no user info or fragment. Replaces the list when sent.","items":{"type":"string","maxLength":2048,"minLength":0},"maxItems":20,"minItems":0},"max_nesting_depth":{"type":"integer","format":"int32","description":"How many rounds of sampling, elicitation or roots requests one call may take, 1 to 10. Default 3.","maximum":10,"minimum":1}}},"McpCapabilityUpdate":{"type":"object","description":"One capability change; absent fields are left unchanged. On an MCP server only `enabled` applies (it switches the capability for that server), and `pin` is refused.","properties":{"id":{"type":"string","format":"uuid","description":"The capability's ID (UUID). It must belong to the connector (or to the server's connector)."},"enabled":{"type":"boolean","description":"Switch the capability on or off."},"pin":{"type":"boolean","description":"`true` approves the current definition, clearing drift. Connectors only."},"release":{"type":"boolean","description":"`true` serves a quarantined definition despite its scan findings. Releases this exact definition only: a later change is scanned again. A 400 when it is not quarantined."},"is_privileged":{"type":"boolean","description":"Tools only: refuse the tool for a caller that received untrusted content recently, unless approved."},"requires_approval":{"type":"boolean","description":"Tools only: hold every call until a person approves it."},"trusted_output":{"type":"boolean","description":"Mark what it returns as trusted, so it does not make the caller untrusted."}},"required":["id"]},"UpdateMcpCapabilitiesRequest":{"type":"object","description":"Changes to several capabilities at once, applied together.","properties":{"capabilities":{"type":"array","description":"The changes, one per capability. At least one.","items":{"$ref":"#/components/schemas/McpCapabilityUpdate"},"minItems":1}},"required":["capabilities"]},"McpCapability":{"type":"object","description":"A capability (tool, prompt, resource or resource template) the upstream exposes, with the gateway's settings for it. The definition is pinned when first seen; a later change to it is drift, and the capability is refused on calls until an admin pins the new definition.","properties":{"id":{"type":"string","format":"uuid","description":"The capability's ID (UUID), used to update it."},"type":{"type":"string","description":"`TOOL`, `PROMPT`, `RESOURCE` or `RESOURCE_TEMPLATE`.","enum":["TOOL","PROMPT","RESOURCE","RESOURCE_TEMPLATE"]},"identifier":{"type":"string","description":"What identifies it at the upstream: the name of a tool or prompt, the URI of a resource, the URI template of a resource template."},"name":{"type":"string","description":"The capability's name, as the upstream gives it."},"title":{"type":"string","description":"Human-readable title, when the upstream gives one."},"description":{"type":"string","description":"Description, as the upstream gives it."},"annotations":{"description":"Tool annotations (hints such as read-only or destructive), as a JSON object, when the upstream gives them."},"input_schema":{"description":"Tools: the JSON Schema of the arguments."},"output_schema":{"description":"Tools: the JSON Schema of the structured result, when the upstream gives one."},"arguments":{"description":"Prompts: the prompt's arguments, as the upstream lists them."},"uri":{"type":"string","description":"Resources: the resource URI."},"uri_template":{"type":"string","description":"Resource templates: the URI template."},"mime_type":{"type":"string","description":"Resources and resource templates: the MIME type, when given."},"schema_hash":{"type":"string","description":"SHA-256 of the current definition (hex)."},"pinned_schema_hash":{"type":"string","description":"SHA-256 of the approved (pinned) definition."},"drifted":{"type":"boolean","description":"`true` when the current definition differs from the pinned one. A drifted capability is refused until it is pinned again."},"scanned":{"type":"boolean","description":"`true` when the current definition has been scanned for tool poisoning (hidden instructions in its description or schema). `false` for a definition synced before scanning was available."},"scan_findings":{"description":"What the scan found in the current definition: a list of objects with `check_type`, `description` and `field`. Absent when not scanned."},"quarantined":{"type":"boolean","description":"`true` when the scan found tool poisoning and no admin has released this definition: it is refused on calls and hidden from listings."},"released_by":{"type":"string","description":"The user who released the current definition despite its findings. Absent unless released."},"released_at":{"type":"string","format":"date-time","description":"When the current definition was released (ISO 8601). Absent unless released."},"is_privileged":{"type":"boolean","description":"Tools: `true` refuses the tool for a caller that received untrusted content recently (a result from a tool not marked `trusted_output`), unless a person approves that exact call. Tools of `OPENAPI` and `HTTP` connectors other than GET and HEAD start privileged."},"requires_approval":{"type":"boolean","description":"Tools: `true` holds every call until a person approves that exact call; the agent's identical retry then goes ahead once."},"trusted_output":{"type":"boolean","description":"`true`: what it returns does not make the caller untrusted. Default `false`."},"enabled":{"type":"boolean","description":"Whether the capability is switched on for the connector. A capability that appears after the first sync starts off, and every tool of an `OPENAPI` or `HTTP` connector starts off."},"status":{"type":"string","description":"`ACTIVE` (listed by the upstream on the last sync) or `REMOVED`.","enum":["ACTIVE","REMOVED"]},"server_enabled":{"type":"boolean","description":"In a server's listing: whether that server has it switched on. Absent in a connector's listing."},"effective_enabled":{"type":"boolean","description":"Whether a call to it would be allowed: enabled, active, on for the server, not drifted and not quarantined."},"first_seen_at":{"type":"string","format":"date-time","description":"When a sync first found it (ISO 8601)."},"last_seen_at":{"type":"string","format":"date-time","description":"When a sync last found it (ISO 8601)."}}},"McpCapabilityListResponse":{"type":"object","description":"The capabilities of a connector, or of an MCP server's connector as seen from that server.","properties":{"data":{"type":"array","description":"The capabilities, all of them (not paginated).","items":{"$ref":"#/components/schemas/McpCapability"}},"total":{"type":"integer","format":"int64","description":"How many there are."}}},"UpdateMcpKeyRequest":{"type":"object","description":"A partial update of an MCP key: absent fields are left unchanged; the `clear_*` switches remove a value. The secret is changed only by rotating the key.","properties":{"name":{"type":"string","description":"New display name, up to 255 characters.","maxLength":255,"minLength":0},"tool_allowlist":{"type":"array","description":"Replaces the allowlist (same format as on create). An empty list allows no tool.","items":{"type":"string"},"maxItems":500,"minItems":0},"clear_tool_allowlist":{"type":"boolean","description":"`true` removes the allowlist: the key may call every tool the registry allows."},"rate_limit_rpm":{"type":"integer","format":"int32","description":"New per-minute limit (at least 1).","minimum":1},"rate_limit_rpd":{"type":"integer","format":"int32","description":"New per-day limit (at least 1).","minimum":1},"clear_rate_limits":{"type":"boolean","description":"`true` removes both of the key's own rate limits. A limit sent in the same request is then applied."}}},"McpKey":{"type":"object","description":"An MCP key: the `va_` key an agent presents to the MCP Gateway. It works only on the gateway (an MCP server's URL and the gateway's own server), never on the VectorAxis API. The secret is returned once, when the key is created or rotated.","properties":{"id":{"type":"string","format":"uuid","description":"The key's ID (UUID), used in the API paths."},"name":{"type":"string","description":"Display name."},"organization":{"type":"string","description":"The organization that owns it."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace it belongs to (UUID)."},"key_hint":{"type":"string","description":"The last four characters of the key."},"status":{"type":"string","description":"`ACTIVE` or `REVOKED`."},"tool_allowlist":{"type":"array","description":"The tools it may call (`{server slug}/{tool name}` or `{server slug}/*`). Absent: every tool the registry allows.","items":{"type":"string"}},"rate_limit_rpm":{"type":"integer","format":"int32","description":"Gateway calls per minute. Absent: only the plan's per-workspace limit."},"rate_limit_rpd":{"type":"integer","format":"int32","description":"Gateway calls per day. Absent: no daily limit of its own."},"expires_at":{"type":"string","format":"date-time","description":"When it stops working (ISO 8601). Absent: never."},"last_used_at":{"type":"string","format":"date-time","description":"When it was last used on the gateway (ISO 8601)."},"created_by":{"type":"string","description":"The user who created it."},"created_at":{"type":"string","format":"date-time","description":"When it was created (ISO 8601)."}}},"McpHttpTool":{"type":"object","description":"One endpoint of an `HTTP` connector, declared by hand: a tool that becomes one HTTP request. Every argument in `input_schema` that is not a path placeholder and not named in `query` or `headers` goes in the body (JSON or form); for GET, HEAD and DELETE it goes in the query string instead.","properties":{"name":{"type":"string","description":"The tool's name, up to 128 characters.","maxLength":128,"minLength":0},"title":{"type":"string","description":"Human-readable title, up to 255 characters.","maxLength":255,"minLength":0},"description":{"type":"string","description":"What the tool does, up to 4000 characters. Agents read it to choose the tool.","maxLength":4000,"minLength":0},"method":{"type":"string","description":"The HTTP method: `GET`, `POST`, `PUT`, `PATCH`, `DELETE` or `HEAD`.","minLength":1},"path":{"type":"string","description":"The path, relative to the connector's base URL, up to 2048 characters. May hold `{name}` placeholders filled from arguments.","maxLength":2048,"minLength":0},"query":{"type":"array","description":"Arguments sent as query parameters.","items":{"type":"string"}},"headers":{"type":"array","description":"Arguments sent as request headers.","items":{"type":"string"}},"input_schema":{"type":"object","additionalProperties":{},"description":"A JSON Schema of type `object`; its properties are the tool's arguments."},"body_format":{"type":"string","description":"How the body is encoded: `json` (default) or `form`."}},"required":["method","name","path"]},"McpOAuthClientConfig":{"type":"object","description":"OAuth settings for a connector that authenticates upstream with OAuth. `OAUTH_CLIENT_CREDENTIALS` needs `client_id` and `client_secret`: a client you registered at the upstream's authorization server. For `OAUTH_AUTO` on an MCP server they are optional: without a client the gateway registers itself; give one when the upstream requires pre-registration. On an `OPENAPI` or `HTTP` connector, OAuth needs `token_endpoint`, and `OAUTH_AUTO` also needs `authorization_endpoint` and `client_id`.","properties":{"client_id":{"type":"string","description":"The OAuth client ID, up to 500 characters.","maxLength":500,"minLength":0},"client_secret":{"type":"string","description":"The client secret, up to 2000 characters. Write-only: stored encrypted, never returned.","maxLength":2000,"minLength":0,"writeOnly":true},"scopes":{"type":"string","description":"Scopes to request, space-separated, up to 1000 characters. Empty clears them.","maxLength":1000,"minLength":0},"token_endpoint":{"type":"string","description":"The upstream token endpoint, up to 2000 characters. On an MCP server it skips discovery for client credentials. It must pass the egress policy.","maxLength":2000,"minLength":0},"authorization_endpoint":{"type":"string","description":"`OAUTH_AUTO` on an `OPENAPI` or `HTTP` connector: where people sign in (an https URL, up to 2000 characters). An MCP server's is discovered, so it is refused there.","maxLength":2000,"minLength":0}}},"UpdateMcpIntegrationRequest":{"type":"object","description":"A partial update of a connector: absent fields are left unchanged. Changing the URL, spec or credentials marks a synced connector `STALE` until it is synced again.","properties":{"name":{"type":"string","description":"New display name, up to 255 characters. A blank value is ignored.","maxLength":255,"minLength":0},"description":{"type":"string","description":"New description."},"url":{"type":"string","description":"New upstream URL (or base URL for a REST connector), up to 2048 characters; it must pass the egress policy.","maxLength":2048,"minLength":0},"auth_type":{"type":"string","description":"New auth type: `NONE`, `HEADERS`, `OAUTH_AUTO` or `OAUTH_CLIENT_CREDENTIALS`.","enum":["NONE","HEADERS","OAUTH_AUTO","OAUTH_CLIENT_CREDENTIALS"]},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"`HEADERS` auth: replaces the stored headers. Write-only. Switching back to `HEADERS` without sending headers keeps the stored set."},"oauth":{"$ref":"#/components/schemas/McpOAuthClientConfig","description":"OAuth settings, for the OAuth auth types only. Changing `client_id` resets the stored client registration."},"spec_url":{"type":"string","description":"`OPENAPI` only: a new spec URL. Empty clears it (an uploaded document must then be kept or given).","maxLength":2048,"minLength":0},"spec_content":{"type":"string","description":"`OPENAPI` only: a new uploaded document, replacing the stored one. Empty clears it."},"spec_format":{"type":"string","description":"`OPENAPI` only: the format of `spec_content`, `JSON` or `YAML`. Required with `spec_content`.","enum":["JSON","YAML"]},"http_tools":{"type":"array","description":"`HTTP` only: replaces the declared endpoints. At most 200.","items":{"$ref":"#/components/schemas/McpHttpTool"},"maxItems":200,"minItems":0},"query_params":{"type":"object","additionalProperties":{"type":"string"},"description":"Query-parameter credentials (`OPENAPI` and `HTTP`, `HEADERS` auth): replaces the stored set; empty clears it."},"global_workspace_access":{"type":"boolean","description":"Organization-level connectors only: `true` shares it with every workspace. Setting `true` on a workspace-owned connector is a 400."},"org_connection_for_users":{"type":"boolean","description":"`OAUTH_AUTO` only: whether a signed-in person without their own connected account may use the organization connection. Changing it requires an organization admin."},"status":{"type":"string","description":"`ACTIVE` or `DISABLED`. A disabled connector cannot be synced or used by new servers.","enum":["ACTIVE","DISABLED"]},"guardrail_slugs":{"type":"array","description":"Replaces the connector's guardrails (in order, at most 10); an empty list removes them all.","items":{"type":"string"},"maxItems":10,"minItems":0}}},"McpIntegration":{"type":"object","description":"A connector: an upstream MCP server or REST API that MCP servers in workspaces are built on. Credential values are never returned, only their names.","properties":{"id":{"type":"string","format":"uuid","description":"The connector's ID (UUID)."},"slug":{"type":"string","description":"The connector's slug (`mcpi-` followed by 16 characters), used in the API paths."},"organization":{"type":"string","description":"The organization that owns it."},"workspace_id":{"type":"string","format":"uuid","description":"The owning workspace (UUID). Absent for an organization-level connector."},"name":{"type":"string","description":"Display name."},"description":{"type":"string","description":"Description."},"url":{"type":"string","description":"The upstream URL (the base URL for a REST connector)."},"kind":{"type":"string","description":"`MCP`, `OPENAPI` or `HTTP`.","enum":["MCP","OPENAPI","HTTP"]},"spec_url":{"type":"string","description":"`OPENAPI`: where the document is fetched from."},"has_spec_document":{"type":"boolean","description":"`OPENAPI` and `HTTP`: whether an uploaded document is stored. The document itself is not returned."},"spec_format":{"type":"string","description":"`OPENAPI`: the format of the uploaded document, `JSON` or `YAML`.","enum":["JSON","YAML"]},"spec_hash":{"type":"string","description":"`OPENAPI` and `HTTP`: SHA-256 of the spec the last sync read."},"http_tools":{"type":"array","description":"`HTTP`: the declared endpoints.","items":{"$ref":"#/components/schemas/McpHttpTool"}},"query_param_names":{"type":"array","description":"Names of the query-parameter credentials. Their values are never returned.","items":{"type":"string"}},"transport":{"type":"string","description":"The upstream transport: `HTTP`.","enum":["HTTP"]},"auth_type":{"type":"string","description":"`NONE`, `HEADERS`, `OAUTH_AUTO` or `OAUTH_CLIENT_CREDENTIALS`.","enum":["NONE","HEADERS","OAUTH_AUTO","OAUTH_CLIENT_CREDENTIALS"]},"header_names":{"type":"array","description":"Names of the stored credential headers. Their values are never returned.","items":{"type":"string"}},"oauth":{"$ref":"#/components/schemas/McpIntegrationOAuth","description":"The OAuth client registration. OAuth auth types only."},"global_workspace_access":{"type":"boolean","description":"Whether every workspace in the organization may use it."},"org_connection_for_users":{"type":"boolean","description":"`OAUTH_AUTO`: whether a signed-in person without their own connected account may use the organization connection."},"status":{"type":"string","description":"`ACTIVE` or `DISABLED`.","enum":["ACTIVE","DISABLED"]},"protocol_version":{"type":"string","description":"The MCP protocol version the upstream spoke on the last sync."},"protocol_era":{"type":"string","description":"`MODERN` or `LEGACY`, from `protocol_version`.","enum":["MODERN","LEGACY"]},"server_name":{"type":"string","description":"The name the upstream reported on the last sync (a REST connector: the spec's title)."},"server_version":{"type":"string","description":"The version the upstream reported on the last sync."},"instructions":{"type":"string","description":"Usage instructions the upstream sent for agents, if any."},"sync_status":{"type":"string","description":"`NEVER`, `OK`, `FAILED` or `STALE`.","enum":["NEVER","OK","FAILED","STALE"]},"sync_error":{"type":"string","description":"Why the last sync failed. Absent unless `sync_status` is `FAILED`."},"last_synced_at":{"type":"string","format":"date-time","description":"When the last successful sync finished (ISO 8601)."},"last_sync_attempt_at":{"type":"string","format":"date-time","description":"When a sync was last attempted (ISO 8601)."},"created_by":{"type":"string","description":"The user who created it."},"created_at":{"type":"string","format":"date-time","description":"When it was created (ISO 8601)."},"updated_at":{"type":"string","format":"date-time","description":"When it was last changed (ISO 8601)."},"guardrail_slugs":{"type":"array","description":"Guardrails run on every call through this connector, in order. Empty when there are none.","items":{"type":"string"}}}},"McpIntegrationOAuth":{"type":"object","description":"A connector's OAuth client registration with its upstream. The client secret is never returned.","properties":{"client_id":{"type":"string","description":"The OAuth client ID the gateway uses at the upstream."},"registration":{"type":"string","description":"How the client was registered: `PRE_REGISTERED` (given by you), `CIMD` (a client ID metadata document) or `DCR` (dynamic client registration). Absent until the first sign-in or token request."},"has_client_secret":{"type":"boolean","description":"`true` when a client secret is stored."},"issuer":{"type":"string","description":"The upstream authorization server the registration is bound to."},"scopes":{"type":"string","description":"The scopes requested, space-separated."},"authorization_endpoint":{"type":"string","description":"Where people sign in. Shown for `OPENAPI` and `HTTP` connectors only."},"token_endpoint":{"type":"string","description":"The upstream token endpoint."}}},"McpWorkspaceAccessEntry":{"type":"object","description":"Whether one workspace may use an organization-level connector.","properties":{"workspace_id":{"type":"string","format":"uuid","description":"The workspace (UUID)."},"enabled":{"type":"boolean","description":"`true` lets the workspace use the connector, `false` does not."}},"required":["enabled","workspace_id"]},"UpdateMcpWorkspaceAccessRequest":{"type":"object","description":"Changes which workspaces may use an organization-level connector. Listed workspaces are added or updated; workspaces not listed keep their current setting.","properties":{"global_workspace_access":{"type":"boolean","description":"`true` lets every workspace use the connector, whatever the entries say. Absent: unchanged."},"workspaces":{"type":"array","description":"Per-workspace settings to add or update. Each workspace must belong to the organization.","items":{"$ref":"#/components/schemas/McpWorkspaceAccessEntry"}}}},"McpWorkspaceAccess":{"type":"object","description":"Which workspaces may use a connector.","properties":{"global_workspace_access":{"type":"boolean","description":"Whether every workspace in the organization may use it."},"owner_workspace_id":{"type":"string","format":"uuid","description":"The owning workspace (UUID). Absent for an organization-level connector."},"workspaces":{"type":"array","description":"The per-workspace settings of an organization-level connector.","items":{"$ref":"#/components/schemas/McpWorkspaceAccessEntry"}}}},"GuardrailCheck":{"type":"object","description":"One check in a guardrail: which validator runs, on which side of the request, and what happens when it finds something.","properties":{"type":{"type":"string","description":"The validator's id, from `GET /v1/guardrail-validators`, for example `PII_DETECTOR`, `  REGEX_MATCH`, `banned_words` or `prompt_injection`. An unknown id is a 400. A validator of kind `LLM_JUDGE` needs a plan with AI guardrails (402 otherwise)."},"target":{"type":"string","description":"Where the check runs: `INPUT` (the request's messages, before the provider is called), `OUTPUT` (the provider's answer, before it is returned) or `BOTH`.","enum":["INPUT","OUTPUT","BOTH"]},"action":{"type":"string","description":"What a finding does: `BLOCK` (the request fails with 422), `REDACT` (the match is replaced with a placeholder and the request continues) or `MONITOR` (logged only). Use an action the validator lists in `supported_actions`.","enum":["BLOCK","REDACT","MONITOR"]},"config":{"type":"object","additionalProperties":{},"description":"The validator's settings, as a JSON object matching its `config_schema` (its `default_config` is a starting point). A config the validator rejects is a 400. Default: an empty object."}},"required":["action","target","type"]},"UpdateGuardrailRequest":{"type":"object","description":"Changes to a guardrail. Every field is optional: a field that is present replaces the stored value, an absent one leaves it unchanged.","properties":{"name":{"type":"string","description":"New display name."},"description":{"type":"string","description":"New description."},"enabled":{"type":"boolean","description":"`true` to run the guardrail, `false` to skip it."},"checks":{"type":"array","description":"The full new list of checks, replacing all current ones. Validated as on create.","items":{"$ref":"#/components/schemas/GuardrailCheck"}}}},"AttachedVirtualKey":{"type":"object","description":"A virtual key that applies this guardrail to its requests. Identity only, never credentials.","properties":{"slug":{"type":"string","description":"The virtual key's slug."},"name":{"type":"string","description":"The virtual key's display name."},"status":{"type":"string","description":"The virtual key's status: `ACTIVE`, `DISABLED`, `EXHAUSTED` or `EXPIRED`."},"workspace_id":{"type":"string","format":"uuid","description":"Id (UUID) of the virtual key's workspace. Null for a key with no workspace."}}},"GuardrailDetail":{"type":"object","description":"A guardrail with its checks and the virtual keys that apply it.","properties":{"id":{"type":"string","format":"uuid","description":"The guardrail's unique id (UUID)."},"slug":{"type":"string","description":"The guardrail's identifier in URLs, on virtual keys and in the `x-guardrail` header: `gr-` and 16 hex characters. It never changes."},"name":{"type":"string","description":"Display name, unique within the organization."},"description":{"type":"string","description":"Free-text description. Null when none is set."},"organization":{"type":"string","description":"Slug of the organization that owns the guardrail."},"workspace_id":{"type":"string","format":"uuid","description":"Id (UUID) of the workspace the guardrail belongs to."},"enabled":{"type":"boolean","description":"Whether the guardrail runs. A disabled guardrail is skipped wherever it is applied."},"checks":{"type":"array","description":"The guardrail's checks.","items":{"$ref":"#/components/schemas/GuardrailCheck"}},"attached_keys":{"type":"array","description":"The virtual keys that apply this guardrail. Filled by `GET /v1/guardrails/{slug`}; empty in the other responses.","items":{"$ref":"#/components/schemas/AttachedVirtualKey"}},"attached_key_count":{"type":"integer","format":"int32","description":"How many virtual keys apply this guardrail. Filled by `GET /v1/guardrails/{slug`}; null in the other responses."},"created_by":{"type":"string","description":"Identifier of the caller (user or API key) that created the guardrail."},"created_at":{"type":"string","format":"date-time","description":"When the guardrail was created (ISO 8601)."},"updated_at":{"type":"string","format":"date-time","description":"When the guardrail was last changed (ISO 8601)."}}},"CacheConfig":{"type":"object","description":"Response cache settings stored with a routing config or target. Requests served through a routing config are not answered from the response cache at present.","properties":{"mode":{"type":"string","description":"The cache mode: `simple` (exact match) or `semantic`. Absent: none."},"max_age_seconds":{"type":"integer","format":"int32","description":"How long a cached answer stays valid, in seconds. Absent: none."}}},"OverrideParams":{"type":"object","description":"Request parameters a routing target sets on the requests it receives, in place of the caller's. A field left out keeps the caller's value. `model`, `temperature`, `max_tokens`, `top_p` and `stop` are applied; the other fields are validated and stored but not applied at present.","properties":{"model":{"type":"string","description":"The model to call instead of the request's, e.g. `gpt-4o-mini`."},"temperature":{"type":"number","format":"double","description":"The sampling temperature, from 0 to 2."},"max_tokens":{"type":"integer","format":"int32","description":"The most tokens to generate; at least 1."},"top_p":{"type":"number","format":"double","description":"Nucleus sampling, from 0 to 1."},"frequency_penalty":{"type":"number","format":"double","description":"From -2 to 2. Stored, not applied at present."},"presence_penalty":{"type":"number","format":"double","description":"From -2 to 2. Stored, not applied at present."},"stop":{"type":"array","description":"Stop sequences; a non-empty list replaces the request's.","items":{"type":"string"}},"seed":{"type":"integer","format":"int32","description":"A sampling seed, at least 0. Stored, not applied at present."},"response_format_type":{"type":"string","description":"`json_object`, `text` or `json_schema`. Accepted, but neither applied nor returned at present.","enum":["json_object","text","json_schema"]}}},"RetryConfig":{"type":"object","description":"Retries for a routing target's provider calls. A failed call with a listed status is tried again after 1, 2, 4, ... seconds (at most 16), until `attempts` calls have been made.","properties":{"attempts":{"type":"integer","format":"int32","description":"How many calls to make in all, the first one included (`1` means no retry). From 1 to 10. Required."},"on_status_codes":{"type":"array","description":"The provider HTTP statuses to retry. Empty or absent: 429, 500, 502, 503 and 504.","items":{"type":"integer","format":"int32"}}},"required":["attempts"]},"RoutingConditionRequest":{"type":"object","description":"A rule of a `CONDITIONAL` strategy: when `query` matches the request, the request goes to the target named `then_target_name`. Rules are tried in `condition_order`; the first match wins.","properties":{"condition_order":{"type":"integer","format":"int32","description":"The rule's position: lower numbers are tried first. Required."},"query":{"type":"object","additionalProperties":{},"description":"What the request must match, as a JSON object of field paths to operator objects, all of which must hold, e.g. `{\"metadata.tier\": {\"$eq\": \"premium\"}}`. Required and not empty.\n\n- Fields: `metadata.` followed by a key of the JSON object in the request's `x-metadata` header, and `params.model`, `params.temperature`, `params.max_tokens`, `params.top_p`, `params.stream` (an omitted `stream` is `false`).\n- Operators: `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte` (numbers), `$in`, `$nin` (arrays), `$regex` (case-insensitive, must match the whole value) and `$exists` (`true` or `false`).\n- `$and` and `$or` take an array of such objects."},"then_target_name":{"type":"string","description":"The `name` of the target, at the same level as this rule, that a matching request goes to. Required."}},"required":["condition_order","query","then_target_name"]},"RoutingTargetRequest":{"type":"object","description":"One target of a routing config. A target is either a virtual key (set `virtual_key_slug`) or a nested strategy (set `strategy_mode` and its own `targets`), never both. Strategies nest at most 3 levels below the top of the config.","properties":{"name":{"type":"string","description":"The target's name, which conditions and `conditional_default_target_name` refer to. Optional otherwise."},"virtual_key_slug":{"type":"string","description":"For a virtual key target: the key's slug. The key must belong to the config's organization and not be `EXPIRED`. Requests to this target use the key's provider credential."},"weight":{"type":"number","format":"double","description":"For `LOADBALANCE`: the target's share of requests, relative to its siblings. Greater than 0. Default 1."},"order_index":{"type":"integer","format":"int32","description":"The target's position among its siblings, which sets the `FALLBACK` order and which target `SINGLE` uses. Absent: its position in the list."},"strategy_mode":{"type":"string","description":"For a nested strategy target: how it picks among its own `targets`: `SINGLE`, `LOADBALANCE`, `FALLBACK` or `CONDITIONAL`.","enum":["SINGLE","LOADBALANCE","FALLBACK","CONDITIONAL"]},"on_status_codes":{"type":"array","description":"For a nested `FALLBACK` target: the provider HTTP statuses that move on to its next target. Empty or absent: 429, 500, 502, 503 and 504.","items":{"type":"integer","format":"int32"}},"conditional_default_target_name":{"type":"string","description":"For a nested `CONDITIONAL` target: the `name` of one of its `targets`, used when no condition matches."},"conditions":{"type":"array","description":"For a nested `CONDITIONAL` target (at least one required): the rules that pick one of its targets.","items":{"$ref":"#/components/schemas/RoutingConditionRequest"}},"override_params":{"$ref":"#/components/schemas/OverrideParams","description":"For a virtual key target: request parameters to override on requests sent to it. Optional."},"cache":{"$ref":"#/components/schemas/CacheConfig","description":"Response cache settings, stored with the target. Requests served through a routing config are not answered from the response cache at present. Optional."},"retry":{"$ref":"#/components/schemas/RetryConfig","description":"For a virtual key target: its retries, in place of the config's `retry`. `attempts` must be from 1 to 10. Optional."},"request_timeout_ms":{"type":"integer","format":"int32","description":"For a virtual key target: the time limit for each call to its provider, in milliseconds. A call that takes longer fails. Absent: no limit of its own."}}},"UpdateRoutingConfigRequest":{"type":"object","description":"Changes to a routing config. `targets` is required and replaces the whole target tree, with the conditions. The other fields change when present and are kept when left out, except `on_status_codes`, which is replaced on every update. The organization and workspace cannot be changed.","properties":{"name":{"type":"string","description":"The config's new name. Left out: unchanged. The slug does not change."},"description":{"type":"string","description":"The new description. Left out: unchanged."},"strategy_mode":{"type":"string","description":"The new strategy: `SINGLE`, `LOADBALANCE`, `FALLBACK` or `CONDITIONAL` (see \"Create a routing config\"). Left out: unchanged.","enum":["SINGLE","LOADBALANCE","FALLBACK","CONDITIONAL"]},"on_status_codes":{"type":"array","description":"For `FALLBACK`: the provider HTTP statuses that move a request on to the next target. Replaced on every update: left out or empty, the default (429, 500, 502, 503 and 504) applies.","items":{"type":"integer","format":"int32"}},"conditional_default_target_name":{"type":"string","description":"For `CONDITIONAL`: the target used when no condition matches. Left out: unchanged."},"targets":{"type":"array","description":"The complete new list of targets, which replaces the old tree. Required, at least one.","items":{"$ref":"#/components/schemas/RoutingTargetRequest"}},"conditions":{"type":"array","description":"For `CONDITIONAL`: the complete new list of conditions, replaced together with `targets`. Left out: the config has no conditions.","items":{"$ref":"#/components/schemas/RoutingConditionRequest"}},"cache":{"$ref":"#/components/schemas/CacheConfig","description":"Response cache settings; each field present replaces the stored one. Requests served through a routing config are not answered from the response cache at present. Left out: unchanged."},"retry":{"$ref":"#/components/schemas/RetryConfig","description":"Retries for every target that has no `retry` of its own; each field present replaces the stored one. Left out: unchanged."},"request_timeout_ms":{"type":"integer","format":"int32","description":"A time limit in milliseconds, stored with the config (see \"Create a routing config\"). Left out: unchanged."}}},"RoutingConditionResponse":{"type":"object","description":"A rule of a `CONDITIONAL` strategy: a request that matches `query` goes to the target named `then_target_name`. Rules are tried in `condition_order`; the first match wins.","properties":{"condition_order":{"type":"integer","format":"int32","description":"The rule's position: lower numbers are tried first."},"query":{"type":"object","additionalProperties":{},"description":"What the request must match: field paths (`metadata.*`, `params.*`) to operator objects, as described for the rule's request form."},"then_target_name":{"type":"string","description":"The `name` of the target a matching request goes to."},"id":{"type":"string","format":"uuid","description":"The rule's id (UUID). Changes whenever the config's targets are replaced by an update."}},"required":["condition_order","query","then_target_name"]},"RoutingConfigDetail":{"type":"object","description":"A routing config with its full target tree, conditions and settings.","properties":{"id":{"type":"string","format":"uuid","description":"The config's id (UUID)."},"slug":{"type":"string","description":"The config's slug: send it in the `x-config` header, and use it to manage the config."},"name":{"type":"string","description":"The config's name, unique within the organization."},"description":{"type":"string","description":"A free-text description. Absent when none was set."},"organization":{"type":"string","description":"The slug of the organization the config belongs to."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace the config belongs to (UUID)."},"strategy_mode":{"type":"string","description":"How a request picks among `targets`: `SINGLE` (the first), `LOADBALANCE` (at random, by `weight`), `FALLBACK` (in order, moving on at a status in `on_status_codes`) or `CONDITIONAL` (by `conditions`).","enum":["SINGLE","LOADBALANCE","FALLBACK","CONDITIONAL"]},"on_status_codes":{"type":"array","description":"For `FALLBACK`: the statuses that move on to the next target. Absent: 429, 500, 502, 503 and 504.","items":{"type":"integer","format":"int32"}},"conditional_default_target_name":{"type":"string","description":"For `CONDITIONAL`: the target used when no condition matches. Absent: none (such a request fails with 424)."},"targets":{"type":"array","description":"The top-level targets in order; nested strategies carry their own `targets`.","items":{"$ref":"#/components/schemas/RoutingTargetResponse"}},"conditions":{"type":"array","description":"For `CONDITIONAL`: the top-level rules, in `condition_order`. Empty otherwise.","items":{"$ref":"#/components/schemas/RoutingConditionResponse"}},"cache":{"$ref":"#/components/schemas/CacheConfig","description":"Stored response cache settings (not applied to routed requests at present). Absent when none were set."},"retry":{"$ref":"#/components/schemas/RetryConfig","description":"Retries for every target without its own `retry`. Absent: no retries."},"request_timeout_ms":{"type":"integer","format":"int32","description":"The stored time limit in milliseconds (applied only on virtual key targets). Absent when none was set."},"schema_version":{"type":"integer","format":"int32","description":"The version of the config format. Currently always 1."},"created_by":{"type":"string","description":"Who created the config: an identifier of the user, or of the API key, that made the request."},"created_at":{"type":"string","format":"date-time","description":"When the config was created (ISO 8601 date-time)."},"updated_at":{"type":"string","format":"date-time","description":"When the config last changed (ISO 8601 date-time)."}}},"RoutingTargetResponse":{"type":"object","description":"One target of a routing config: a virtual key (`virtual_key_slug`) or a nested strategy (`strategy_mode` with its own `targets`).","properties":{"name":{"type":"string","description":"The target's name, which conditions refer to. Absent when none was set."},"virtual_key_slug":{"type":"string","description":"For a virtual key target: the key's slug. Absent for a nested strategy target."},"weight":{"type":"number","format":"double","description":"For `LOADBALANCE`: the target's share of requests, relative to its siblings. Default 1."},"order_index":{"type":"integer","format":"int32","description":"The target's position among its siblings (the `FALLBACK` order)."},"strategy_mode":{"type":"string","description":"For a nested strategy target: `SINGLE`, `LOADBALANCE`, `FALLBACK` or `CONDITIONAL`. Absent for a virtual key target.","enum":["SINGLE","LOADBALANCE","FALLBACK","CONDITIONAL"]},"on_status_codes":{"type":"array","description":"For a nested `FALLBACK` target: the statuses that move on to its next target. Absent: the default.","items":{"type":"integer","format":"int32"}},"conditional_default_target_name":{"type":"string","description":"For a nested `CONDITIONAL` target: the target used when no condition matches."},"conditions":{"type":"array","description":"For a nested `CONDITIONAL` target: its rules, in `condition_order`. Empty otherwise.","items":{"$ref":"#/components/schemas/RoutingConditionResponse"}},"override_params":{"$ref":"#/components/schemas/OverrideParams","description":"For a virtual key target: the request parameters it overrides. Absent when none are set."},"cache":{"$ref":"#/components/schemas/CacheConfig","description":"Stored response cache settings (not applied to routed requests at present). Absent when none were set."},"retry":{"$ref":"#/components/schemas/RetryConfig","description":"For a virtual key target: its own retries, in place of the config's. Absent: the config's apply."},"request_timeout_ms":{"type":"integer","format":"int32","description":"For a virtual key target: the time limit per provider call, in milliseconds. Absent: no limit of its own."},"id":{"type":"string","format":"uuid","description":"The target's id (UUID). Changes whenever the config's targets are replaced by an update."}}},"OrgCreditAccount":{"type":"object","description":"The organization's credit account: the USD balance that platform (PLATFORM) virtual keys draw on.","properties":{"id":{"type":"string","format":"uuid","description":"The account's id (UUID); absent for an organization that has never bought credits."},"organization":{"type":"string","description":"The slug of the organization."},"balance_usd":{"type":"number","format":"double","description":"The credit left, in USD."},"total_purchased_usd":{"type":"number","format":"double","description":"All credit added so far (purchases and auto-recharges), in USD."},"total_consumed_usd":{"type":"number","format":"double","description":"All credit used by PLATFORM keys so far, in USD."},"auto_recharge_enabled":{"type":"boolean","description":"Whether credit is bought automatically when the balance falls below `auto_recharge_threshold_usd`."},"auto_recharge_threshold_usd":{"type":"number","format":"double","description":"The balance, in USD, below which an auto-recharge is charged."},"auto_recharge_amount_usd":{"type":"number","format":"double","description":"How much credit each auto-recharge buys, in USD."},"has_payment_method":{"type":"boolean","description":"Whether a card is saved for auto-recharge (saved by a credit purchase)."},"has_billing_account":{"type":"boolean","description":"Whether the organization has a customer account with the payment provider, so the billing portal can be opened."},"withdrawal_status":{"type":"string","description":"`PENDING` while a withdrawal of the balance is being refunded, else `NONE`.","enum":["NONE","PENDING"]},"withdrawal_amount_usd":{"type":"number","format":"double","description":"The amount being withdrawn, in USD; absent when no withdrawal is pending."},"withdrawal_initiated_at":{"type":"string","format":"date-time","description":"When the pending withdrawal was started (ISO 8601 date-time); absent when none is pending."},"created_at":{"type":"string","format":"date-time","description":"When the account was created (ISO 8601 date-time)."},"updated_at":{"type":"string","format":"date-time","description":"When the account last changed (ISO 8601 date-time)."}}},"CreateWorkspaceRequest":{"type":"object","description":"A new workspace.","properties":{"name":{"type":"string","description":"The workspace's display name."},"slug":{"type":"string","description":"The workspace's slug, unique within the organization. Omit to derive it from `name` (lower case, spaces as dashes, other punctuation removed)."},"description":{"type":"string","description":"An optional description."},"organization":{"type":"string","description":"The slug of the organization to create the workspace in."}},"required":["name","organization"]},"CreateVirtualKeyRequest":{"type":"object","description":"A virtual key to create.\n\nWith `credential_mode` `BYOK` (the default) you supply your provider keys in `credentials`; `initial_credits_usd`, `provider_whitelist` and `markup_pct` are ignored. With `PLATFORM` the key uses VectorAxis's provider accounts and is paid from the organization's credits: `initial_credits_usd` is required (greater than 0) and becomes the key's credit limit, and `credentials` and `credit_limit_usd` are ignored.","properties":{"name":{"type":"string","description":"The key's name, unique within the organization. Required."},"note":{"type":"string","description":"A free-text note about the key. Optional."},"credential_mode":{"type":"string","description":"Where the provider credentials come from: `BYOK` (your own provider keys, in `credentials`) or `PLATFORM` (VectorAxis's provider accounts, paid from your organization's credits). Default `BYOK`.","enum":["BYOK","PLATFORM"]},"credentials":{"type":"array","description":"Your provider keys, for a BYOK key: one entry per provider. Stored encrypted; only the last four characters of each are ever returned. Ignored for a PLATFORM key.","items":{"$ref":"#/components/schemas/VirtualKeyCredentialInput"}},"organization":{"type":"string","description":"The slug of the organization the key belongs to. Required."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace the key belongs to (UUID). Required."},"expires_at":{"type":"string","format":"date-time","description":"When the key expires (ISO 8601 date-time). From then on its requests are refused (403 `VIRTUAL_KEY_EXPIRED`) and its status becomes `EXPIRED`, which is final. Absent: the key never expires."},"metadata":{"type":"object","additionalProperties":{"type":"string"},"description":"Your own string key/value pairs, stored with the key. Optional."},"model_allowlist":{"type":"array","description":"The models the key may call. A request for any other model is refused (403 `MODEL_NOT_ALLOWED`). A model matches with or without its provider prefix (`openai/gpt-4o` matches `gpt-4o`). Empty or absent: every model.","items":{"type":"string"}},"credit_limit_usd":{"type":"number","format":"double","description":"The most the key may spend, in USD. Once its spend reaches the limit the key becomes `EXHAUSTED` and its requests are refused (403 `VIRTUAL_KEY_EXHAUSTED`) until the limit is raised or the spend is reset. Absent: no limit. Ignored for a PLATFORM key, whose limit is `initial_credits_usd`."},"credit_alert_threshold_usd":{"type":"number","format":"double","description":"A soft limit in USD: once the key's spend reaches it, the key carries the `ALERT_THRESHOLD_EXCEEDED` warning. Requests are not refused. Absent: no alert."},"credit_reset_policy":{"type":"string","description":"When the key's spend goes back to zero: `MONTHLY` (the 1st of each month, 00:00 UTC), `WEEKLY` (each Monday, 00:00 UTC) or `NEVER`. A reset also makes an `EXHAUSTED` key `ACTIVE`. Default `NEVER`.","enum":["MONTHLY","WEEKLY","NEVER"]},"rate_limit_rpm":{"type":"integer","format":"int32","description":"The most requests the key may make per minute (a 60-second window); over it, 429. Absent: no limit."},"rate_limit_tpm":{"type":"integer","format":"int32","description":"The most tokens the key may use per minute (a 60-second window); over it, 429. Absent: no limit."},"rate_limit_rpd":{"type":"integer","format":"int32","description":"The most requests the key may make per day (a UTC calendar day); over it, 429. Absent: no limit."},"initial_credits_usd":{"type":"number","format":"double","description":"For a PLATFORM key: the credit in USD the key starts with, which is also its credit limit. Required and greater than 0 for a PLATFORM key; ignored for a BYOK key."},"provider_whitelist":{"type":"array","description":"For a PLATFORM key: the only providers it may use, as provider ids (e.g. `OPENAI`, `ANTHROPIC`). A request for a model of another provider is refused (403 `PROVIDER_NOT_WHITELISTED`). Empty or absent: any provider VectorAxis serves. Ignored for a BYOK key.","items":{"type":"string"}},"guardrail_slugs":{"type":"array","description":"Slugs of guardrails to run on every request made with this key, in addition to any named in the request's `x-guardrail` header. Each must belong to the organization and, when it belongs to a workspace, to the key's workspace; no duplicates. Optional.","items":{"type":"string"}},"markup_pct":{"type":"number","format":"double","description":"For a PLATFORM key: the markup on the provider's price as a fraction (`0.06` is 6%), replacing the platform's default markup for this key. Absent: the platform default. Ignored for a BYOK key."}},"required":["name","organization","workspace_id"]},"VirtualKeyCredentialInput":{"type":"object","description":"A provider key for a BYOK virtual key, supplied when the key is created. Write-only: the provider key is stored encrypted and never returned; the key shows only its last four characters.","properties":{"provider":{"type":"string","description":"The provider id, e.g. `OPENAI` or `ANTHROPIC` (see \"List supported providers\"). Required."},"key":{"type":"string","description":"The provider API key. For `VERTEX_AI`, the Google service-account key file's JSON, as a string. Required."},"vertex_project_id":{"type":"string","description":"For `VERTEX_AI`: the Google Cloud project id to call. A request's `x-vertex-project` header overrides it. Ignored for other providers."},"vertex_region":{"type":"string","description":"For `VERTEX_AI`: the Vertex AI region (e.g. `us-central1`, or `global`). A request's `x-vertex-region` header overrides it. Ignored for other providers."}},"required":["key","provider"]},"VirtualKeyCreateResponse":{"type":"object","description":"A newly created virtual key and its API key. The API key is returned only here: store it now. Provider keys are never returned.","properties":{"slug":{"type":"string","description":"The key's slug: `vk-` followed by 16 hex characters. Use it to manage the key."},"api_key":{"type":"string","description":"The API key your applications send: the slug, a dot, then a secret. Send it as a bearer token in `Authorization` (or in `x-virtual-key`). Shown only once; only a hash of the secret is kept."},"token_hint":{"type":"string","description":"The last characters of the API key's secret, as later shown on the key as `token_hint`."},"key_hint":{"type":"string","description":"The last four characters of the first provider credential. An empty string for a PLATFORM key."}}},"TransferVirtualKeyRequest":{"type":"object","description":"Where to move a virtual key: another workspace of its organization. The key must not be `EXPIRED`.","properties":{"target_workspace_id":{"type":"string","format":"uuid","description":"The workspace to move the key to (UUID). Required, and different from the key's current workspace."}},"required":["target_workspace_id"]},"VirtualKeyRotateResponse":{"type":"object","description":"A virtual key's new API key, after a rotation. Returned only here: store it now. The previous API key (or, for a legacy key, the bare slug) no longer authenticates.","properties":{"slug":{"type":"string","description":"The key's slug, unchanged by the rotation."},"api_key":{"type":"string","description":"The new API key: the slug, a dot, then a new secret. Shown only once."},"token_hint":{"type":"string","description":"The last characters of the new secret, as later shown on the key as `token_hint`."},"rotated_at":{"type":"string","format":"date-time","description":"When the key was rotated (ISO 8601 date-time)."}},"required":["api_key","rotated_at","slug","token_hint"]},"DisableVirtualKeyRequest":{"type":"object","description":"Why a virtual key is being disabled. The whole body is optional.","properties":{"reason":{"type":"string","description":"The reason, free text. Shown on the key as `disable_reason` and returned as the message of the 403 its callers receive while it is disabled. Optional."}}},"CreateEvidenceExportRequest":{"type":"object","description":"The period an evidence bundle covers. The body and both fields are optional: the default period is the 90 days up to now, and the period can be at most 366 days long.","properties":{"start_time":{"type":"string","format":"date-time","description":"Start of the period (ISO 8601 date-time). Default: 90 days before end_time."},"end_time":{"type":"string","format":"date-time","description":"End of the period (ISO 8601 date-time). Default: now."}}},"TrustEvidenceExport":{"type":"object","description":"One evidence bundle: a signed zip of the period's Trust Pack reports, audit trails and request metadata.","properties":{"id":{"type":"string","format":"uuid","description":"The bundle id (UUID)."},"organization":{"type":"string","description":"The organization slug."},"status":{"type":"string","description":"Where the bundle is in its life. PENDING: accepted, not started. RUNNING: being built. READY: built and signed, downloadable until expires_at. FAILED: could not be built; error says why. EXPIRED: past its retention, the zip has been deleted.","enum":["PENDING","RUNNING","READY","FAILED","EXPIRED"]},"start_time":{"type":"string","format":"date-time","description":"Start of the period the bundle covers (ISO 8601 date-time)."},"end_time":{"type":"string","format":"date-time","description":"End of the period the bundle covers (ISO 8601 date-time)."},"error":{"type":"string","description":"Why the bundle could not be built; FAILED only."},"file_name":{"type":"string","description":"The zip's file name, evidence-{organization}-{start date}-{end date}.zip (dates in UTC)."},"sha256":{"type":"string","description":"SHA-256 of the zip file, hex; set once READY."},"bytes":{"type":"integer","format":"int64","description":"Size of the zip file in bytes; set once READY."},"key_id":{"type":"string","description":"Id of the key that signed the bundle; set once READY. The public key is at GET /v1/public/trust/evidence-signing-key."},"region":{"type":"string","description":"The AWS region that built the bundle; set once READY."},"created_by":{"type":"string","description":"Who started the export: the user id, or api-key:{key id} for a platform API key."},"created_at":{"type":"string","format":"date-time","description":"When the export was requested (ISO 8601 date-time)."},"completed_at":{"type":"string","format":"date-time","description":"When the bundle was built (ISO 8601 date-time); absent until then."},"expires_at":{"type":"string","format":"date-time","description":"When the zip is deleted and the bundle becomes EXPIRED (ISO 8601 date-time), 30 days after it was built; absent until READY."},"download_path":{"type":"string","description":"Path to download the zip, relative to the API base URL; READY only."}}},"SystemOneQuestion":{"type":"object","description":"One question about the state.","properties":{"type":{"type":"string","description":"The kind of answer wanted: `noul` (the probability that a statement is true), `choice` (one option from a list) or `score` (a place on an ordered rubric).","enum":["noul","choice","score"]},"instructions":{"description":"The question itself: the statement to judge, or what to choose or score."},"criteria":{"description":"For `choice`, the options to pick from; for `score`, the rubric's levels. Absent for `noul`."}},"required":["instructions","type"]},"SystemOneRequest":{"type":"object","description":"A request to System One: a state and the questions to answer about it.","properties":{"model":{"type":"string","description":"The System One model, for example `jev-latest`. With a virtual key a `provider/` prefix is removed."},"state":{"description":"What the questions are about: text or any JSON value."},"questions":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/SystemOneQuestion"},"description":"The questions to answer, keyed by a name you choose. The response has one answer per name."}},"required":["model","questions","state"]},"SystemOneAnswer":{"type":"object","description":"The answer to one question. Which fields are set depends on the question's `type`.","properties":{"type":{"type":"string","description":"The question's type: `noul`, `choice` or `score`.","enum":["noul","choice","score"]},"noul":{"type":"number","format":"double","description":"For `noul`: the probability, 0 to 1, that the statement is true. Absent otherwise."},"choice":{"type":"string","description":"For `choice`: the option picked. Absent otherwise."},"score":{"type":"number","format":"double","description":"For `score`: the place on the rubric. Absent otherwise."},"legend":{"type":"object","additionalProperties":{},"description":"What the answer's values stand for (for example the rubric levels), as TypeSafe returns it. Absent when not returned."},"probabilities":{"type":"object","additionalProperties":{"type":"number","format":"double"},"description":"For `choice`: the probability, 0 to 1, of each option. Absent when not returned."},"confidence":{"type":"number","format":"double","description":"How confident the model is in a `choice` or `score` answer, 0 to 1. Absent when not returned."}},"required":["type"]},"SystemOneResponse":{"type":"object","description":"System One's answers to a request's questions.","properties":{"model":{"type":"string","description":"The model that answered: the versioned model behind an alias such as `jev-latest`."},"answers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/SystemOneAnswer"},"description":"One answer per question, keyed by the names used in `questions`."},"usage":{"$ref":"#/components/schemas/SystemOneUsage","description":"The tokens the request used."}},"required":["answers","model","usage"]},"SystemOneUsage":{"type":"object","description":"The tokens a System One request used.","properties":{"input_tokens":{"type":"integer","format":"int32","description":"Tokens read from the state and questions."},"output_tokens":{"type":"integer","format":"int32","description":"Tokens produced."}},"required":["input_tokens","output_tokens"]},"CreatePromptRequest":{"type":"object","description":"A new prompt for the prompt library. Add its content by saving a version.","properties":{"name":{"type":"string","description":"Display name (required), unique within the organization (409 otherwise). The slug is derived from it."},"description":{"type":"string","description":"Free-text description. Optional."},"organization":{"type":"string","description":"Slug of the organization that will own the prompt (required)."},"workspace_id":{"type":"string","format":"uuid","description":"Id (UUID) of the workspace the prompt belongs to (required). It must belong to the organization."}},"required":["name","organization","workspace_id"]},"CreatePromptVersionRequest":{"type":"object","description":"A new version of a prompt. Each version is complete: nothing is carried over from the previous one, so send every message, variable and parameter. The version is created as a DRAFT with the next version number.","properties":{"messages":{"type":"array","description":"The template messages, in order (required). A message's `content` may contain `{{name`}} placeholders: a name of letters, digits and underscores that does not start with a digit.","items":{"$ref":"#/components/schemas/PromptMessage"}},"model":{"type":"string","description":"The model completions use, for example `gpt-4o`. Optional: without it every completion and test run must send `model_override`."},"temperature":{"type":"number","format":"double","description":"Sampling temperature sent with every completion. Optional."},"max_tokens":{"type":"integer","format":"int32","description":"Maximum number of tokens to generate, sent with every completion. Optional."},"top_p":{"type":"number","format":"double","description":"Nucleus-sampling value (`top_p`) sent with every completion. Optional."},"stop":{"type":"array","description":"Stop sequences sent with every completion. Optional.","items":{"type":"string"}},"variables":{"type":"array","description":"The variables the template uses, for documentation and forms. Optional and not enforced.","items":{"$ref":"#/components/schemas/PromptVariable"}},"tools":{"type":"array","description":"Tool definitions to store with the version. Optional. Completions of this prompt do not send them to the model.","items":{"$ref":"#/components/schemas/PromptTool"}}},"required":["messages"]},"PromptFunction":{"type":"object","description":"The function of a stored tool definition, in OpenAI's function-calling format.","properties":{"name":{"type":"string","description":"The function's name (required)."},"description":{"type":"string","description":"What the function does, for the model. Null when not given."},"parameters":{"type":"object","additionalProperties":{},"description":"The function's parameters as a JSON Schema object. Null when not given."}},"required":["name"]},"PromptMessage":{"type":"object","description":"One message of a prompt template.","properties":{"role":{"type":"string","description":"Who the message is from: `system`, `user`, `assistant` or `tool` (required).","enum":["system","user","assistant","tool"]},"content":{"type":"string","description":"The message text (required). Each `{{name`}} placeholder is replaced with the value of variable `  name` when the prompt is rendered or run; a placeholder with no value is left as written."}},"required":["content","role"]},"PromptTool":{"type":"object","description":"A tool definition in OpenAI's function-calling format, stored with a prompt version.","properties":{"type":{"type":"string","description":"The tool type: `function` (required)."},"function":{"$ref":"#/components/schemas/PromptFunction","description":"The function the tool exposes (required)."}},"required":["function","type"]},"PromptVariable":{"type":"object","description":"A variable a prompt template declares. Declarations describe the template; they are not enforced.","properties":{"name":{"type":"string","description":"The variable's name, as written in `{{name`}} (required)."},"description":{"type":"string","description":"What the variable is for. Null when not given."},"default_value":{"type":"string","description":"A suggested value. Informational: it is not substituted when a request leaves the variable out."},"required":{"type":"boolean","description":"Whether callers are expected to supply the variable. Informational, not enforced. Default `false`."}},"required":["name"]},"PromptVersion":{"type":"object","description":"A version of a prompt: the messages, model and parameters a completion uses. A version is never edited: each change is saved as a new version with the next number.","properties":{"id":{"type":"string","description":"The version's unique id (UUID)."},"prompt_id":{"type":"string","description":"Id (UUID) of the prompt the version belongs to."},"version_number":{"type":"integer","format":"int32","description":"The version's number within the prompt, from 1, incremented by every save or rollback."},"messages":{"type":"array","description":"The template messages, in order. A message's `content` may contain `{{name`}} placeholders.","items":{"$ref":"#/components/schemas/PromptMessage"}},"model":{"type":"string","description":"The model completions use, for example `gpt-4o`. Null when none was set: a completion or test run must then send `model_override`."},"temperature":{"type":"number","format":"double","description":"Sampling temperature sent with every completion of this version. Null when not set (the provider's default applies)."},"max_tokens":{"type":"integer","format":"int32","description":"Maximum number of tokens to generate, sent with every completion of this version. Null when not set."},"top_p":{"type":"number","format":"double","description":"Nucleus-sampling value (`top_p`) sent with every completion of this version. Null when not set."},"stop":{"type":"array","description":"Stop sequences sent with every completion of this version. Null or empty when none.","items":{"type":"string"}},"variables":{"type":"array","description":"The variables the template declares. Descriptive only: rendering substitutes whichever variables a request sends.","items":{"$ref":"#/components/schemas/PromptVariable"}},"tools":{"type":"array","description":"Tool definitions stored with the version. They are stored and returned, but completions of this prompt do not send them to the model.","items":{"$ref":"#/components/schemas/PromptTool"}},"status":{"type":"string","description":"Lifecycle state: `DRAFT` (saved, never published), `PUBLISHED` (the prompt's published version; at most one at a time) or `ARCHIVED` (was the published version until another version was published).","enum":["DRAFT","PUBLISHED","ARCHIVED"]},"labels":{"type":"array","description":"Labels currently pointing at this version, for example `production`. Empty when none.","items":{"type":"string"}},"created_at":{"type":"string","format":"date-time","description":"When the version was saved (ISO 8601)."},"created_by":{"type":"string","description":"Identifier of the caller (user or API key) that saved the version, or `unknown` when the caller could not be identified."}}},"PublishVersionRequest":{"type":"object","description":"Labels to set when publishing a version. The body is optional.","properties":{"labels":{"type":"array","description":"Labels to point at the published version, for example `[\"production\"]`. Each one is created, or moved from the version it pointed at. Omitted or empty: no label changes.","items":{"type":"string"}}}},"CreatePromptTestCaseRequest":{"type":"object","description":"A test case for a prompt: the variables to render it with and a pattern a good answer matches.","properties":{"name":{"type":"string","description":"A name for the test case (required)."},"variables_json":{"type":"object","additionalProperties":{"type":"string"},"description":"The variable values to render the prompt with, as a JSON object of strings, for example `{\"customer\":  \"Ada\"`} (required; may be empty)."},"expected_pattern":{"type":"string","description":"What a passing answer contains: a regular expression, matched case-insensitively anywhere in the answer (a value that is not a valid regular expression is matched as a case-insensitive substring). Omit it to pass every answer that completes."}},"required":["name","variables_json"]},"PromptTestCase":{"type":"object","description":"A test case of a prompt.","properties":{"id":{"type":"string","description":"The test case's unique id (UUID)."},"prompt_id":{"type":"string","description":"Id (UUID) of the prompt."},"name":{"type":"string","description":"The test case's name."},"variables_json":{"type":"object","additionalProperties":{"type":"string"},"description":"The variable values the prompt is rendered with, as a JSON object of strings."},"expected_pattern":{"type":"string","description":"The pattern a passing answer matches: a case-insensitive regular expression, or a substring when it is not a valid regular expression. Null when every completed answer passes."},"created_at":{"type":"string","format":"date-time","description":"When the test case was created (ISO 8601)."}}},"RunTestSuiteRequest":{"type":"object","description":"Options for running a prompt's test cases.","properties":{"virtual_key":{"type":"string","description":"Slug of the virtual key that runs the test cases (required), for example `vk-...`. It must belong to the prompt's organization and, when it is scoped to a workspace, to the prompt's workspace (400 otherwise). Each test case is one completion on this key, with its usage and cost."},"model_override":{"type":"string","description":"A model to use instead of the version's `model`. Required when the version has no model (400 otherwise)."}},"required":["virtual_key"]},"TestCaseRunResult":{"type":"object","description":"The result of one test case in a test run.","properties":{"test_case_id":{"type":"string","description":"Id (UUID) of the test case."},"name":{"type":"string","description":"The test case's name."},"passed":{"type":"boolean","description":"Whether the answer matched the test case's `expected_pattern`. `false` when the call failed."},"response_text":{"type":"string","description":"The model's answer text. Null when the call failed."},"latency_ms":{"type":"integer","format":"int64","description":"How long the call took, in milliseconds. Null when it failed."},"prompt_tokens":{"type":"integer","format":"int32","description":"Input tokens the call used. Null when it failed or the provider reported no usage."},"completion_tokens":{"type":"integer","format":"int32","description":"Output tokens the call generated. Null when it failed or the provider reported no usage."},"cost_usd":{"type":"number","format":"double","description":"The provider cost of the call in USD, at list price. Null when the call failed or the model has no price."},"error_message":{"type":"string","description":"Why the call failed. Null when it succeeded."},"pattern_matched":{"type":"boolean","description":"Whether the answer matched `expected_pattern` (`true` when the test case has no pattern and the call succeeded). Same as `passed`."}}},"TestRunResponse":{"type":"object","description":"The outcome of running a prompt's test cases.","properties":{"prompt_slug":{"type":"string","description":"Slug of the prompt."},"version_number":{"type":"integer","format":"int32","description":"The version that was tested: the one the `production` label points at, else the PUBLISHED version, else the highest version number."},"virtual_key":{"type":"string","description":"Slug of the virtual key the test cases ran on."},"test_case_count":{"type":"integer","format":"int32","description":"Number of test cases run."},"pass_count":{"type":"integer","format":"int32","description":"Number of test cases that passed."},"fail_count":{"type":"integer","format":"int32","description":"Number of test cases that failed, including calls that errored."},"total_cost_usd":{"type":"number","format":"double","description":"Total cost of the run in USD, the sum of the test cases' `cost_usd`. Null when the prompt has no test cases."},"results":{"type":"array","description":"One result per test case, in the order they ran.","items":{"$ref":"#/components/schemas/TestCaseRunResult"}}}},"RenderPromptRequest":{"type":"object","description":"The variables to render a prompt version with.","properties":{"variables":{"type":"object","additionalProperties":{"type":"string"},"description":"Values for the template's `{{name`}} placeholders, as a JSON object of strings. A placeholder with no value is left as written."},"version_ref":{"type":"string","description":"Which version to use: a version number (for example `3`), `latest` (the highest version number, whatever its status) or `@` followed by a label (for example `@staging`). Omit it for the default version: the one the `production` label points at, else the PUBLISHED version. An unknown version or label is a 404, any other value a 400."}},"required":["variables"]},"RenderPromptResponse":{"type":"object","description":"A prompt version's messages with the variables substituted.","properties":{"version_number":{"type":"integer","format":"int32","description":"The version that was rendered."},"messages":{"type":"array","description":"The rendered messages, in order.","items":{"$ref":"#/components/schemas/PromptMessage"}}}},"PromptCompletionRequest":{"type":"object","description":"What to run a prompt with. The virtual key goes in the `Authorization: Bearer` or `x-virtual-key` header, not in the body.","properties":{"variables":{"type":"object","additionalProperties":{"type":"string"},"description":"Values for the template's `{{name`}} placeholders, as a JSON object of strings. A placeholder with no value is sent to the model as written."},"version_ref":{"type":"string","description":"Which version to use: a version number (for example `3`), `latest` (the highest version number, whatever its status) or `@` followed by a label (for example `@staging`). Omit it for the default version: the one the `production` label points at, else the PUBLISHED version. An unknown version or label is a 404, any other value a 400."},"stream":{"type":"boolean","description":"`true` streams the answer as server-sent events. Default `false`."},"model_override":{"type":"string","description":"A model to use instead of the version's `model`. Required when the version has no model (400 otherwise)."}},"required":["variables"]},"ChatCompletionChoice":{"type":"object","description":"One answer in a chat completion's `choices`: the model's message and why it stopped.","properties":{"index":{"type":"integer","format":"int32","description":"The choice's position in `choices`, from 0."},"message":{"$ref":"#/components/schemas/ChatMessage","description":"The model's answer, an `assistant` message."},"finish_reason":{"type":"string","description":"Why the model stopped: `stop` (a natural end or a stop sequence), `length` (the token limit), `  tool_calls` or `content_filter`.","enum":["stop","length","content_filter","tool_calls"]},"stop_sequence":{"type":"string","description":"The stop sequence that ended the turn, when one did (Anthropic's `stop_sequence`). OpenAI's `finish_reason` reports a stop sequence and a natural end alike as `stop`, so this is what lets `/v1/messages` answer `stop_reason: stop_sequence`. Set only by the Anthropic adapters; omitted from the body otherwise."}}},"ChatCompletionResponse":{"type":"object","description":"A chat completion in OpenAI's format: the model's answer (one choice per `n`) and the tokens used, whichever provider served the request.","properties":{"id":{"type":"string","description":"The completion's id, as the provider assigned it."},"object":{"type":"string","description":"The object type, `chat.completion`."},"created":{"type":"integer","format":"int64","description":"When the completion was created, in Unix seconds."},"model":{"type":"string","description":"The model that produced the answer, as the provider reports it (it may carry a version suffix)."},"choices":{"type":"array","description":"The answers, one per requested choice (`n`, default 1).","items":{"$ref":"#/components/schemas/ChatCompletionChoice"}},"usage":{"$ref":"#/components/schemas/UsageInfo","description":"The tokens the request used, as the provider reported them."}}},"ChatMessage":{"type":"object","description":"One message of a conversation, in OpenAI's format: in a request, a turn of the conversation so far; in a response, the model's answer.","properties":{"role":{"type":"string","description":"Who wrote the message: `system` (instructions), `user`, `assistant` (the model) or `tool` (a tool call's result). Required.","enum":["system","user","assistant","tool"]},"content":{"description":"The message's content: a string, or an array of content parts (`text`, `image_url`, `input_audio`, `file`), each an object with a `type`. Any other shape is a 400 naming the message. May be null on an assistant message that only calls tools."},"name":{"type":"string","description":"An optional name for the author, to tell participants with the same role apart."},"tool_calls":{"type":"array","description":"On an assistant message: the tool calls the model made. Empty when it made none.","items":{"$ref":"#/components/schemas/ToolCall"}},"tool_call_id":{"type":"string","description":"On a `tool` message: the id of the tool call this message answers."},"thinking_blocks":{"type":"array","description":"Claude models with extended thinking: the assistant turn's reasoning blocks, `{\"type\":\"thinking\",\"thinking\":\"...\",\"signature\":\"...\"`} or `{\"type\":\"redacted_thinking\",\"data\":\"...\"`}, each with a `position` among the message's other blocks. Send them back unchanged on the next request: Anthropic checks the signature and treats a dropped, edited or reordered block as an edited history. Absent when there are none.","items":{"type":"object","additionalProperties":{}}},"is_error":{"type":"boolean","description":"On a `tool` message: `true` when the tool call failed. Sent to Claude models as the tool result's error flag. Absent otherwise."}},"required":["role"]},"FunctionCall":{"type":"object","description":"The function a tool call invokes: its name and the arguments the model chose.","properties":{"name":{"type":"string","description":"The name of the function the model calls."},"arguments":{"type":"string","description":"The arguments, as a JSON string the model generated. Validate it before use: the model may produce invalid JSON or arguments the schema does not allow."}}},"PromptTokensDetails":{"type":"object","description":"OpenAI's `usage.prompt_tokens_details`. Only `cached_tokens` is carried: the input tokens read from the provider's prompt cache (OpenAI's automatic caching, Anthropic's `cache_read_input_tokens`). Other fields OpenAI adds (`audio_tokens`) are ignored.","properties":{"cached_tokens":{"type":"integer","format":"int32","description":"Input tokens read from the provider's prompt cache."}}},"ToolCall":{"type":"object","description":"A tool call the model made, on an assistant message. Run the function and send the result back in a `tool` message with the same `tool_call_id`.","properties":{"id":{"type":"string","description":"The tool call id, sent back as `tool_call_id` on the `tool` message with the result."},"type":{"type":"string","description":"Always `function`."},"function":{"$ref":"#/components/schemas/FunctionCall","description":"The function called and its arguments."}}},"UsageInfo":{"type":"object","description":"The tokens a request used, in OpenAI's format. `prompt_tokens` counts every input token, including those read from or written to the provider's prompt cache.","properties":{"prompt_tokens":{"type":"integer","format":"int32","description":"Input tokens, cached or not."},"completion_tokens":{"type":"integer","format":"int32","description":"Output tokens the model generated."},"total_tokens":{"type":"integer","format":"int32","description":"`prompt_tokens` plus `completion_tokens`."},"prompt_tokens_details":{"$ref":"#/components/schemas/PromptTokensDetails","description":"A breakdown of `prompt_tokens`: `cached_tokens` is the part read from the provider's prompt cache. Absent when the provider reported none."},"cache_creation_input_tokens":{"type":"integer","format":"int32","description":"Input tokens written to the provider's prompt cache (Claude), part of `prompt_tokens`. Absent when none were reported."},"cache_creation_1h_input_tokens":{"type":"integer","format":"int32","description":"Of `cache_creation_input_tokens`, those written with the 1-hour cache lifetime, which costs more than the 5-minute one. Absent when none were reported."}}},"AnthropicChatResponse":{"type":"object","description":"Response body of `POST /v1/messages`, and the envelope carried by `message_start`.","properties":{"id":{"type":"string","description":"The message id (`msg_...`)."},"type":{"type":"string","description":"Always `message`."},"role":{"type":"string","description":"Always `assistant`."},"content":{"type":"array","description":"What the model generated, as content blocks: `text`, `tool_use`, `thinking` or `  redacted_thinking`.","items":{"$ref":"#/components/schemas/AnthropicContentBlock"}},"model":{"type":"string","description":"The model that answered."},"stop_reason":{"type":"string","description":"Why the model stopped: `end_turn`, `max_tokens`, `stop_sequence` or `tool_use`. Null on `message_start`.","enum":["end_turn","max_tokens","stop_sequence","tool_use"]},"stop_sequence":{"type":"string","description":"The stop sequence that ended the turn, when `stop_reason` is `stop_sequence`."},"usage":{"$ref":"#/components/schemas/AnthropicUsageInfo","description":"The tokens the request used."}}},"AnthropicContentBlock":{"type":"object","description":"A content block on a Messages response or a `content_block_start` event: `text` carries `text`; `tool_use` carries `id`, `name` and `input`; `thinking` carries `thinking` and `signature`; `redacted_thinking` carries `data`.","properties":{"type":{"type":"string","description":"The block type: `text`, `tool_use`, `thinking` or `redacted_thinking`."},"text":{"type":"string","description":"`text` blocks: the generated text."},"id":{"type":"string","description":"`tool_use` blocks: the tool call id (`toolu_...`), sent back in the `tool_result`."},"name":{"type":"string","description":"`tool_use` blocks: the name of the tool the model calls."},"input":{"type":"object","additionalProperties":{},"description":"`tool_use` blocks: the tool's arguments, an object matching its `input_schema`."},"thinking":{"type":"string","description":"`thinking` blocks: the reasoning text, \"\" when display is omitted (still sent)."},"signature":{"type":"string","description":"`thinking` blocks: the signature the client must send back with the block."},"data":{"type":"string","description":"`redacted_thinking` blocks: the opaque payload."}}},"AnthropicUsageInfo":{"type":"object","description":"Token usage on a Messages response or a `message_start` / `message_delta` event.","properties":{"input_tokens":{"type":"integer","format":"int32","description":"Input tokens that were not read from or written to the prompt cache."},"output_tokens":{"type":"integer","format":"int32","description":"Output tokens generated."},"cache_creation_input_tokens":{"type":"integer","format":"int32","description":"Input tokens written to the prompt cache."},"cache_read_input_tokens":{"type":"integer","format":"int32","description":"Input tokens read from the prompt cache."},"cache_creation":{"type":"object","additionalProperties":{},"description":"The cache writes by TTL: `ephemeral_5m_input_tokens`, `ephemeral_1h_input_tokens`."}}},"CreateMcpServerRequest":{"type":"object","description":"Creates an MCP server: a workspace's endpoint on a connector, which agents reach at the gateway URL returned in `url`. The connector must be available to the workspace.","properties":{"organization":{"type":"string","description":"The organization's identifier (slug).","minLength":1},"workspace_id":{"type":"string","format":"uuid","description":"The workspace the server belongs to (UUID)."},"integration_slug":{"type":"string","description":"The slug of the connector to serve (`mcpi-...`). It must be active and available to the workspace.","minLength":1},"name":{"type":"string","description":"Display name, up to 255 characters.","maxLength":255,"minLength":0},"description":{"type":"string","description":"Optional free-text description."},"guardrail_slugs":{"type":"array","description":"Guardrails run on every call through this server, in order, after the connector's own, at most 10. Each must be an organization-level guardrail or one of this workspace's.","items":{"type":"string"},"maxItems":10,"minItems":0}},"required":["integration_slug","name","organization","workspace_id"]},"McpTestResult":{"type":"object","description":"A connectivity check. A failed check is a 200 with `ok: false`, not an HTTP error.","properties":{"ok":{"type":"boolean","description":"Whether the gateway could connect (for a REST connector: read the spec or declarations into tools)."},"protocol_era":{"type":"string","description":"`MODERN` or `LEGACY`.","enum":["MODERN","LEGACY"]},"protocol_version":{"type":"string","description":"The MCP protocol version agreed."},"server_name":{"type":"string","description":"The name the upstream reported (a REST connector: the spec's title, or the connector's name)."},"server_version":{"type":"string","description":"The version the upstream reported."},"capabilities":{"type":"array","description":"The capability groups the upstream declared, for example `tools`, `prompts`, `resources`.","items":{"type":"string"}},"latency_ms":{"type":"integer","format":"int64","description":"How long the check took, in milliseconds."},"error_kind":{"type":"string","description":"On failure, the kind of error: `EGRESS_BLOCKED`, `UNREACHABLE`, `TIMEOUT`, `AUTH_FAILED`, `HTTP_ERROR`, `PROTOCOL_ERROR`, `UNSUPPORTED_VERSION`, `UNSUPPORTED_TRANSPORT`, `RESPONSE_TOO_LARGE`, `SPEC_INVALID`, `CONNECTION_REQUIRED` (`OAUTH_AUTO`: no connected account to test with) or `OAUTH_ERROR`."},"error":{"type":"string","description":"On failure, what went wrong."}}},"McpToolRun":{"type":"object","description":"One call through the MCP Gateway (a tool call, prompt get or resource read, or a refused request), as recorded for audit.","properties":{"id":{"type":"string","format":"uuid","description":"The run's ID (UUID)."},"created_at":{"type":"string","format":"date-time","description":"When the call was made (ISO 8601)."},"request_id":{"type":"string","description":"The request ID (`X-Request-ID`) of the call."},"virtual_key_slug":{"type":"string","description":"Calls made before MCP keys existed, when the gateway took virtual keys. New calls carry `mcp_key_id`."},"user_id":{"type":"string","description":"Set when a person called through an MCP client they connected with OAuth (no MCP key)."},"upstream_account":{"type":"string","description":"`OAUTH_AUTO` calls: whose upstream account was used, `USER` (the caller's own) or `ORGANIZATION` (the organization connection). Absent for other auth types."},"user_email":{"type":"string","description":"The caller's email, for display, when `user_id` is set."},"workspace_id":{"type":"string","format":"uuid","description":"The MCP server's workspace (UUID)."},"server_slug":{"type":"string","description":"The MCP server the call went through."},"server_name":{"type":"string","description":"The server's name, for display. Absent once the server is deleted."},"integration_slug":{"type":"string","description":"The connector behind the server."},"mcp_method":{"type":"string","description":"The MCP method, for example `tools/call`, `prompts/get` or `resources/read`."},"mcp_name":{"type":"string","description":"The tool or prompt name, or the resource URI."},"capability_type":{"type":"string","description":"`TOOL`, `PROMPT`, `RESOURCE` or `RESOURCE_TEMPLATE`.","enum":["TOOL","PROMPT","RESOURCE","RESOURCE_TEMPLATE"]},"protocol_version":{"type":"string","description":"The MCP protocol version the client sent."},"status":{"type":"string","description":"The gateway's verdict: `COMPLETED`, `FAILED`, `BLOCKED` or `TIMED_OUT`.","enum":["COMPLETED","FAILED","BLOCKED","TIMED_OUT"]},"provider_http_status":{"type":"integer","format":"int32","description":"The HTTP status the upstream answered with. Absent when it was not called."},"tool_error":{"type":"boolean","description":"`true` when the call worked but the tool reported a failure (its `isError`)."},"blocked_control":{"type":"string","description":"`BLOCKED` calls: the control that refused it, for example `DISABLED`, `DISABLED_ON_SERVER`, `DRIFT`, `QUARANTINED`, `NOT_IN_KEY_ALLOWLIST`, `RATE_LIMITED`, `USER_ACCESS_DENIED`, `GUARDRAIL`, `TAINTED`, `APPROVAL_REQUIRED`, `CONNECTION_REQUIRED`, `SAMPLING_REFUSED`, `ELICITATION_REFUSED` or `NESTING_DEPTH`."},"blocked_reason":{"type":"string","description":"`BLOCKED` calls: why, in a sentence."},"error_message":{"type":"string","description":"`FAILED` and `TIMED_OUT` calls: what went wrong."},"guardrail_status":{"type":"string","description":"The guardrails' verdict: `PASS`, `MONITOR`, `REDACT` or `BLOCK`, from the built-in scan and the guardrails on the connector and server. Absent when none ran."},"guardrail_violations":{"description":"What they found: a list of objects with `check_type`, `target`, `action` and `description`. Never the matched text."},"input":{"description":"The call's arguments. Present only when the organization stores log bodies, or when the call awaits approval."},"output":{"type":"string","description":"The upstream's reply, truncated. Present only when the organization stores log bodies."},"latency_ms":{"type":"integer","format":"int64","description":"How long the call took at the gateway, in milliseconds."},"output_taint":{"type":"string","description":"`TRUSTED` or `UNTRUSTED`, when content went back to the caller. `UNTRUSTED` (any result from a capability not marked `trusted_output`) makes the caller untrusted for a while, so privileged tools are refused."},"approval_status":{"type":"string","description":"On a call held for approval: `PENDING`, `APPROVED`, `REJECTED`, `USED` (the caller's retry went ahead on it) or `EXPIRED` (not decided, or not used, in time)."},"approval_decided_by":{"type":"string","description":"The user who approved or rejected it."},"approval_decided_at":{"type":"string","format":"date-time","description":"When it was approved or rejected (ISO 8601)."},"approval_expires_at":{"type":"string","format":"date-time","description":"Until when a `PENDING` call can be approved, or an `APPROVED` one used (ISO 8601)."},"approval_used_by":{"type":"string","format":"uuid","description":"The run that went ahead on this approval."},"approval_run_id":{"type":"string","format":"uuid","description":"On a run that went ahead with an approval: the run that was approved."},"mcp_key_id":{"type":"string","description":"The MCP key the call came in on."},"mcp_key_name":{"type":"string","description":"That key's name, for display."},"initiator":{"type":"string","description":"`AGENT`: the client's own call. `MCP_SERVER`: a request the upstream made while answering a call (sampling, elicitation or roots)."},"parent_run_id":{"type":"string","format":"uuid","description":"The call a server's request belongs to, or the round a client's retry continues."},"nesting_depth":{"type":"integer","format":"int32","description":"0 for a client's first call; one more per round of sampling, elicitation or roots requests."},"region":{"type":"string","description":"The AWS region whose database holds this record. Absent on older records."}}},"CreateMcpKeyRequest":{"type":"object","description":"Creates an MCP key: the `va_` key an agent presents to the MCP Gateway. It works only on the gateway and belongs to one workspace.","properties":{"organization":{"type":"string","description":"The organization's identifier (slug).","minLength":1},"workspace_id":{"type":"string","format":"uuid","description":"The workspace the key belongs to (UUID). The key reaches only that workspace's MCP servers."},"name":{"type":"string","description":"Display name, up to 255 characters.","maxLength":255,"minLength":0},"expires_at":{"type":"string","format":"date-time","description":"When the key stops working (ISO 8601). Absent: it does not expire."},"tool_allowlist":{"type":"array","description":"The tools the key may call, at most 500 entries: `{server slug}/{tool name}`, or `{server slug}/*` for every tool of that server. Each server must be in the key's workspace. Absent: every tool the registry allows. The allowlist can only narrow what the registry allows.","items":{"type":"string"},"maxItems":500,"minItems":0},"rate_limit_rpm":{"type":"integer","format":"int32","description":"Gateway calls per minute for this key (at least 1). Absent: only the plan's per-workspace limit applies.","minimum":1},"rate_limit_rpd":{"type":"integer","format":"int32","description":"Gateway calls per day for this key (at least 1). Absent: no daily limit of its own.","minimum":1}},"required":["name","organization","workspace_id"]},"McpKeyCreated":{"type":"object","description":"An MCP key with its secret, returned once, on create and on rotate.","properties":{"key":{"$ref":"#/components/schemas/McpKey","description":"The key."},"api_key":{"type":"string","description":"The full key (`va_...`). Shown only now: only its hash is stored, so store it safely."}}},"CreateMcpIntegrationRequest":{"type":"object","description":"Registers a connector: an upstream MCP server, or a REST API described by an OpenAPI document (`OPENAPI`) or by hand-declared endpoints (`HTTP`). Credentials are write-only: they are stored encrypted and never returned.","properties":{"organization":{"type":"string","description":"The organization's identifier (slug).","minLength":1},"workspace_id":{"type":"string","format":"uuid","description":"The workspace that owns the connector (UUID). Absent: an organization-level connector, which can be shared with several workspaces (see `global_workspace_access` and the workspace access endpoint)."},"name":{"type":"string","description":"Display name, up to 255 characters.","maxLength":255,"minLength":0},"description":{"type":"string","description":"Optional free-text description."},"url":{"type":"string","description":"The upstream URL, up to 2048 characters: the MCP server's endpoint for `MCP`, the API's base URL for `OPENAPI` and `HTTP` (no query string or fragment). It must pass the gateway's egress policy (public addresses only).","maxLength":2048,"minLength":0},"transport":{"type":"string","description":"The upstream transport. Only `HTTP` (Streamable HTTP); the default.","enum":["HTTP"]},"auth_type":{"type":"string","description":"How the gateway authenticates upstream: `NONE`, `HEADERS`, `OAUTH_AUTO` or `OAUTH_CLIENT_CREDENTIALS`. Default: `HEADERS` when `headers` or `query_params` are given, else `NONE`.","enum":["NONE","HEADERS","OAUTH_AUTO","OAUTH_CLIENT_CREDENTIALS"]},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"`HEADERS` auth: header name to value, sent on every upstream request. Write-only. Names that the gateway sets itself (for example `Host`, `Content-Type`, `Mcp-Session-Id`) are refused, and values may not contain control characters. Cannot be combined with an OAuth auth type."},"oauth":{"$ref":"#/components/schemas/McpOAuthClientConfig","description":"OAuth settings, for `OAUTH_AUTO` and `OAUTH_CLIENT_CREDENTIALS` only."},"kind":{"type":"string","description":"What is behind the connector: `MCP` (default), `OPENAPI` or `HTTP`. Fixed once created.","enum":["MCP","OPENAPI","HTTP"]},"spec_url":{"type":"string","description":"`OPENAPI` only: where the OpenAPI document is fetched from, on every sync. Give this or `spec_content`. Up to 2048 characters.","maxLength":2048,"minLength":0},"spec_content":{"type":"string","description":"`OPENAPI` only: the OpenAPI 3.0 or 3.1 document itself, in the format `spec_format` names."},"spec_format":{"type":"string","description":"`OPENAPI` only: the format of `spec_content`, `JSON` or `YAML`. Required with `spec_content`.","enum":["JSON","YAML"]},"http_tools":{"type":"array","description":"`HTTP` only: the endpoints, declared by hand. At most 200.","items":{"$ref":"#/components/schemas/McpHttpTool"},"maxItems":200,"minItems":0},"query_params":{"type":"object","additionalProperties":{"type":"string"},"description":"`OPENAPI` and `HTTP` with `HEADERS` auth: API keys sent as query parameters (name to value), alone or with `headers`. Write-only."},"global_workspace_access":{"type":"boolean","description":"Organization-level connectors only: `true` lets every workspace in the organization use it. Default `false`. Ignored for a workspace-owned connector."},"org_connection_for_users":{"type":"boolean","description":"`OAUTH_AUTO` only: `true` lets a signed-in person who has not connected their own account use the organization connection. Default `false`. Agents on an MCP key always use the organization connection."},"guardrail_slugs":{"type":"array","description":"Guardrails run on every call through this connector, in order, at most 10: INPUT checks on the arguments sent upstream, OUTPUT checks on what the upstream returns. Each must exist in the organization; an organization-level connector takes only organization-level guardrails.","items":{"type":"string"},"maxItems":10,"minItems":0}},"required":["name","organization","url"]},"McpSkippedOperation":{"type":"object","description":"An operation of an OpenAPI document that did not become a tool, and why.","properties":{"method":{"type":"string","description":"The HTTP method of the operation."},"path":{"type":"string","description":"The operation's path in the document."},"operation_id":{"type":"string","description":"The operation's `operationId`, when it has one."},"reason":{"type":"string","description":"Why it was skipped, for example an unsupported request body type."}}},"McpSyncResult":{"type":"object","description":"The outcome of a capability sync. A failed sync is still a 200, with `sync_status: FAILED` and the error; the connector keeps the capabilities from its last good sync.","properties":{"sync_status":{"type":"string","description":"`OK` or `FAILED`.","enum":["NEVER","OK","FAILED","STALE"]},"protocol_era":{"type":"string","description":"`MODERN` or `LEGACY`. Absent on failure.","enum":["MODERN","LEGACY"]},"protocol_version":{"type":"string","description":"The MCP protocol version the upstream spoke. Absent on failure."},"server_name":{"type":"string","description":"The name the upstream reported (a REST connector: the spec's title). Absent on failure."},"server_version":{"type":"string","description":"The version the upstream reported. Absent on failure."},"added":{"type":"integer","format":"int32","description":"Capabilities found for the first time."},"updated":{"type":"integer","format":"int32","description":"Known capabilities whose details changed."},"removed":{"type":"integer","format":"int32","description":"Capabilities no longer listed (now `REMOVED`)."},"unchanged":{"type":"integer","format":"int32","description":"Capabilities that did not change."},"drifted":{"type":"integer","format":"int32","description":"Capabilities whose definition now differs from the pinned one."},"quarantined":{"type":"integer","format":"int32","description":"Active capabilities whose current definition is quarantined by the tool-poisoning scan."},"truncated":{"type":"boolean","description":"`true` when the upstream listed more capabilities (or operations) than the gateway keeps; the rest were ignored."},"skipped":{"type":"array","description":"`OPENAPI`: operations that did not become tools, and why.","items":{"$ref":"#/components/schemas/McpSkippedOperation"}},"synced_at":{"type":"string","format":"date-time","description":"When the sync ran (ISO 8601)."},"error_kind":{"type":"string","description":"On failure, the kind of error: `EGRESS_BLOCKED`, `UNREACHABLE`, `TIMEOUT`, `AUTH_FAILED`, `HTTP_ERROR`, `PROTOCOL_ERROR`, `UNSUPPORTED_VERSION`, `UNSUPPORTED_TRANSPORT`, `RESPONSE_TOO_LARGE` or `SPEC_INVALID`."},"error":{"type":"string","description":"On failure, what went wrong."}}},"McpSpecPreviewRequest":{"type":"object","description":"An OpenAPI document to read before creating a connector: a URL, or the document itself.","properties":{"organization":{"type":"string","description":"The organization's identifier (slug).","minLength":1},"workspace_id":{"type":"string","format":"uuid","description":"The workspace the connector is for (UUID). Set: any member of that workspace may preview. Absent: any organization member may."},"spec_url":{"type":"string","description":"Where to fetch the OpenAPI document from, up to 2048 characters. Give this or `spec_content`.","maxLength":2048,"minLength":0},"spec_content":{"type":"string","description":"The OpenAPI 3.0 or 3.1 document itself. Takes precedence over `spec_url`."},"spec_format":{"type":"string","description":"The format of `spec_content`: `JSON` or `YAML`.","enum":["JSON","YAML"]}},"required":["organization"]},"McpSpecPreview":{"type":"object","description":"What an OpenAPI document holds: its title, the base URLs it suggests, the tools it would become, what would be skipped, and how it says to authenticate. Nothing is stored. The connector always uses the base URL you give it, never the document's.","properties":{"openapi_version":{"type":"string","description":"The document's OpenAPI version, for example `3.1.0`."},"title":{"type":"string","description":"The document's `info.title`."},"version":{"type":"string","description":"The document's `info.version`."},"description":{"type":"string","description":"The document's `info.description`."},"format":{"type":"string","description":"The format the document was read as, `JSON` or `YAML`.","enum":["JSON","YAML"]},"servers":{"type":"array","description":"The document's `servers[].url`, as written.","items":{"type":"string"}},"tools":{"type":"array","description":"The tools the operations would become.","items":{"$ref":"#/components/schemas/McpSpecPreviewTool"}},"skipped":{"type":"array","description":"Operations that would not become tools, and why.","items":{"$ref":"#/components/schemas/McpSkippedOperation"}},"truncated":{"type":"boolean","description":"`true` when the document has more operations than a connector takes; the rest are left out."},"security_schemes":{"type":"array","description":"The document's security schemes, with the auth type each suggests.","items":{"$ref":"#/components/schemas/McpSpecPreviewSecurityScheme"}}}},"McpSpecPreviewSecurityScheme":{"type":"object","description":"A security scheme of the document, and the auth type it suggests: `HEADERS` for an API key in a header or query parameter and for HTTP bearer or basic; `OAUTH_CLIENT_CREDENTIALS` or `OAUTH_AUTO` for OAuth 2 flows; absent when the gateway cannot use it (mutual TLS, an API key in a cookie, OpenID Connect discovery).","properties":{"name":{"type":"string","description":"The scheme's name in the document."},"type":{"type":"string","description":"The OpenAPI scheme type: `apiKey`, `http`, `oauth2`, `openIdConnect` or `mutualTLS`."},"in":{"type":"string","description":"`apiKey`: where the key goes, `header`, `query` or `cookie`."},"parameter_name":{"type":"string","description":"`apiKey`: the header or query parameter name."},"scheme":{"type":"string","description":"`http`: `bearer` or `basic`."},"authorization_url":{"type":"string","description":"`oauth2`: the authorization URL."},"token_url":{"type":"string","description":"`oauth2`: the token URL."},"scopes":{"type":"array","description":"`oauth2`: the scopes the document lists.","items":{"type":"string"}},"suggested_auth_type":{"type":"string","description":"The connector auth type to use. Absent when the gateway cannot use this scheme.","enum":["NONE","HEADERS","OAUTH_AUTO","OAUTH_CLIENT_CREDENTIALS"]}}},"McpSpecPreviewTool":{"type":"object","description":"A tool an operation of the document would become.","properties":{"name":{"type":"string","description":"The tool's name (from the `operationId`, or derived from the method and path)."},"method":{"type":"string","description":"The HTTP method."},"path":{"type":"string","description":"The operation's path."},"title":{"type":"string","description":"The tool's title (the operation's summary), when it has one."},"read_only":{"type":"boolean","description":"`true` for GET and HEAD. The others start privileged when imported."}}},"ExportJobRequest":{"type":"object","description":"What to export: the logs matching every filter given, newest first, as CSV or JSON.","properties":{"format":{"type":"string","description":"`csv` (default) or `json`. CSV has one header row and a fixed set of columns; JSON is an array of log rows as the search returns them.","enum":["csv","json"]},"max_rows":{"type":"integer","format":"int32","description":"The most logs to export: default 10,000, at most 50,000."},"provider":{"type":"string","description":"Only requests to this provider, as stored: upper case with underscores, e.g. `OPENAI`."},"model":{"type":"string","description":"Only requests for this model id."},"organization":{"type":"string","description":"The slug of the organization whose logs to export. Required."},"user_id":{"type":"string","description":"Only requests attributed to this end user."},"virtual_key_slug":{"type":"string","description":"Only requests made with this virtual key (`vk-...`)."},"status":{"type":"string","description":"`success` (status below 400) or `error` (400 and above).","enum":["success","error"]},"cache_status":{"type":"string","description":"Only requests with this cache result: `HIT`, `SEMANTIC_HIT`, `MISS`, `BYPASS`, `  REFRESH` or `DISABLED`.","enum":["HIT","SEMANTIC_HIT","MISS","BYPASS","REFRESH","DISABLED"]},"start_time":{"type":"string","format":"date-time","description":"Only requests at or after this time (ISO 8601 date-time with offset)."},"end_time":{"type":"string","format":"date-time","description":"Only requests before this time (ISO 8601 date-time with offset)."}}},"ExportJobResponse":{"type":"object","description":"A log export job and its progress.","properties":{"job_id":{"type":"string","description":"The job's id. Use it to check progress and download the file."},"status":{"type":"string","description":"`PENDING`, `RUNNING`, `DONE` or `FAILED`.","enum":["PENDING","RUNNING","DONE","FAILED"]},"format":{"type":"string","description":"The file format: `csv` or `json`.","enum":["csv","json"]},"row_count":{"type":"integer","format":"int32","description":"How many logs were exported; 0 until the job is done."},"error_message":{"type":"string","description":"Why the job failed; null unless the status is `FAILED`."},"created_at":{"type":"string","format":"date-time","description":"When the job was started (ISO 8601 date-time). The job and its file are kept for one hour from then."},"completed_at":{"type":"string","format":"date-time","description":"When the job finished or failed (ISO 8601 date-time); null while it runs."}}},"ImageGenerationResponse":{"type":"object","description":"The images produced by an image generation or edit request, as the provider returned them.","properties":{"created":{"type":"integer","format":"int64","description":"When the images were created, as a Unix timestamp in seconds."},"data":{"type":"array","description":"The images, one per `n` requested.","items":{"$ref":"#/components/schemas/ImageObject"}}}},"ImageObject":{"type":"object","description":"One generated or edited image. Either `url` or `b64_json` is set, following `response_format`.","properties":{"url":{"type":"string","description":"A URL to download the image from, when `response_format` is `url`. The provider's URL, valid for a limited time."},"b64_json":{"type":"string","description":"The image as base64-encoded data, when `response_format` is `b64_json` (always, for the gpt-image models)."},"revised_prompt":{"type":"string","description":"The prompt the model actually used, when it rewrote yours (dall-e-3). Absent otherwise."}}},"CreateGuardrailRequest":{"type":"object","description":"A new guardrail: its name, workspace and checks.","properties":{"name":{"type":"string","description":"Display name, unique within the organization (409 if taken)."},"description":{"type":"string","description":"Free-text description. Optional."},"organization":{"type":"string","description":"Slug of the organization that will own the guardrail."},"workspace_id":{"type":"string","format":"uuid","description":"Id (UUID) of the workspace the guardrail belongs to. It must belong to `organization`."},"enabled":{"type":"boolean","description":"Whether the guardrail runs. Default `true`."},"checks":{"type":"array","description":"The checks to run. Every check's `type` must be a validator id and its `config` must be accepted by that validator (400 otherwise).","items":{"$ref":"#/components/schemas/GuardrailCheck"}}},"required":["checks","name","organization","workspace_id"]},"VectorAxisFile":{"type":"object","description":"A file uploaded through VectorAxis. Its `id` is the VectorAxis file id (`vxf-...`), which you use with every VectorAxis endpoint in place of the provider's id. The provider's own file id is never returned.","properties":{"id":{"type":"string","description":"The VectorAxis file id: `vxf-` followed by a UUID."},"provider":{"type":"string","description":"The provider the file was uploaded to, for example `OPENAI`."},"filename":{"type":"string","description":"The file's name as uploaded."},"bytes":{"type":"integer","format":"int64","description":"The file's size in bytes, as the provider reported it. Absent when the provider did not report it."},"mime_type":{"type":"string","description":"The file's content type as uploaded, for example `application/jsonl`."},"purpose":{"type":"string","description":"What the file is for: `batch` (input for a batch job), `fine-tune` (training data), `assistants` (documents for assistants and the Responses API, the default) or `vision` (an image for chat messages). Absent when the purpose given at upload is none of these.","enum":["fine-tune","batch","assistants","vision"]},"status":{"type":"string","description":"The file's state at VectorAxis: `uploaded` (received and sent to the provider), `processing` (the provider is processing it), `processed` (ready) or `error` (the provider rejected it; see `provider_status`).","enum":["uploaded","processing","processed","error"]},"provider_status":{"type":"string","description":"The file's status as the provider reported it at upload. Absent when the provider reported none."},"organization":{"type":"string","description":"The organization the file belongs to. Absent for an upload with direct provider credentials and no `x-organization`."},"virtual_key_slug":{"type":"string","description":"The slug of the virtual key the file was uploaded with (`vk-...`). Only that key can read, download or delete it. Absent for an upload with direct provider credentials."},"created_at":{"type":"string","format":"date-time","description":"When the file was uploaded, ISO 8601."},"expires_at":{"type":"string","format":"date-time","description":"When the file expires at the provider, ISO 8601. Absent when it does not expire."}}},"CreateRoutingConfigRequest":{"type":"object","description":"A routing config to create: a strategy, the targets it chooses between, and for CONDITIONAL the rules that choose. A target is a virtual key or, nested, another strategy with targets of its own.","properties":{"name":{"type":"string","description":"The config's name, unique within the organization. The slug is derived from it. Required."},"description":{"type":"string","description":"A free-text description. Optional."},"organization":{"type":"string","description":"The slug of the organization the config belongs to. Required."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace the config belongs to (UUID). Required."},"strategy_mode":{"type":"string","description":"How a request picks among `targets`. Required.\n\n- `SINGLE`: always the first target.\n- `LOADBALANCE`: one target at random, in proportion to each target's `weight`.\n- `FALLBACK`: the targets in order; the next is tried when one fails with a status in `on_status_codes`.\n- `CONDITIONAL`: the first of `conditions` (by `condition_order`) that matches the request picks its `then_target_name`; if none matches, `conditional_default_target_name`.","enum":["SINGLE","LOADBALANCE","FALLBACK","CONDITIONAL"]},"on_status_codes":{"type":"array","description":"For `FALLBACK`: the provider HTTP statuses that move a request on to the next target. Any other failure is returned at once. Empty or absent: 429, 500, 502, 503 and 504.","items":{"type":"integer","format":"int32"}},"conditional_default_target_name":{"type":"string","description":"For `CONDITIONAL`: the `name` of the target used when no condition matches. Absent: a request that matches no condition fails with 424."},"targets":{"type":"array","description":"The targets, in order. At least one. Required.","items":{"$ref":"#/components/schemas/RoutingTargetRequest"}},"conditions":{"type":"array","description":"For `CONDITIONAL` (at least one required): the rules that pick a target. Ignored otherwise.","items":{"$ref":"#/components/schemas/RoutingConditionRequest"}},"cache":{"$ref":"#/components/schemas/CacheConfig","description":"Response cache settings, stored with the config. Requests served through a routing config are not answered from the response cache at present. Optional."},"retry":{"$ref":"#/components/schemas/RetryConfig","description":"Retries for every target that has no `retry` of its own. Absent: no retries."},"request_timeout_ms":{"type":"integer","format":"int32","description":"A time limit in milliseconds. Stored with the config; only the `request_timeout_ms` of a virtual key target is applied to its calls. Optional."}},"required":["name","organization","strategy_mode","targets","workspace_id"]},"RoutingConfigValidateRequest":{"type":"object","description":"A routing config to check without saving it. The fields mean what they do in \"Create a routing config\"; only `organization`, `strategy_mode`, `targets` and `conditions` are checked.","properties":{"organization":{"type":"string","description":"The organization slug the config's virtual keys must belong to. Required."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace the config is for (UUID). Optional: a member of that workspace (or a key scoped to it) may validate with it; without it the caller must be a member of the organization."},"strategy_mode":{"type":"string","description":"The strategy: `SINGLE`, `LOADBALANCE`, `FALLBACK` or `CONDITIONAL`. Required.","enum":["SINGLE","LOADBALANCE","FALLBACK","CONDITIONAL"]},"targets":{"type":"array","description":"The targets. At least one. Required.","items":{"$ref":"#/components/schemas/RoutingTargetRequest"}},"conditions":{"type":"array","description":"For `CONDITIONAL` (at least one required): the rules that pick a target.","items":{"$ref":"#/components/schemas/RoutingConditionRequest"}},"on_status_codes":{"type":"array","description":"For `FALLBACK`: the statuses that move on to the next target. Not checked.","items":{"type":"integer","format":"int32"}},"conditional_default_target_name":{"type":"string","description":"For `CONDITIONAL`: the target used when no condition matches. Not checked at this level."},"cache":{"$ref":"#/components/schemas/CacheConfig","description":"Response cache settings. Not checked."},"retry":{"$ref":"#/components/schemas/RetryConfig","description":"Retries for targets without their own. Not checked at this level."}},"required":["organization","strategy_mode","targets"]},"RoutingConfigValidateResponse":{"type":"object","description":"Whether a routing config is valid, and if not, why.","properties":{"valid":{"type":"boolean","description":"True when the config would be accepted by create and update."},"errors":{"type":"array","description":"Empty when `valid` is true; otherwise one entry listing the problems.","items":{"$ref":"#/components/schemas/RoutingConfigValidateResponseErrorsInner"}}}},"RoutingConfigValidateResponseErrorsInner":{"type":"object","description":"Why a routing config is not valid.","properties":{"path":{"type":"string","description":"Where the problem is. Currently always `request`: the message carries each problem's own path."},"message":{"type":"string","description":"The problems, each as `[path] message` and separated by `; `, e.g. `[targets[0].weight] Weight must be greater than 0`."}}},"ChatCompletionRequest":{"type":"object","description":"A chat completion request in OpenAI's Chat Completions format. Whichever provider serves the model, the request is written the same way; the gateway translates it where the provider has its own format. Fields not listed here (provider-specific options) are passed on to the provider as top-level body fields, unchanged. VectorAxis options (credentials, cache, retries, fallbacks, guardrails) are request headers, never body fields.","properties":{"model":{"type":"string","description":"The model to use, for example `gpt-4o` or `claude-sonnet-4-5`. Required. With a virtual key that allows only certain models, any other model is refused (403). A `provider/` prefix (for example `openai/gpt-4o`) names the provider explicitly."},"messages":{"type":"array","description":"The conversation so far, oldest first: system, user, assistant and tool messages. Required.","items":{"$ref":"#/components/schemas/ChatMessage"}},"max_tokens":{"type":"integer","format":"int32","description":"The most tokens the model may generate in its answer. Optional; the provider's default when absent. Newer OpenAI models take `max_completion_tokens` instead."},"temperature":{"type":"number","format":"float","description":"Sampling temperature, typically 0 to 2: higher is more random. Optional; the provider's default when absent."},"top_p":{"type":"number","format":"float","description":"Nucleus sampling: only tokens within this cumulative probability (0 to 1) are considered. Optional; the provider's default when absent."},"stream":{"type":"boolean","description":"`true` to receive the answer as a stream of server-sent events (`chat.completion.chunk` objects, then `[DONE]`). Default `false`."},"stop":{"type":"array","description":"Sequences that end generation when the model produces them. Optional; empty by default.","items":{"type":"string"}},"user":{"type":"string","description":"Your identifier for the end user, passed to the provider. Optional."},"tools":{"type":"array","description":"Functions the model may call. Optional; empty by default. Each is a `function` tool with a name, description and JSON Schema parameters.","items":{"$ref":"#/components/schemas/Tool"}},"tool_choice":{"description":"How the model uses `tools`: `\"auto\"` (the model decides), `\"none\"` (no tool call), `\"required\"` (at least one tool call), or `{\"type\":\"function\",\"function\":{\"name\":\"...\"`}} to force one function. Optional; the provider's default when absent."},"frequency_penalty":{"type":"number","format":"float","description":"Penalises tokens by how often they already appear, typically -2 to 2. Optional; passed to providers that support it."},"presence_penalty":{"type":"number","format":"float","description":"Penalises tokens that have appeared at all, typically -2 to 2. Optional; passed to providers that support it."},"n":{"type":"integer","format":"int32","description":"How many alternative answers to generate. Optional; the provider's default (1) when absent."},"seed":{"type":"integer","format":"int64","description":"A seed for best-effort deterministic sampling, on providers that support it. Optional."},"max_completion_tokens":{"type":"integer","format":"int32","description":"The most tokens the model may generate, reasoning tokens included (OpenAI's newer models). Optional."},"reasoning_effort":{"type":"string","description":"How much the model reasons before answering, on reasoning models: for example `low`, `medium` or `high`. On Claude models it sets Anthropic's effort level (`none` and `minimal` become `low`). Optional."},"thinking":{"type":"object","additionalProperties":{},"description":"Extended thinking for Claude models, in Anthropic's form: for example `{\"type\":\"enabled\",  \"budget_tokens\":2048`} or `{\"type\":\"adaptive\"`}. Sent to Anthropic as `thinking`, and to other providers as a body field as sent. Optional; omitted when absent."},"cache_control":{"type":"object","additionalProperties":{},"description":"Anthropic prompt caching for the whole request, for example `{\"type\":\"ephemeral\"`}: Claude caches the prompt up to its last cacheable block. Used on Claude models only. Optional; omitted when absent."},"parallel_tool_calls":{"type":"boolean","description":"`false` to let the model call at most one tool per turn. Optional; the provider's default (parallel calls allowed) when absent."},"logit_bias":{"type":"object","additionalProperties":{"type":"integer","format":"int32"},"description":"Token id to bias (-100 to 100) map that makes tokens more or less likely, on providers that support it. Optional; empty by default."},"response_format":{"type":"object","additionalProperties":{},"description":"The answer's format: `{\"type\":\"text\"`}, `{\"type\":\"json_object\"`}, or `{\"type\":\"json_schema\",\"json_schema\":{\"name\":...,\"schema\":{...`,\"strict\":true}}} for structured output. On Claude models a `json_schema` format is sent as Anthropic's structured output; the other two have no Claude equivalent and are not sent. Optional; empty by default."}},"required":["messages","model"]},"FunctionDefinition":{"type":"object","description":"A function the model may call: its name, what it does, and the JSON Schema of its arguments. Sent inside a `tools` entry of type `function`; the gateway passes it to OpenAI-format providers as is and translates it for Anthropic.","properties":{"name":{"type":"string","description":"The function's name, as the model will call it. Letters, digits, underscores and dashes."},"description":{"type":"string","description":"What the function does and when to use it; the model reads this to decide whether to call it."},"parameters":{"type":"object","additionalProperties":{},"description":"The function's arguments as a JSON Schema object. Empty when the function takes no arguments."},"strict":{"type":"boolean","description":"Strict tool use: the model's arguments are guaranteed to match `parameters`. OpenAI's `function.strict` and Anthropic's tool `strict`; the adapters carry it both ways."}},"required":["name"]},"Tool":{"type":"object","description":"A tool the model may call, in a chat request's `tools`. Only function tools are supported.","properties":{"type":{"type":"string","description":"Always `function`."},"function":{"$ref":"#/components/schemas/FunctionDefinition","description":"The function the model may call: its name, description and JSON Schema parameters. Required."},"cache_control":{"type":"object","additionalProperties":{},"description":"Anthropic prompt caching: a cache breakpoint (`{\"type\":\"ephemeral\"`}, optionally with `\"ttl\":\"1h\"`), as LiteLLM carries it on the OpenAI format. Only the Anthropic adapters send it; omitted from the body when unset."}},"required":["function","type"]},"CreateBatchRequest":{"type":"object","description":"A batch job to create.","properties":{"input_file_id":{"type":"string","description":"The file holding the requests, one JSON request per line (JSONL), uploaded with purpose `batch`: its VectorAxis id (`vxf-...`, for a file uploaded with the same virtual key) or the provider's file id."},"endpoint":{"type":"string","description":"The endpoint every request is sent to, for example `/v1/chat/completions`, `/v1/responses` or `/v1/embeddings`."},"completion_window":{"type":"string","description":"The time the batch has to complete. OpenAI supports `24h`."},"metadata":{"type":"object","additionalProperties":{"type":"string"},"description":"Your own string key/value pairs to attach to the batch. Optional."}},"required":["completion_window","endpoint","input_file_id"]},"BatchError":{"type":"object","description":"An error with the batch as a whole, for example an invalid line in its input file (not the error of one request, which is in the error file).","properties":{"code":{"type":"string","description":"The provider's error code."},"message":{"type":"string","description":"A human-readable description of the error."},"param":{"type":"string","description":"The parameter the error is about. Absent when it is not about a parameter."},"line":{"type":"integer","format":"int32","description":"The line of the input file the error is on, from 1. Absent when it is not about a line."}}},"BatchErrors":{"type":"object","description":"The errors with the batch as a whole.","properties":{"object":{"type":"string","description":"Always `list`."},"data":{"type":"array","description":"The errors.","items":{"$ref":"#/components/schemas/BatchError"}}}},"BatchObject":{"type":"object","description":"A batch job and its current state, as the provider reports it. Its file ids are the provider's.","properties":{"id":{"type":"string","description":"The provider's batch id, for example `batch_...`."},"object":{"type":"string","description":"Always `batch`."},"endpoint":{"type":"string","description":"The endpoint every request in the batch is sent to, for example `/v1/chat/completions`."},"errors":{"$ref":"#/components/schemas/BatchErrors","description":"Errors with the batch as a whole. Absent when there are none."},"input_file_id":{"type":"string","description":"The provider's id of the input file."},"completion_window":{"type":"string","description":"The time the batch has to complete, for example `24h`."},"status":{"type":"string","description":"The batch's state: `validating` (checking the input file), `in_progress` (running), `finalizing` (assembling the results), `completed` (done; `output_file_id` is set), `failed` (failed before running; see `errors`), `expired` (did not finish within `completion_window`), `cancelling` or `cancelled`.","enum":["validating","in_progress","finalizing","completed","failed","expired","cancelling","cancelled"]},"output_file_id":{"type":"string","description":"The provider's id of the file with the successful results. Absent until the batch has results."},"error_file_id":{"type":"string","description":"The provider's id of the file with the failed requests' errors. Absent when there are none."},"created_at":{"type":"integer","format":"int64","description":"When the batch was created, as a Unix timestamp in seconds."},"in_progress_at":{"type":"integer","format":"int64","description":"When the batch started running, as a Unix timestamp in seconds. Absent until then."},"expires_at":{"type":"integer","format":"int64","description":"When the batch expires, as a Unix timestamp in seconds."},"finalizing_at":{"type":"integer","format":"int64","description":"When the batch started finalizing, as a Unix timestamp in seconds. Absent until then."},"completed_at":{"type":"integer","format":"int64","description":"When the batch completed, as a Unix timestamp in seconds. Absent until then."},"failed_at":{"type":"integer","format":"int64","description":"When the batch failed, as a Unix timestamp in seconds. Absent unless it failed."},"expired_at":{"type":"integer","format":"int64","description":"When the batch expired, as a Unix timestamp in seconds. Absent unless it expired."},"cancelling_at":{"type":"integer","format":"int64","description":"When cancellation started, as a Unix timestamp in seconds. Absent unless it was cancelled."},"cancelled_at":{"type":"integer","format":"int64","description":"When the batch was cancelled, as a Unix timestamp in seconds. Absent unless it was cancelled."},"request_counts":{"$ref":"#/components/schemas/BatchRequestCounts","description":"How many requests have finished so far."},"metadata":{"type":"object","additionalProperties":{"type":"string"},"description":"The key/value pairs you attached when creating the batch. Absent when none were."}}},"BatchRequestCounts":{"type":"object","description":"How many of the batch's requests have finished so far.","properties":{"total":{"type":"integer","format":"int32","description":"Requests in the batch."},"completed":{"type":"integer","format":"int32","description":"Requests that completed successfully."},"failed":{"type":"integer","format":"int32","description":"Requests that failed."}}},"TranslationResponse":{"type":"object","description":"The English translation of an audio file.","properties":{"text":{"type":"string","description":"The translated text, in English."}},"required":["text"]},"TranscriptionResponse":{"type":"object","description":"The transcription of an audio file. With `response_format: json` only `text` is present; with `verbose_json` the language, duration, segments and words are added, as requested by `timestamp_granularities`.","properties":{"text":{"type":"string","description":"The transcribed text."},"language":{"type":"string","description":"The detected or given language of the audio. With `verbose_json` only."},"duration":{"type":"number","format":"float","description":"The audio's length, in seconds. With `verbose_json` only."},"segments":{"type":"array","description":"The transcription split into timed segments. With `verbose_json` and segment timestamps only.","items":{"$ref":"#/components/schemas/TranscriptionSegment"}},"words":{"type":"array","description":"Every word with its timing. With `verbose_json` and `timestamp_granularities` including `word` only.","items":{"$ref":"#/components/schemas/TranscriptionWord"}}},"required":["text"]},"TranscriptionSegment":{"type":"object","description":"A segment of the transcription (roughly a sentence) with its timing and the model's quality signals. Present with `response_format: verbose_json`.","properties":{"id":{"type":"integer","format":"int32","description":"The segment's index, from 0."},"seek":{"type":"integer","format":"int32","description":"The seek offset of the segment, in the model's audio frames."},"start":{"type":"number","format":"float","description":"When the segment starts, in seconds from the beginning of the audio."},"end":{"type":"number","format":"float","description":"When the segment ends, in seconds from the beginning of the audio."},"text":{"type":"string","description":"The segment's text."},"tokens":{"type":"array","description":"The token ids of the segment's text.","items":{"type":"integer","format":"int32"}},"temperature":{"type":"number","format":"float","description":"The sampling temperature used for this segment."},"avg_logprob":{"type":"number","format":"float","description":"The average log probability of the segment's tokens. Below -1, the segment may be unreliable."},"compression_ratio":{"type":"number","format":"float","description":"The segment's compression ratio. Above 2.4, the text may be repetitive or unreliable."},"no_speech_prob":{"type":"number","format":"float","description":"The probability, 0 to 1, that the segment contains no speech."}}},"TranscriptionWord":{"type":"object","description":"A single word of the transcription with its timing. Present when `timestamp_granularities` includes `word`.","properties":{"word":{"type":"string","description":"The word as transcribed."},"start":{"type":"number","format":"float","description":"When the word starts, in seconds from the beginning of the audio."},"end":{"type":"number","format":"float","description":"When the word ends, in seconds from the beginning of the audio."}}},"PlatformApiKey":{"type":"object","description":"A platform API key (`va_...`) for the management API, sent as `Authorization: Bearer va_...`. It is not accepted on the inference endpoints, which take a virtual key. The key itself is shown only once, when it is created; this object carries only its last four characters.","properties":{"id":{"type":"string","format":"uuid","description":"The key's id (UUID), used to revoke it."},"name":{"type":"string","description":"The key's name, for people to recognise it."},"organization":{"type":"string","description":"The slug of the organization the key belongs to."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace (UUID) a `workspace`-scoped key is limited to; absent for an `org`-scoped key."},"scope":{"type":"string","description":"`org`: the key acts across the whole organization. `workspace`: it acts only on `  workspace_id`.","enum":["org","workspace"]},"role":{"type":"string","description":"What the key may do: `admin` or `member`, with the same rights as a person with that role in its scope.","enum":["admin","manager","member"]},"key_hint":{"type":"string","description":"The key's last four characters, to tell keys apart."},"expires_at":{"type":"string","format":"date-time","description":"When the key stops working (ISO 8601 date-time); absent when it does not expire."},"last_used_at":{"type":"string","format":"date-time","description":"When the key last authenticated a request (ISO 8601 date-time); absent if it never has."},"created_by":{"type":"string","description":"The user id of the person who created the key."},"status":{"type":"string","description":"`ACTIVE`, or `REVOKED` once revoked; a revoked key is refused.","enum":["ACTIVE","REVOKED"]},"created_at":{"type":"string","format":"date-time","description":"When the key was created (ISO 8601 date-time)."}}},"WorkspaceListResponse":{"type":"object","description":"Workspaces.","properties":{"workspaces":{"type":"array","description":"The workspaces; the list is not paginated.","items":{"$ref":"#/components/schemas/Workspace"}},"total":{"type":"integer","format":"int32","description":"The number of entries in `workspaces`."}}},"WorkspaceMemberListResponse":{"type":"object","description":"The workspace's members and pending invitations.","properties":{"members":{"type":"array","description":"Every explicit member and pending invitation; the list is not paginated.","items":{"$ref":"#/components/schemas/WorkspaceMember"}},"total":{"type":"integer","format":"int32","description":"The number of entries in `members`."}}},"VirtualKeyListResponse":{"type":"object","description":"One page of virtual keys.","properties":{"total":{"type":"integer","format":"int32","description":"How many keys match the filters, across every page."},"page":{"type":"integer","format":"int32","description":"This page's number, starting at 1."},"page_size":{"type":"integer","format":"int32","description":"The page size used (at most 100)."},"data":{"type":"array","description":"The keys on this page.","items":{"$ref":"#/components/schemas/VirtualKey"}}}},"ToolScanSettingsListResponse":{"type":"object","description":"The keys of an organization or workspace whose tool-result scan action is not the platform default, for the virtual key list. Every other key uses `default_action`.","properties":{"default_action":{"type":"string","description":"The platform default action, used by every key not listed in `data`: `MONITOR`, `REDACT` or `BLOCK`.","enum":["MONITOR","REDACT","BLOCK"]},"data":{"type":"array","description":"The keys that set an action of their own. Empty when every key uses the default.","items":{"$ref":"#/components/schemas/ToolScanSettings"}}}},"TrustProviderTerms":{"type":"object","description":"A provider's published data-handling terms for its API, as recorded in the VectorAxis provider catalogue. Every value comes from the pages in `sources`, checked on `reviewed_on`; a null value means the provider's own pages did not clearly state it.","properties":{"legal_entity":{"type":"string","description":"The legal entity that processes API data (several when it depends on the customer's location)."},"headquarters":{"type":"string","description":"ISO country code of the provider's headquarters."},"processing_regions":{"type":"array","description":"Regions where the provider processes API data, as it states them.","items":{"type":"string"}},"data_residency":{"type":"string","description":"Data residency options the provider offers, as it states them."},"trains_on_api_data":{"type":"boolean","description":"Whether the provider trains on API inputs and outputs by default; null when not stated."},"api_data_retention":{"type":"string","description":"How long the provider keeps API inputs and outputs, as it states it."},"zero_retention":{"type":"string","description":"Whether and how zero data retention is available, as the provider states it."},"baa":{"type":"string","description":"Whether and how a HIPAA business associate agreement is available, as the provider states it."},"dpa_url":{"type":"string","description":"Link to the provider's data processing agreement."},"terms_url":{"type":"string","description":"Link to the provider's terms of service."},"privacy_url":{"type":"string","description":"Link to the provider's privacy policy."},"sources":{"type":"array","description":"The provider's pages these facts were taken from.","items":{"type":"string"}},"reviewed_on":{"type":"string","description":"ISO date the facts were last checked against the sources."}}},"TrustSubprocessor":{"type":"object","description":"One party that received, or is set up to receive, the organization's data: a model provider (one entry per legal entity, covering every provider id it serves), an upstream tool server, or a service the platform itself uses.","properties":{"key":{"type":"string","description":"The sub-processor's key: a catalogue key (for example openai, aws), the provider id in lower case when the provider is not catalogued, or the MCP integration slug for a tool server."},"name":{"type":"string","description":"The sub-processor's name."},"category":{"type":"string","description":"What kind of party it is. MODEL_PROVIDER: an AI model provider the requests were sent to. TOOL_SERVER: an upstream MCP server or API called through the MCP Gateway. PLATFORM: a service VectorAxis itself uses to run the gateway (hosting, edge, embeddings, AI guardrail checks).","enum":["MODEL_PROVIDER","TOOL_SERVER","PLATFORM"]},"usage":{"type":"string","description":"OBSERVED: it received the organization's data in the period. CONFIGURED: it is reachable through the organization's configuration (a virtual key, an integration, a guardrail) but received nothing in the period.","enum":["OBSERVED","CONFIGURED"]},"providers":{"type":"array","description":"The provider ids this entry covers (as GET /v1/providers lists them); model providers only.","items":{"type":"string"}},"purposes":{"type":"array","description":"What the data is sent for; platform services and tool servers.","items":{"type":"string"}},"host":{"type":"string","description":"Host of an upstream tool server."},"requests":{"type":"integer","format":"int64","description":"Requests (or tool calls) in the window that reached this party."},"first_seen":{"type":"string","format":"date-time","description":"First request (or tool call) in the window that reached it (ISO 8601 date-time); absent when none did."},"last_seen":{"type":"string","format":"date-time","description":"Last request (or tool call) in the window that reached it (ISO 8601 date-time); absent when none did."},"regions":{"type":"array","description":"Regions requests were sent to, where the gateway knows them; else see the terms' processing regions.","items":{"type":"string"}},"models":{"type":"array","description":"Models used in the window, most used first (at most 50).","items":{"$ref":"#/components/schemas/TrustSubprocessorModel"}},"virtual_keys":{"type":"integer","format":"int32","description":"Active or exhausted virtual keys that can reach this provider."},"catalogued":{"type":"boolean","description":"Whether the provider's terms are in the catalogue; null for tool servers."},"terms":{"$ref":"#/components/schemas/TrustProviderTerms","description":"The provider's published data-handling terms; absent when it is not catalogued, and for tool servers."}}},"TrustSubprocessorModel":{"type":"object","description":"One model of a model provider, as used in the report window.","properties":{"model":{"type":"string","description":"The model id, as requested."},"requests":{"type":"integer","format":"int64","description":"Requests to this model in the window."},"first_seen":{"type":"string","format":"date-time","description":"First request to this model in the window (ISO 8601 date-time)."},"last_seen":{"type":"string","format":"date-time","description":"Last request to this model in the window (ISO 8601 date-time)."}}},"TrustSubprocessorsResponse":{"type":"object","description":"Every party the organization's AI data reached in a window, or can reach through its configuration.","properties":{"organization":{"type":"string","description":"The organization slug the report is for."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace the report is limited to (UUID); absent for an organization-wide report."},"start_time":{"type":"string","format":"date-time","description":"Start of the report window (ISO 8601 date-time)."},"end_time":{"type":"string","format":"date-time","description":"End of the report window (ISO 8601 date-time)."},"generated_at":{"type":"string","format":"date-time","description":"When the report was generated (ISO 8601 date-time)."},"summary":{"$ref":"#/components/schemas/TrustSubprocessorsSummary","description":"Counts over the report's entries."},"data":{"type":"array","description":"The sub-processors: model providers first, then tool servers, then platform services; within each, those that received data in the window first, most used first.","items":{"$ref":"#/components/schemas/TrustSubprocessor"}},"notes":{"type":"array","description":"How to read the report: what is and is not counted.","items":{"type":"string"}}}},"TrustSubprocessorsSummary":{"type":"object","description":"Counts over the report's entries.","properties":{"model_providers":{"type":"integer","format":"int32","description":"Model providers that received data in the window."},"tool_servers":{"type":"integer","format":"int32","description":"Tool servers called in the window."},"platform":{"type":"integer","format":"int32","description":"Platform services listed."},"configured_only":{"type":"integer","format":"int32","description":"Entries that are configured but received nothing in the window."},"uncatalogued":{"type":"integer","format":"int32","description":"Model providers and platform services whose terms are not in the catalogue."},"requests":{"type":"integer","format":"int64","description":"Requests in the window that reached a model provider."}}},"TrustQuestion":{"type":"object","description":"One questionnaire question and its answer.","properties":{"id":{"type":"string","description":"The question's id (for example log-retention), used to write an answer."},"category":{"type":"string","description":"The question's category: AI providers and sub-processors, Data handling, Safety controls, Governance, or Security, audit and evidence."},"question":{"type":"string","description":"The question text."},"status":{"type":"string","description":"Where the answer comes from. GENERATED: built from the organization's records and settings when the questionnaire was read. ANSWERED: written by the organization (it replaces any generated answer). NEEDS_ANSWER: no generated answer, the organization has to answer it.","enum":["GENERATED","ANSWERED","NEEDS_ANSWER"]},"answer":{"type":"string","description":"The answer to send: the organization's own, else the generated one; null when it needs an answer."},"generated_answer":{"type":"string","description":"What the records say, even when the organization wrote its own."},"guidance":{"type":"string","description":"What a good answer covers, for questions only the organization can answer."},"updated_by":{"type":"string","description":"Who wrote the organization's answer: the user id, or api-key:{key id} for a platform API key; absent unless ANSWERED."},"updated_at":{"type":"string","format":"date-time","description":"When the organization's answer was written (ISO 8601 date-time); absent unless ANSWERED."}}},"TrustQuestionnaireResponse":{"type":"object","description":"The AI questionnaire with the organization's answers. Generated answers use the organization-wide reports for the trailing 90 days.","properties":{"organization":{"type":"string","description":"The organization slug."},"entitled":{"type":"boolean","description":"Whether the organization's plan includes the questionnaire (always true here: without it the request is refused with a 402)."},"generated_at":{"type":"string","format":"date-time","description":"When the answers were generated (ISO 8601 date-time)."},"start_time":{"type":"string","format":"date-time","description":"Start of the window the generated answers read (ISO 8601 date-time)."},"end_time":{"type":"string","format":"date-time","description":"End of the window the generated answers read (ISO 8601 date-time)."},"data":{"type":"array","description":"The questions in questionnaire order, each with its answer.","items":{"$ref":"#/components/schemas/TrustQuestion"}}}},"PublicChange":{"type":"object","description":"A sub-processor change, as the public trust page lists it.","properties":{"detected_at":{"type":"string","format":"date-time","description":"When the change was found (ISO 8601 date-time)."},"description":{"type":"string","description":"The change as a sentence."}}},"PublicGuardrails":{"type":"object","description":"What the guardrails check, as the public trust page shows it.","properties":{"checked_percent":{"type":"number","format":"double","description":"Share of AI requests in the period a guardrail checked."},"pii_types_covered":{"type":"array","description":"Personal data types an enabled guardrail redacts or blocks.","items":{"type":"string"}},"protections":{"type":"array","description":"The checks the enabled guardrails run, by name.","items":{"type":"string"}},"tool_result_scan":{"type":"string","description":"What the tool-result scan does with a suspicious tool result: MONITOR, REDACT or BLOCK; null when off."}}},"PublicPolicy":{"type":"object","description":"The approved provider policy, as the public trust page states it.","properties":{"enforced":{"type":"boolean","description":"Requests to providers outside the list are refused before they are sent."},"approved_providers":{"type":"array","description":"Provider names, when enforced.","items":{"type":"string"}}}},"PublicSubprocessor":{"type":"object","description":"A sub-processor as the public trust page shows it: who, why, where and on what terms, without traffic figures. The terms fields come from the provider's own published pages and are absent when they do not clearly say.","properties":{"name":{"type":"string","description":"The sub-processor's name."},"category":{"type":"string","description":"What kind of party it is. MODEL_PROVIDER: an AI model provider the requests were sent to. TOOL_SERVER: an upstream MCP server or API called through the MCP Gateway. PLATFORM: a service VectorAxis itself uses to run the gateway (hosting, edge, embeddings, AI guardrail checks).","enum":["MODEL_PROVIDER","TOOL_SERVER","PLATFORM"]},"usage":{"type":"string","description":"OBSERVED: it received the organization's data in the period. CONFIGURED: it is reachable through the organization's configuration (a virtual key, an integration, a guardrail) but received nothing in the period.","enum":["OBSERVED","CONFIGURED"]},"purposes":{"type":"array","description":"What the data is sent to it for; platform services and tool servers only.","items":{"type":"string"}},"regions":{"type":"array","description":"Regions the data was sent to, where known; absent otherwise.","items":{"type":"string"}},"legal_entity":{"type":"string","description":"The legal entity that processes the data."},"headquarters":{"type":"string","description":"ISO country code of the provider's headquarters."},"trains_on_api_data":{"type":"boolean","description":"Whether the provider trains on API inputs and outputs by default; absent when it does not clearly say."},"api_data_retention":{"type":"string","description":"How long the provider keeps API inputs and outputs, as it states it."},"zero_retention":{"type":"string","description":"Whether and how zero data retention is available, as the provider states it."},"dpa_url":{"type":"string","description":"Link to the provider's data processing agreement."},"terms_url":{"type":"string","description":"Link to the provider's terms of service."},"privacy_url":{"type":"string","description":"Link to the provider's privacy policy."}}},"PublicTrustPage":{"type":"object","description":"An organization's published trust page, built from its records for the trailing 90 days with only the sections it chose. A section that is not chosen is absent.","properties":{"slug":{"type":"string","description":"The page's address (public_slug)."},"display_name":{"type":"string","description":"The company name shown on the page; the organization slug when none is set."},"contact_email":{"type":"string","description":"Where a reviewer can ask questions; absent when not set."},"indexable":{"type":"boolean","description":"Whether the organization lets search engines index the page."},"generated_at":{"type":"string","format":"date-time","description":"When the page was built (ISO 8601 date-time). A page can be served from a cache for up to ten minutes."},"start_time":{"type":"string","format":"date-time","description":"Start of the period the page reports on (ISO 8601 date-time), 90 days before end_time."},"end_time":{"type":"string","format":"date-time","description":"End of the period the page reports on (ISO 8601 date-time)."},"sections":{"type":"array","description":"The sections shown, in order: SUBPROCESSORS, DATA_HANDLING, GUARDRAILS, CHANGES, POLICY.","items":{"type":"string","enum":["SUBPROCESSORS","DATA_HANDLING","GUARDRAILS","CHANGES","POLICY"]}},"subprocessors":{"type":"array","description":"The sub-processors and their terms; SUBPROCESSORS section only.","items":{"$ref":"#/components/schemas/PublicSubprocessor"}},"data_handling":{"type":"array","description":"Data handling statements as plain sentences; DATA_HANDLING section only.","items":{"type":"string"}},"guardrails":{"$ref":"#/components/schemas/PublicGuardrails","description":"What the guardrails check; GUARDRAILS section only."},"changes":{"type":"array","description":"Sub-processor changes in the period, newest first; CHANGES section only.","items":{"$ref":"#/components/schemas/PublicChange"}},"policy":{"$ref":"#/components/schemas/PublicPolicy","description":"The approved provider policy; POLICY section only."}}},"TrustCoverageSummary":{"type":"object","description":"Guardrail coverage of the organization's traffic in the window.","properties":{"requests":{"type":"integer","format":"int64","description":"Requests through the gateway in the window."},"requests_checked":{"type":"integer","format":"int64","description":"Requests at least one guardrail ran on."},"checked_percent":{"type":"number","format":"double","description":"`requests_checked / requests`, 0 to 100, one decimal; null with no requests."},"streamed_requests":{"type":"integer","format":"int64","description":"Streamed requests in the window."},"streamed_requests_checked":{"type":"integer","format":"int64","description":"Streamed requests at least one guardrail ran on."},"blocked":{"type":"integer","format":"int64","description":"Requests whose combined guardrail outcome was BLOCK."},"redacted":{"type":"integer","format":"int64","description":"Requests whose combined guardrail outcome was REDACT."},"monitored":{"type":"integer","format":"int64","description":"Requests whose combined guardrail outcome was MONITOR (flagged, passed through unchanged)."},"tool_results_scanned":{"type":"integer","format":"int64","description":"Tool results in requests, scanned by the always-on tool-result scan."},"tool_results_flagged_requests":{"type":"integer","format":"int64","description":"Requests where the tool-result scan flagged something (MONITOR, REDACT or BLOCK)."},"mcp_calls":{"type":"integer","format":"int64","description":"MCP Gateway tool calls in the window."},"mcp_calls_checked":{"type":"integer","format":"int64","description":"MCP Gateway tool calls a guardrail checked."},"mcp_calls_blocked":{"type":"integer","format":"int64","description":"MCP Gateway tool calls a guardrail blocked."}}},"TrustGuardrailCheckInfo":{"type":"object","description":"One check of a guardrail, as configured.","properties":{"type":{"type":"string","description":"The validator id (for example PII_DETECTOR, prompt_injection), as GET /v1/guardrail-validators lists it."},"name":{"type":"string","description":"The validator's display name; absent for a validator id the gateway no longer knows."},"kind":{"type":"string","description":"DETERMINISTIC (a pattern or rule check run by the gateway) or LLM_JUDGE (an AI check, run by TypeSafe AI)."},"target":{"type":"string","description":"What the check runs on: INPUT (the request), OUTPUT (the response) or BOTH."},"action":{"type":"string","description":"What the check does on a finding: BLOCK, REDACT or MONITOR."},"pii_types":{"type":"array","description":"PII checks only: the personal data types it looks for (EMAIL, PHONE, SSN, CREDIT_CARD, IP_ADDRESS).","items":{"type":"string"}}}},"TrustGuardrailCoverage":{"type":"object","description":"One guardrail: what it checks and what it did in the window.","properties":{"slug":{"type":"string","description":"The guardrail's slug (gr-...)."},"name":{"type":"string","description":"The guardrail's name; absent when it ran in the window but has since been deleted."},"enabled":{"type":"boolean","description":"Whether the guardrail is enabled now; absent when it has been deleted."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace the guardrail belongs to (UUID); absent for an organization-wide guardrail or a deleted one."},"checks":{"type":"array","description":"Its checks, as configured now; absent when it has been deleted.","items":{"$ref":"#/components/schemas/TrustGuardrailCheckInfo"}},"virtual_keys":{"type":"integer","format":"int32","description":"Virtual keys that apply it to every request."},"mcp_bindings":{"type":"integer","format":"int32","description":"MCP connectors and endpoints that apply it to tool calls."},"requests":{"type":"integer","format":"int64","description":"Requests in the window it ran on."},"passed":{"type":"integer","format":"int64","description":"Of those requests, how many passed every guardrail applied to them."},"blocked":{"type":"integer","format":"int64","description":"Of those requests, how many were blocked (by this or another guardrail on the same request)."},"redacted":{"type":"integer","format":"int64","description":"Of those requests, how many were redacted (by this or another guardrail on the same request)."},"monitored":{"type":"integer","format":"int64","description":"Of those requests, how many were flagged without being changed."}}},"TrustGuardrailCoverageResponse":{"type":"object","description":"How much of the organization's traffic its guardrails checked in a window, what each guardrail checks and what it did, the personal data covered and the tool-result scan.","properties":{"organization":{"type":"string","description":"The organization slug the report is for."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace the report is limited to (UUID); absent for an organization-wide report."},"start_time":{"type":"string","format":"date-time","description":"Start of the report window (ISO 8601 date-time)."},"end_time":{"type":"string","format":"date-time","description":"End of the report window (ISO 8601 date-time)."},"generated_at":{"type":"string","format":"date-time","description":"When the report was generated (ISO 8601 date-time)."},"summary":{"$ref":"#/components/schemas/TrustCoverageSummary","description":"Totals over the window."},"guardrails":{"type":"array","description":"Guardrails that ran in the window or are enabled now, most used first.","items":{"$ref":"#/components/schemas/TrustGuardrailCoverage"}},"pii_types_covered":{"type":"array","description":"Personal data types (EMAIL, PHONE, SSN, CREDIT_CARD, IP_ADDRESS) that an enabled PII check with the REDACT or BLOCK action looks for; empty when none does.","items":{"type":"string"}},"tool_scan":{"$ref":"#/components/schemas/TrustToolScan","description":"The scan of tool results sent back to a model through the gateway."},"statements":{"type":"array","description":"The main figures as plain sentences, ready for a questionnaire or a trust page.","items":{"type":"string"}},"notes":{"type":"array","description":"How to read the report: what is and is not counted.","items":{"type":"string"}}}},"TrustToolScan":{"type":"object","description":"The scan of tool results sent back to a model through the gateway, for indirect prompt injection.","properties":{"enabled":{"type":"boolean","description":"Whether the scan runs on this deployment."},"default_action":{"type":"string","description":"What a finding does on a virtual key without its own setting: MONITOR (recorded, the request is unchanged), REDACT (the matched text is replaced) or BLOCK (the request is refused)."},"keys_by_action":{"type":"object","additionalProperties":{"type":"integer","format":"int32"},"description":"Virtual keys with their own scan action, counted per action (MONITOR, REDACT, BLOCK)."},"validators":{"type":"array","description":"The validator ids the scan runs.","items":{"type":"string"}}}},"TrustEvidenceExportListResponse":{"type":"object","description":"The organization's evidence bundles, newest first.","properties":{"data":{"type":"array","description":"The bundles, newest first, at most 50.","items":{"$ref":"#/components/schemas/TrustEvidenceExport"}}}},"TrustCacheRetention":{"type":"object","description":"How long cached responses are kept, and where. Responses are cached only when a request asks for it (the x-cache-mode header).","properties":{"semantic_caching_allowed":{"type":"boolean","description":"Whether the semantic cache is available to the organization. When false, the semantic_* fields are absent."},"exact_ttl_seconds":{"type":"integer","format":"int64","description":"Longest an exact-match entry is kept, in seconds: the organization's ceiling, else the platform default."},"exact_ttl_capped":{"type":"boolean","description":"True when the organization sets its own exact-match TTL, a ceiling a request's x-cache-ttl can shorten but not raise; false when a request may set any TTL."},"exact_storage":{"type":"string","description":"Where exact-match entries are stored, as a phrase."},"semantic_ttl_seconds":{"type":"integer","format":"int64","description":"Longest a semantic entry is served after its last use, in seconds."},"semantic_ttl_capped":{"type":"boolean","description":"True when the organization sets its own semantic TTL, a ceiling a request cannot raise."},"semantic_max_idle_seconds":{"type":"integer","format":"int64","description":"A semantic entry unused this long is deleted, in seconds."},"semantic_sweep_interval_seconds":{"type":"integer","format":"int64","description":"How often unused semantic entries are deleted, in seconds."},"semantic_storage":{"type":"string","description":"Where semantic cache entries are stored, as a phrase (the regional databases that serve the organization's requests)."}}},"TrustDataHandlingResponse":{"type":"object","description":"What VectorAxis keeps of the organization's AI data, for how long and where, and what providers keep at its request, from its current settings.","properties":{"organization":{"type":"string","description":"The organization slug the report is for."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace the report is limited to (UUID); absent for an organization-wide report."},"start_time":{"type":"string","format":"date-time","description":"Start of the report window (ISO 8601 date-time)."},"end_time":{"type":"string","format":"date-time","description":"End of the report window (ISO 8601 date-time)."},"generated_at":{"type":"string","format":"date-time","description":"When the report was generated (ISO 8601 date-time)."},"account_data_storage":{"type":"string","description":"Where the organization's account and settings are stored: the primary database and its region, and any read-only copies."},"logs":{"$ref":"#/components/schemas/TrustLogRetention","description":"How long request logs are kept, and what they hold."},"cache":{"$ref":"#/components/schemas/TrustCacheRetention","description":"How long cached responses are kept, and where."},"provider_storage":{"type":"array","description":"Data the organization asked a provider to keep (files, batches, stored responses), per provider and feature; empty when there is none.","items":{"$ref":"#/components/schemas/TrustProviderStorage"}},"statements":{"type":"array","description":"The same facts as plain sentences, ready for a questionnaire or a trust page.","items":{"type":"string"}},"notes":{"type":"array","description":"How to read the report: what is and is not counted.","items":{"type":"string"}}}},"TrustLogRetention":{"type":"object","description":"How long the gateway keeps the organization's request logs, and what they hold.","properties":{"retention_days":{"type":"integer","format":"int32","description":"Rows older than this are deleted; null = no age limit."},"max_rows":{"type":"integer","format":"int32","description":"Only the newest this many rows are kept; null = no count limit."},"retain_forever":{"type":"boolean","description":"Logs are never deleted on a schedule: kept until the organization is closed."},"bodies_stored":{"type":"boolean","description":"Request and response bodies (and MCP tool-call arguments and results) are stored with the rows."},"monthly_row_limit":{"type":"integer","format":"int32","description":"Most rows written a month; null = unlimited."},"sweep_interval_seconds":{"type":"integer","format":"int64","description":"How often the scheduled deletion applies the age and count rules, in seconds."},"storage":{"type":"string","description":"Where the logs are stored."},"regions":{"type":"array","description":"AWS regions whose local databases hold the organization's logs (each request is logged in the region that served it), within the retention period. Empty before its first logged request.","items":{"type":"string"}}}},"TrustProviderStorage":{"type":"object","description":"Data the organization asked a provider to keep (files, batches, stored responses): it stays at the provider under that provider's terms, outside the gateway's retention rules.","properties":{"provider":{"type":"string","description":"The provider id (for example OPENAI, ANTHROPIC)."},"provider_name":{"type":"string","description":"Catalogue name of the provider, when catalogued."},"feature":{"type":"string","description":"`FILES`, `MESSAGE_BATCHES`, `BATCHES` or `RESPONSES`."},"items":{"type":"integer","format":"int64","description":"Files currently stored, batches created, or responses created (in the window for responses and batches)."},"description":{"type":"string","description":"What the provider holds and why, as a sentence."},"provider_retention":{"type":"string","description":"The provider's published retention for API data, from the catalogue."}}},"TrustChangeEvent":{"type":"object","description":"One change to the organization's sub-processors, found by the daily check.","properties":{"id":{"type":"string","format":"uuid","description":"The change id (UUID)."},"kind":{"type":"string","description":"What changed. SUBPROCESSOR_ADDED: a sub-processor that was not there before. SUBPROCESSOR_REMOVED: no longer used in the report window and no longer configured. SUBPROCESSOR_FIRST_USED: a configured sub-processor received data for the first time. REGION_ADDED: data processed in a new region. MODEL_ADDED: a model provider served a new model (not emailed; sent to the webhook).","enum":["SUBPROCESSOR_ADDED","SUBPROCESSOR_REMOVED","SUBPROCESSOR_FIRST_USED","REGION_ADDED","MODEL_ADDED"]},"category":{"type":"string","description":"What kind of party it is. MODEL_PROVIDER: an AI model provider the requests were sent to. TOOL_SERVER: an upstream MCP server or API called through the MCP Gateway. PLATFORM: a service VectorAxis itself uses to run the gateway (hosting, edge, embeddings, AI guardrail checks).","enum":["MODEL_PROVIDER","TOOL_SERVER","PLATFORM"]},"subprocessor":{"type":"string","description":"The sub-processor's key, as in the sub-processor report (for example openai, an integration slug, aws)."},"name":{"type":"string","description":"The sub-processor's name."},"subject":{"type":"string","description":"The model (MODEL_ADDED), the region (REGION_ADDED), or the usage OBSERVED / CONFIGURED (SUBPROCESSOR_ADDED)."},"description":{"type":"string","description":"The change as a sentence."},"region":{"type":"string","description":"The deployment region whose snapshot found it."},"detected_at":{"type":"string","format":"date-time","description":"When the change was found (ISO 8601 date-time)."},"notified_at":{"type":"string","format":"date-time","description":"When the alerts (email, webhook) went out; null while pending."}}},"TrustChangesResponse":{"type":"object","description":"Changes to the organization's sub-processors found in a window, newest first.","properties":{"organization":{"type":"string","description":"The organization slug the report is for."},"start_time":{"type":"string","format":"date-time","description":"Start of the report window (ISO 8601 date-time)."},"end_time":{"type":"string","format":"date-time","description":"End of the report window (ISO 8601 date-time)."},"last_checked_at":{"type":"string","format":"date-time","description":"When the daily check last ran for the organization (ISO 8601 date-time); absent before the first check."},"data":{"type":"array","description":"The changes in the window, newest first, at most 500.","items":{"$ref":"#/components/schemas/TrustChangeEvent"}},"notes":{"type":"array","description":"How to read the report: what is and is not counted.","items":{"type":"string"}}}},"ToolInventoryEntry":{"type":"object","description":"One tool name seen in the window, from any of three sources: declared on LLM requests, called by the model, or called through the MCP Gateway. Names are client-supplied - display them, never trust them.","properties":{"name":{"type":"string","description":"The tool's name, as declared or called. Names come from your agents and MCP servers and are not verified."},"declared_requests":{"type":"integer","format":"int64","description":"LLM requests whose `tools[]` declared it."},"model_calls":{"type":"integer","format":"int64","description":"Times a model asked to call it."},"gateway_calls":{"type":"integer","format":"int64","description":"`tools/call`s through the MCP Gateway."},"definitions":{"type":"integer","format":"int32","description":"Distinct definitions (name + description + parameters) declared under this name. More than one means the tool changed - a rug pull or tool shadowing looks exactly like this."},"first_seen":{"type":"string","format":"date-time","description":"When the tool was first seen in the window, in any source (ISO 8601 date-time)."},"last_seen":{"type":"string","format":"date-time","description":"When the tool was last seen in the window, in any source (ISO 8601 date-time)."},"virtual_keys":{"type":"array","description":"Up to 10 virtual keys that declared it.","items":{"type":"string"}},"models":{"type":"array","description":"Up to 10 models it was declared to.","items":{"type":"string"}},"registered":{"type":"boolean","description":"An MCP Gateway integration in the org exposes a tool of this name. False = shadow tool."},"servers":{"type":"array","description":"Gateway servers that expose it (in the requested workspace, when one is given).","items":{"$ref":"#/components/schemas/ToolInventoryServer"}}}},"ToolInventoryResponse":{"type":"object","description":"The AI inventory: every tool agents use, and whether the MCP Gateway governs it.","properties":{"start_time":{"type":"string","format":"date-time","description":"Start of the window the inventory covers, inclusive (ISO 8601 date-time)."},"end_time":{"type":"string","format":"date-time","description":"End of the window the inventory covers, exclusive (ISO 8601 date-time)."},"summary":{"$ref":"#/components/schemas/ToolInventorySummary","description":"Counts over the whole window; not limited by the cap on the tool list."},"data":{"type":"array","description":"Most used first; capped at `limit`.","items":{"$ref":"#/components/schemas/ToolInventoryEntry"}},"truncated":{"type":"boolean","description":"True when more tool names exist than were returned."}}},"ToolInventoryServer":{"type":"object","description":"An MCP Gateway server whose integration exposes a tool of the same name.","properties":{"slug":{"type":"string","description":"The MCP Gateway server's slug."},"name":{"type":"string","description":"The MCP Gateway server's display name."}}},"ToolInventorySummary":{"type":"object","description":"Totals for the tool inventory's window.","properties":{"tools":{"type":"integer","format":"int32","description":"Distinct tool names in the inventory (the length of `data`)."},"unregistered_tools":{"type":"integer","format":"int32","description":"Tools seen in traffic that no MCP Gateway integration exposes."},"changed_tools":{"type":"integer","format":"int32","description":"Tools declared with more than one definition in the window."},"requests_with_tools":{"type":"integer","format":"int64","description":"LLM requests in the window that declared at least one tool."},"tool_results":{"type":"integer","format":"int64","description":"Tool-role messages (results fed back to the model) on LLM requests."},"flagged_requests":{"type":"integer","format":"int64","description":"LLM requests whose tool results the always-on scan flagged (MONITOR, REDACT or BLOCK)."},"gateway_calls":{"type":"integer","format":"int64","description":"Tool calls (`tools/call`) made through the MCP Gateway in the window, whatever their outcome."}}},"TrustSigningKeyResponse":{"type":"object","description":"The public key that verifies evidence bundles: a reviewer checks manifest.sig against manifest.json with it, and that key_id matches the one in the manifest.","properties":{"key_id":{"type":"string","description":"The key id, the first 16 hex characters of the SHA-256 of the public key; the same id is in each bundle's manifest."},"algorithm":{"type":"string","description":"The signature algorithm, always Ed25519."},"public_key_pem":{"type":"string","description":"The public key, X.509 SubjectPublicKeyInfo in PEM encoding (what openssl reads)."}}},"PromptListResponse":{"type":"object","description":"A page of prompts.","properties":{"total":{"type":"integer","format":"int64","description":"Number of prompts in the organization, or in the workspace when `workspace_id` was given. It does not apply `search`."},"page":{"type":"integer","format":"int32","description":"The page number, from 1."},"page_size":{"type":"integer","format":"int32","description":"Prompts per page."},"data":{"type":"array","description":"The prompts on this page, after `search` is applied to the page.","items":{"$ref":"#/components/schemas/Prompt"}}}},"PromptDetail":{"type":"object","description":"A prompt with the version it serves by default.","properties":{"id":{"type":"string","description":"The prompt's unique id (UUID)."},"slug":{"type":"string","description":"The prompt's identifier in URLs and in the `x-prompt-slug` header. Generated at creation from the name (lower case, every run of other characters as one dash, at most 40 characters) plus a dash and 8 random hex characters, for example `support-reply-3f9a1c2b`. It never changes."},"name":{"type":"string","description":"Display name, unique within the organization."},"description":{"type":"string","description":"Free-text description. Null when none is set."},"organization":{"type":"string","description":"Slug of the organization that owns the prompt."},"workspace_id":{"type":"string","format":"uuid","description":"Id (UUID) of the workspace the prompt belongs to. Currently null when the prompt has no default version (`published_version` is null)."},"created_at":{"type":"string","format":"date-time","description":"When the prompt was created (ISO 8601)."},"updated_at":{"type":"string","format":"date-time","description":"When the prompt was created or its name or description last changed (ISO 8601)."},"published_version":{"$ref":"#/components/schemas/PromptVersion","description":"The version used when a request names none: the one the `production` label points at, else the PUBLISHED version. Null when there is neither."}}},"PromptVersionListResponse":{"type":"object","description":"A prompt's versions, highest version number first.","properties":{"prompt_slug":{"type":"string","description":"Slug of the prompt."},"data":{"type":"array","description":"The versions, without their content.","items":{"$ref":"#/components/schemas/PromptVersionSummary"}}}},"PromptVersionSummary":{"type":"object","description":"A prompt version without its content. Get a prompt version for its messages, variables and tools.","properties":{"id":{"type":"string","description":"The version's unique id (UUID)."},"prompt_id":{"type":"string","description":"Id (UUID) of the prompt the version belongs to."},"version_number":{"type":"integer","format":"int32","description":"The version's number within the prompt, from 1."},"status":{"type":"string","description":"Lifecycle state: `DRAFT` (saved, never published), `PUBLISHED` (the prompt's published version; at most one at a time) or `ARCHIVED` (was the published version until another version was published).","enum":["DRAFT","PUBLISHED","ARCHIVED"]},"labels":{"type":"array","description":"Labels currently pointing at this version, for example `production`. Empty when none.","items":{"type":"string"}},"model":{"type":"string","description":"The model completions use, for example `gpt-4o`. Null when none was set: a completion or test run must then send `model_override`."},"created_at":{"type":"string","format":"date-time","description":"When the version was saved (ISO 8601)."},"created_by":{"type":"string","description":"Identifier of the caller (user or API key) that saved the version, or `unknown` when the caller could not be identified."}}},"PromptTestCaseListResponse":{"type":"object","description":"A prompt's test cases.","properties":{"prompt_slug":{"type":"string","description":"Slug of the prompt."},"data":{"type":"array","description":"The test cases.","items":{"$ref":"#/components/schemas/PromptTestCase"}}}},"PromptAuditLogEntry":{"type":"object","description":"One change recorded in a prompt's audit log.","properties":{"id":{"type":"string","description":"The entry's unique id (UUID)."},"prompt_id":{"type":"string","description":"Id (UUID) of the prompt."},"action":{"type":"string","description":"What happened: `CREATE` (prompt created), `VERSION_SAVE` (version saved), `PUBLISH` (version published), `LABEL_ADD` (label set), `LABEL_REMOVE` (label removed), `ROLLBACK` (an earlier version saved again as a new version), `DELETE` (prompt deleted) or `TEST_RUN` (test cases run).","enum":["CREATE","VERSION_SAVE","PUBLISH","LABEL_ADD","LABEL_REMOVE","ROLLBACK","DELETE","TEST_RUN"]},"actor_id":{"type":"string","description":"Identifier of the caller (user or API key) that made the change, or `unknown` when the caller could not be identified."},"detail":{"type":"object","additionalProperties":{},"description":"Details of the change, by action: for example `slug` and `name`, `version_number`, `  labels`, `label`, `from_version` and `to_version`, or `pass_count` and `  fail_count`."},"created_at":{"type":"string","format":"date-time","description":"When the change was made (ISO 8601)."}}},"PromptAuditLogResponse":{"type":"object","description":"A page of a prompt's audit log, newest entry first.","properties":{"total":{"type":"integer","format":"int64","description":"Number of entries in the whole log."},"page":{"type":"integer","format":"int32","description":"The page number, from 1."},"page_size":{"type":"integer","format":"int32","description":"Entries per page."},"entries":{"type":"array","description":"The entries on this page.","items":{"$ref":"#/components/schemas/PromptAuditLogEntry"}}}},"PromptAnalyticsSummary":{"type":"object","description":"Usage of a prompt over a time window, from the gateway's request logs: every request attributed to the prompt, whether made with Run a prompt or with the `x-prompt-slug` header. Only requests of the prompt's own organization made with a virtual key or a routing config count.","properties":{"prompt_slug":{"type":"string","description":"Slug of the prompt."},"time_window_start":{"type":"string","format":"date-time","description":"Start of the window, inclusive (ISO 8601)."},"time_window_end":{"type":"string","format":"date-time","description":"End of the window, exclusive (ISO 8601)."},"total_requests":{"type":"integer","format":"int64","description":"Requests in the window, across all versions."},"total_cost_usd":{"type":"number","format":"double","description":"Total cost in USD across all versions. Requests answered from the cache cost 0."},"avg_duration_ms":{"type":"number","format":"double","description":"The mean of the versions' average request durations, in milliseconds: each version counts once, whatever its number of requests. 0 when there were no requests."},"p95_duration_ms":{"type":"number","format":"double","description":"The highest of the versions' 95th-percentile request durations, in milliseconds. Null when there were no requests."},"cache_hit_rate":{"type":"number","format":"double","description":"The mean of the versions' cache hit rates, from 0 to 1: each version counts once. 0 when there were no requests."},"by_version":{"type":"array","description":"Figures per version, highest version first.","items":{"$ref":"#/components/schemas/PromptVersionAnalytics"}}}},"PromptVersionAnalytics":{"type":"object","description":"Usage of one prompt version over the time window.","properties":{"version_number":{"type":"integer","format":"int32","description":"The prompt version. Null for requests attributed to the prompt without a version."},"total_requests":{"type":"integer","format":"int64","description":"Requests in the window."},"total_cost_usd":{"type":"number","format":"double","description":"Total cost in USD. Requests answered from the cache cost 0."},"avg_duration_ms":{"type":"number","format":"double","description":"Average request duration, in milliseconds."},"p95_duration_ms":{"type":"number","format":"double","description":"95th-percentile request duration, in milliseconds."},"cache_hit_rate":{"type":"number","format":"double","description":"Share of requests answered from the cache (exact or semantic hit), from 0 to 1."}}},"GetPlatformPricing200Response":{"type":"object","description":"The prices VectorAxis charges for requests made with a PLATFORM virtual key.","properties":{"markup_pct":{"type":"number","format":"double","description":"The platform markup included in every price, as a fraction of the provider's price (`0.06` is 6%). A key with its own `markup_pct` is charged at that instead."},"entries":{"type":"array","description":"One price per model, sorted by provider, then model.","items":{"$ref":"#/components/schemas/PricingEntry"}}}},"PricingEntry":{"type":"object","description":"The PLATFORM key price of one model, with the platform markup included.","properties":{"provider":{"type":"string","description":"The provider id, e.g. `OPENAI`."},"model":{"type":"string","description":"The model id without its provider prefix, e.g. `gpt-4o`."},"request_model":{"type":"string","description":"The model id with its provider prefix, e.g. `openai/gpt-4o`: send this as `model` to be sure a PLATFORM key picks this provider."},"input_cost_per_token":{"type":"number","format":"double","description":"USD per input token, markup included."},"output_cost_per_token":{"type":"number","format":"double","description":"USD per output token, markup included."},"mode":{"type":"string","description":"What kind of model it is: `CHAT`, `IMAGE_GENERATION`, `AUDIO_TRANSCRIPTION`, `AUDIO_SPEECH` or `SYSTEM_ONE`.","enum":["CHAT","IMAGE_GENERATION","AUDIO_TRANSCRIPTION","AUDIO_SPEECH","SYSTEM_ONE"]},"supported_endpoints":{"type":"array","description":"The endpoint that serves this kind of model: `/v1/chat/completions`, `/v1/images/generations`, `/v1/audio/transcriptions`, `/v1/audio/speech` or `/v1/systemone`.","items":{"type":"string"}}}},"OrgMemberListResponse":{"type":"object","description":"The organization's members and pending invitations.","properties":{"members":{"type":"array","description":"Every member and pending invitation; the list is not paginated.","items":{"$ref":"#/components/schemas/OrgMember"}},"total":{"type":"integer","format":"int32","description":"The number of entries in `members`."}}},"OrgClosureEligibility":{"type":"object","description":"Whether the organization can be closed now, and if not, why.","properties":{"closeable":{"type":"boolean","description":"True when closing the organization would be allowed now."},"blocking_reason":{"type":"string","description":"Why it cannot be closed: `ORG_HAS_CREDIT_BALANCE` (withdraw or spend the credit balance first) or `  WITHDRAWAL_IN_PROGRESS` (a credit withdrawal is still being refunded). Absent when `closeable` is true."},"credit_balance_usd":{"type":"number","format":"double","description":"The organization's credit balance, in USD; 0 when it has no credit account."}}},"SystemOneModelCard":{"type":"object","description":"A System One model.","properties":{"name":{"type":"string","description":"The model's id, to send as `model`, for example `jev-latest`."},"description":{"type":"string","description":"What the model is."},"release_date":{"type":"string","description":"When the model was released, as TypeSafe reports it."}},"required":["description","name","release_date"]},"SystemOneModelList":{"type":"object","description":"The System One models your TypeSafe credential can use.","properties":{"models":{"type":"array","description":"The models.","items":{"$ref":"#/components/schemas/SystemOneModelCard"}}},"required":["models"]},"McpConnection":{"type":"object","description":"A live connection: a person's consent for one MCP client to use one MCP server as them. Revoking it cuts the client off at its next call.","properties":{"id":{"type":"string","format":"uuid","description":"The connection's ID (UUID)."},"user_id":{"type":"string","description":"The person who consented."},"user_email":{"type":"string","description":"That person's email, for display."},"server_slug":{"type":"string","description":"The MCP server's slug."},"server_name":{"type":"string","description":"The MCP server's name."},"client_id":{"type":"string","description":"The MCP client's OAuth client ID."},"client_name":{"type":"string","description":"The MCP client's name, as it registered."},"scope":{"type":"string","description":"The OAuth scope granted."},"created_at":{"type":"string","format":"date-time","description":"When the person consented (ISO 8601)."},"last_used_at":{"type":"string","format":"date-time","description":"When the client last used it (ISO 8601). Updated at most every five minutes."}}},"McpConnectionListResponse":{"type":"object","description":"A list of live connections.","properties":{"data":{"type":"array","description":"The connections.","items":{"$ref":"#/components/schemas/McpConnection"}}}},"McpToolHealth":{"type":"object","description":"How a tool has been doing lately: agents' calls through the gateway in the last `window_minutes`, in this region.","properties":{"server_slug":{"type":"string","description":"The MCP server the calls went through."},"tool":{"type":"string","description":"The tool's name."},"status":{"type":"string","description":"`HEALTHY`; `DEGRADED` (failing sometimes, or slow); `OUTAGE` (failing most of the time); or `UNKNOWN` (too few calls to say)."},"reason":{"type":"string","description":"Why, in a sentence. Absent when `HEALTHY` or `UNKNOWN`."},"calls":{"type":"integer","format":"int64","description":"Calls in the window."},"failures":{"type":"integer","format":"int64","description":"Calls that failed or timed out at the gateway or the upstream (`FAILED`, `TIMED_OUT`)."},"failure_rate":{"type":"number","format":"double","description":"`failures` divided by `calls`, 0 to 1."},"tool_errors":{"type":"integer","format":"int64","description":"Calls that went through but on which the tool reported an error (often bad arguments)."},"p50_ms":{"type":"integer","format":"int64","description":"Median latency of completed calls, in milliseconds."},"p95_ms":{"type":"integer","format":"int64","description":"95th-percentile latency of completed calls, in milliseconds."},"last_failure_at":{"type":"string","format":"date-time","description":"When the last failure happened (ISO 8601)."},"window_minutes":{"type":"integer","format":"int32","description":"The length of the window, in minutes."}}},"McpToolSearchResponse":{"type":"object","description":"Tools found by a search.","properties":{"query":{"type":"string","description":"The query, as searched (trimmed)."},"data":{"type":"array","description":"The tools, best match first; a tool that has been failing ranks lower.","items":{"$ref":"#/components/schemas/McpToolSearchResult"}}}},"McpToolSearchResult":{"type":"object","description":"One tool a search found: the tool, the MCP server that reaches it, and how close it is to the query.","properties":{"id":{"type":"string","description":"`{server slug}/{tool name}`: how the tool is named across servers (the format of an MCP key's allowlist)."},"name":{"type":"string","description":"The tool's name."},"title":{"type":"string","description":"The tool's title, when it has one."},"description":{"type":"string","description":"The tool's description."},"server_slug":{"type":"string","description":"The MCP server that reaches the tool."},"server_name":{"type":"string","description":"That server's name."},"integration_slug":{"type":"string","description":"The connector behind the server."},"is_privileged":{"type":"boolean","description":"Whether the tool is privileged (refused for a caller that received untrusted content recently)."},"requires_approval":{"type":"boolean","description":"Whether every call to the tool waits for a person's approval."},"score":{"type":"number","format":"double","description":"Similarity to the query, 0 to 1, before health is applied to the ranking."},"health":{"$ref":"#/components/schemas/McpToolHealth","description":"How the tool has been doing lately. Absent when it has not been called in the window."}}},"McpServerListResponse":{"type":"object","description":"A page of MCP servers.","properties":{"data":{"type":"array","description":"The servers.","items":{"$ref":"#/components/schemas/McpServer"}},"page":{"type":"integer","format":"int32","description":"The page number."},"page_size":{"type":"integer","format":"int32","description":"Servers per page."},"total":{"type":"integer","format":"int64","description":"Matching servers across all pages."}}},"McpToolRunListResponse":{"type":"object","description":"A page of calls through the MCP Gateway, newest first.","properties":{"data":{"type":"array","description":"The calls.","items":{"$ref":"#/components/schemas/McpToolRun"}},"page":{"type":"integer","format":"int32","description":"The page number."},"page_size":{"type":"integer","format":"int32","description":"Calls per page."},"total":{"type":"integer","format":"int64","description":"Matching calls across all pages."}}},"McpAuditEntry":{"type":"object","description":"One entry in the audit log of a connector or an MCP server.","properties":{"id":{"type":"string","format":"uuid","description":"The entry's ID (UUID)."},"entity_type":{"type":"string","description":"What changed: `INTEGRATION` (a connector) or `SERVER` (an MCP server)."},"entity_slug":{"type":"string","description":"The slug of the connector or server."},"action":{"type":"string","description":"What happened, for example `CREATED`, `UPDATED`, `DELETED`, `SYNCED`, `SYNC_FAILED`, `QUARANTINED`, `CAPABILITIES_UPDATED`, `WORKSPACE_ACCESS_UPDATED`, `POLICY_UPDATED`, `USER_ACCESS_UPDATED`, `CONNECTIONS_REVOKED`, `ORG_CONNECTION_REMOVED`, `CALL_APPROVED` or `CALL_REJECTED`."},"actor_id":{"type":"string","description":"The ID of the user (or platform key) that made the change."},"detail":{"description":"Details of the change as a JSON object (fields changed, counts, findings); its shape depends on `action`. Never contains credentials."},"created_at":{"type":"string","format":"date-time","description":"When it happened (ISO 8601)."}}},"McpAuditResponse":{"type":"object","description":"A page of audit log entries, newest first.","properties":{"data":{"type":"array","description":"The entries.","items":{"$ref":"#/components/schemas/McpAuditEntry"}},"page":{"type":"integer","format":"int32","description":"The page number."},"page_size":{"type":"integer","format":"int32","description":"Entries per page."}}},"McpKeyListResponse":{"type":"object","description":"A workspace's MCP keys, newest first, revoked ones included.","properties":{"data":{"type":"array","description":"The keys.","items":{"$ref":"#/components/schemas/McpKey"}}}},"McpIntegrationListResponse":{"type":"object","description":"A page of connectors.","properties":{"data":{"type":"array","description":"The connectors.","items":{"$ref":"#/components/schemas/McpIntegration"}},"page":{"type":"integer","format":"int32","description":"The page number."},"page_size":{"type":"integer","format":"int32","description":"Connectors per page."},"total":{"type":"integer","format":"int64","description":"Matching connectors across all pages."}}},"McpOrgConnection":{"type":"object","description":"The organization connection of an `OAUTH_AUTO` connector: the upstream account an organization admin connected, which agents on an MCP key use. Only `connected: false` when there is none. Tokens are never returned.","properties":{"connected":{"type":"boolean","description":"Whether there is an organization connection."},"status":{"type":"string","description":"`ACTIVE`, or `EXPIRED` (a token refresh failed: an organization admin must connect again)."},"connected_by":{"type":"string","description":"The user ID of the admin who connected it."},"connected_by_email":{"type":"string","description":"That admin's email, for display."},"scope":{"type":"string","description":"The OAuth scope the upstream granted."},"connected_at":{"type":"string","format":"date-time","description":"When it was connected (ISO 8601)."},"expires_at":{"type":"string","format":"date-time","description":"When the current access token expires (ISO 8601); the gateway refreshes it."}}},"LogEntry":{"type":"object","description":"One request in the log search results. Request and response bodies are not included; read the log by its `id` for them.","properties":{"id":{"type":"string","description":"The log's id (UUID). Use it to read the log in full."},"request_id":{"type":"string","description":"The request id the call ran under: the caller's `X-Request-ID`, or one the gateway generated. For a Message Batch request, `<batch id>/<custom_id>`."},"created_at":{"type":"string","format":"date-time","description":"When the request was logged (ISO 8601 date-time)."},"provider":{"type":"string","description":"The provider the request went to, upper case with underscores, e.g. `OPENAI` or `VERTEX_AI`."},"model":{"type":"string","description":"The model id the request asked for."},"status_code":{"type":"integer","format":"int32","description":"The HTTP status the request ended with. 499 means the caller disconnected during a stream."},"duration_ms":{"type":"integer","format":"int64","description":"How long the request took at the gateway, in milliseconds."},"streaming":{"type":"boolean","description":"Whether the response was streamed."},"organization":{"type":"string","description":"The slug of the organization the request belongs to."},"user_id":{"type":"string","description":"The end user the caller attributed the request to (the request's `user` field, or `metadata.user_id` on Claude Messages); null when none was sent."},"prompt_tokens":{"type":"integer","format":"int32","description":"Input tokens, cached input included. Null when the provider reported no usage."},"completion_tokens":{"type":"integer","format":"int32","description":"Output tokens. Null when the provider reported no usage."},"total_tokens":{"type":"integer","format":"int32","description":"Input plus output tokens. Null when the provider reported no usage."},"cost":{"type":"number","format":"double","description":"What the request cost, in USD, including the platform markup on a PLATFORM virtual key. 0 on a cache hit; null when the model has no price."},"cost_saved_usd":{"type":"number","format":"double","description":"What a cache hit would have cost, in USD (`cost` is 0 on a hit); null on every other request."},"cache_status":{"type":"string","description":"The response cache result: `HIT`, `SEMANTIC_HIT`, `MISS`, `BYPASS`, `DISABLED` or `REFRESH`."},"retry_count":{"type":"integer","format":"int32","description":"How many times the gateway retried the call (see `x-retry-count`)."},"fallback_provider":{"type":"string","description":"The fallback provider that served the request when the primary failed; null when no fallback was used."},"virtual_key_slug":{"type":"string","description":"The virtual key the request was made with (`vk-...`); null for direct provider credentials."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace the request belongs to (UUID); null when it has none."},"config_slug":{"type":"string","description":"The routing config the request was routed through; null when none was used."},"guardrail_slug":{"type":"string","description":"The guardrails that applied to the request, comma-separated (`gr-...`); null when none did."},"guardrail_status":{"type":"string","description":"The combined guardrail result over the input and output checks: `PASS`, `MONITOR`, `REDACT`, `BLOCK` or `BYPASS`; null when no guardrail applied."},"tool_scan_status":{"type":"string","description":"The result of the scan of the tool results the request fed back to the model: `PASS`, `MONITOR`, `REDACT` or `BLOCK`; null when the request carried no tool results."},"initiator":{"type":"string","description":"`MCP_SERVER` when the MCP Gateway made this request on behalf of an MCP server's sampling request; null otherwise."},"mcp_server_slug":{"type":"string","description":"The MCP server whose sampling request this request answered; null otherwise."},"region":{"type":"string","description":"The AWS region that served the request and holds this log, e.g. `us-east-2`; null on logs written before it was recorded."},"tool_call_names":{"type":"array","description":"The function names the model asked to call, in the order it asked; null or empty when it asked for none.","items":{"type":"string"}},"tool_result_count":{"type":"integer","format":"int32","description":"How many tool results (tool-role messages) the request carried."},"declared_tool_count":{"type":"integer","format":"int32","description":"How many tools the caller declared on the request."}}},"LogSearchResponse":{"type":"object","description":"One page of request logs matching a search.","properties":{"total":{"type":"integer","format":"int64","description":"How many logs match the search, over all pages."},"page":{"type":"integer","format":"int32","description":"This page's number, starting at 1."},"page_size":{"type":"integer","format":"int32","description":"The most logs a page holds."},"data":{"type":"array","description":"The logs on this page.","items":{"$ref":"#/components/schemas/LogEntry"}}}},"LogDetail":{"type":"object","description":"One request's log in full: everything in the search results, plus the error message, the declared tools, the media details of document operations and, when the organization stores them, the request and response bodies.","properties":{"id":{"type":"string","description":"The log's id (UUID). Use it to read the log in full."},"request_id":{"type":"string","description":"The request id the call ran under: the caller's `X-Request-ID`, or one the gateway generated. For a Message Batch request, `<batch id>/<custom_id>`."},"created_at":{"type":"string","format":"date-time","description":"When the request was logged (ISO 8601 date-time)."},"provider":{"type":"string","description":"The provider the request went to, upper case with underscores, e.g. `OPENAI` or `VERTEX_AI`."},"model":{"type":"string","description":"The model id the request asked for."},"status_code":{"type":"integer","format":"int32","description":"The HTTP status the request ended with. 499 means the caller disconnected during a stream."},"duration_ms":{"type":"integer","format":"int64","description":"How long the request took at the gateway, in milliseconds."},"streaming":{"type":"boolean","description":"Whether the response was streamed."},"organization":{"type":"string","description":"The slug of the organization the request belongs to."},"user_id":{"type":"string","description":"The end user the caller attributed the request to (the request's `user` field, or `metadata.user_id` on Claude Messages); null when none was sent."},"prompt_tokens":{"type":"integer","format":"int32","description":"Input tokens, cached input included. Null when the provider reported no usage."},"completion_tokens":{"type":"integer","format":"int32","description":"Output tokens. Null when the provider reported no usage."},"total_tokens":{"type":"integer","format":"int32","description":"Input plus output tokens. Null when the provider reported no usage."},"cost":{"type":"number","format":"double","description":"What the request cost, in USD, including the platform markup on a PLATFORM virtual key. 0 on a cache hit; null when the model has no price."},"cost_saved_usd":{"type":"number","format":"double","description":"What a cache hit would have cost, in USD (`cost` is 0 on a hit); null on every other request."},"cache_status":{"type":"string","description":"The response cache result: `HIT`, `SEMANTIC_HIT`, `MISS`, `BYPASS`, `DISABLED` or `REFRESH`."},"error_message":{"type":"string","description":"Why a failed request failed, with the provider's own message when the provider refused it; null on success."},"retry_count":{"type":"integer","format":"int32","description":"How many times the gateway retried the call (see `x-retry-count`)."},"fallback_provider":{"type":"string","description":"The fallback provider that served the request when the primary failed; null when no fallback was used."},"virtual_key_slug":{"type":"string","description":"The virtual key the request was made with (`vk-...`); null for direct provider credentials."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace the request belongs to (UUID); null when it has none."},"config_slug":{"type":"string","description":"The routing config the request was routed through; null when none was used."},"guardrail_slug":{"type":"string","description":"The guardrails that applied to the request, comma-separated (`gr-...`); null when none did."},"guardrail_status":{"type":"string","description":"The combined guardrail result over the input and output checks: `PASS`, `MONITOR`, `REDACT`, `BLOCK` or `BYPASS`; null when no guardrail applied."},"tool_scan_status":{"type":"string","description":"The result of the scan of the tool results the request fed back to the model: `PASS`, `MONITOR`, `REDACT` or `BLOCK`; null when the request carried no tool results."},"initiator":{"type":"string","description":"`MCP_SERVER` when the MCP Gateway made this request on behalf of an MCP server's sampling request; null otherwise."},"mcp_server_slug":{"type":"string","description":"The MCP server whose sampling request this request answered; null otherwise."},"region":{"type":"string","description":"The AWS region that served the request and holds this log, e.g. `us-east-2`; null on logs written before it was recorded."},"tool_call_names":{"type":"array","description":"The function names the model asked to call, in the order it asked; null or empty when it asked for none.","items":{"type":"string"}},"tool_result_count":{"type":"integer","format":"int32","description":"How many tool results (tool-role messages) the request carried."},"declared_tool_count":{"type":"integer","format":"int32","description":"How many tools the caller declared on the request."},"declared_tools":{"type":"array","description":"The tools declared on the request: each one's `name` and the `schema_hash` of its definition.","items":{"type":"object","additionalProperties":{}}},"request_body":{"type":"string","description":"The request as sent, as JSON text, with inline images, files and audio elided. Null unless the organization stores request and response bodies."},"response_body":{"type":"string","description":"The response, as JSON text (a streamed answer is rebuilt whole), or the provider's error body on a failed request. Null unless the organization stores request and response bodies."},"operation_type":{"type":"string","description":"The kind of operation, e.g. `embedding`, `transcription`, `image_generation`, `  file_upload`, `batch_create`, `response_create`, `message_batch`, `system_one` or `  openai_decision`; null for chat and Claude Messages requests."},"file_size_bytes":{"type":"integer","format":"int64","description":"The size of the uploaded file or audio, in bytes; only on file and audio operations."},"mime_type":{"type":"string","description":"The media type of the uploaded file or audio; only on file and audio operations."},"media_format":{"type":"string","description":"The audio or response format of an audio or image operation, e.g. `mp3` or `json`."},"image_size":{"type":"string","description":"The requested image size, e.g. `1024x1024`; only on image operations."},"image_quality":{"type":"string","description":"The requested image quality, e.g. `standard` or `hd`; only on image operations."},"image_count":{"type":"integer","format":"int32","description":"How many images were generated; only on image operations."},"audio_duration_seconds":{"type":"number","format":"double","description":"The length of the audio, in seconds; only on audio operations."},"voice":{"type":"string","description":"The voice used for text-to-speech; only on speech operations."},"resolved_model":{"type":"string","description":"The versioned model that answered when the request named an alias; only on System One and Decisions requests."},"question_count":{"type":"integer","format":"int32","description":"How many questions the request asked; only on System One and Decisions requests."},"min_confidence":{"type":"number","format":"double","description":"The lowest confidence among the answers' choices and scores, 0 to 1; only on System One and Decisions requests."}}},"GuardrailListResponse":{"type":"object","description":"A page of guardrails.","properties":{"data":{"type":"array","description":"The guardrails on this page.","items":{"$ref":"#/components/schemas/GuardrailSummary"}},"page":{"type":"integer","format":"int32","description":"The page number, from 1."},"page_size":{"type":"integer","format":"int32","description":"Guardrails per page."},"total":{"type":"integer","format":"int64","description":"Number of guardrails matching the filters."}}},"GuardrailSummary":{"type":"object","description":"A guardrail as it appears in a list, without its checks.","properties":{"id":{"type":"string","format":"uuid","description":"The guardrail's unique id (UUID)."},"slug":{"type":"string","description":"The guardrail's identifier in URLs, on virtual keys and in the `x-guardrail` header: `gr-` and 16 hex characters. It never changes."},"name":{"type":"string","description":"Display name, unique within the organization."},"description":{"type":"string","description":"Free-text description. Null when none is set."},"organization":{"type":"string","description":"Slug of the organization that owns the guardrail."},"workspace_id":{"type":"string","format":"uuid","description":"Id (UUID) of the workspace the guardrail belongs to."},"enabled":{"type":"boolean","description":"Whether the guardrail runs. A disabled guardrail is skipped wherever it is applied."},"check_count":{"type":"integer","format":"int32","description":"How many checks the guardrail has."},"attached_key_count":{"type":"integer","format":"int32","description":"How many virtual keys apply this guardrail."},"created_at":{"type":"string","format":"date-time","description":"When the guardrail was created (ISO 8601)."},"updated_at":{"type":"string","format":"date-time","description":"When the guardrail was last changed (ISO 8601)."}}},"GuardrailAuditEntry":{"type":"object","description":"One change recorded in a guardrail's audit log.","properties":{"id":{"type":"string","format":"uuid","description":"The entry's unique id (UUID)."},"guardrail_id":{"type":"string","format":"uuid","description":"Id (UUID) of the guardrail."},"action":{"type":"string","description":"What happened: `CREATE` (guardrail created), `UPDATE` (name, description, enabled or checks changed), `ENABLE` or `DISABLE`. Enabling an enabled guardrail, or disabling a disabled one, records nothing."},"actor_id":{"type":"string","description":"Identifier of the caller (user or API key) that made the change, or `unknown` when the caller could not be identified."},"detail":{"type":"object","additionalProperties":{},"description":"Not returned at present: always null."},"created_at":{"type":"string","format":"date-time","description":"When the change was made (ISO 8601)."}}},"GuardrailAuditResponse":{"type":"object","description":"A page of a guardrail's audit log, newest entry first.","properties":{"data":{"type":"array","description":"The entries on this page.","items":{"$ref":"#/components/schemas/GuardrailAuditEntry"}},"page":{"type":"integer","format":"int32","description":"The page number, from 1."},"page_size":{"type":"integer","format":"int32","description":"Entries per page."},"total":{"type":"integer","format":"int64","description":"Number of entries in the whole log."}}},"GuardrailValidatorDescriptor":{"type":"object","description":"A validator a guardrail check can use: what it looks for and how to configure it.","properties":{"id":{"type":"string","description":"The validator's id: the value for a check's `type`."},"name":{"type":"string","description":"Display name."},"description":{"type":"string","description":"What the validator detects or enforces."},"category":{"type":"string","description":"The validator's group: `PII`, `SECURITY`, `CONTENT_SAFETY`, `FORMAT`, `CODE`, `QUALITY` or `CUSTOM`.","enum":["PII","SECURITY","CONTENT_SAFETY","FORMAT","CODE","QUALITY","CUSTOM"]},"kind":{"type":"string","description":"How it runs: `DETERMINISTIC` (rules and patterns, no model call) or `LLM_JUDGE` (asks a model; adds latency and needs a plan with AI guardrails).","enum":["DETERMINISTIC","LLM_JUDGE"]},"supported_targets":{"type":"array","description":"The targets the validator is meant for, from `INPUT`, `OUTPUT` and `BOTH`.","items":{"type":"string","enum":["INPUT","OUTPUT","BOTH"]}},"supported_actions":{"type":"array","description":"The actions the validator is meant for, from `BLOCK`, `REDACT` and `MONITOR`.","items":{"type":"string","enum":["BLOCK","REDACT","MONITOR"]}},"config_schema":{"type":"object","additionalProperties":{},"description":"A JSON Schema object describing the check's `config`. Null when the validator takes no settings."},"default_config":{"type":"object","additionalProperties":{},"description":"A sensible starting `config` for a new check. Null when there is none."}},"required":["category","id","kind","name","supported_actions","supported_targets"]},"GuardrailValidatorListResponse":{"type":"object","description":"The validators a guardrail check can use.","properties":{"data":{"type":"array","description":"Every validator, grouped by category and sorted by name.","items":{"$ref":"#/components/schemas/GuardrailValidatorDescriptor"}}},"required":["data"]},"FileListResponse":{"type":"object","description":"One page of the files uploaded with a virtual key.","properties":{"total":{"type":"integer","format":"int32","description":"How many files match, across all pages."},"page":{"type":"integer","format":"int32","description":"This page's number, from 1."},"page_size":{"type":"integer","format":"int32","description":"Files per page (at most 100)."},"data":{"type":"array","description":"The files on this page.","items":{"$ref":"#/components/schemas/VectorAxisFile"}}}},"RoutingConfigListResponse":{"type":"object","description":"One page of routing configs.","properties":{"data":{"type":"array","description":"The configs on this page.","items":{"$ref":"#/components/schemas/RoutingConfigSummary"}},"page":{"type":"integer","format":"int32","description":"This page's number, starting at 1."},"page_size":{"type":"integer","format":"int32","description":"The page size used (at most 100)."},"total":{"type":"integer","format":"int64","description":"How many configs match, across every page."}}},"RoutingConfigSummary":{"type":"object","description":"A routing config in a list, without its targets.","properties":{"id":{"type":"string","format":"uuid","description":"The config's id (UUID)."},"slug":{"type":"string","description":"The config's slug, for the `x-config` header."},"name":{"type":"string","description":"The config's name."},"description":{"type":"string","description":"A free-text description. Absent when none was set."},"organization":{"type":"string","description":"The slug of the organization the config belongs to."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace the config belongs to (UUID)."},"strategy_mode":{"type":"string","description":"The top-level strategy: `SINGLE`, `LOADBALANCE`, `FALLBACK` or `CONDITIONAL`.","enum":["SINGLE","LOADBALANCE","FALLBACK","CONDITIONAL"]},"target_count":{"type":"integer","format":"int32","description":"How many targets the config has, nested targets included."},"created_at":{"type":"string","format":"date-time","description":"When the config was created (ISO 8601 date-time)."},"updated_at":{"type":"string","format":"date-time","description":"When the config last changed (ISO 8601 date-time)."}}},"RoutingConfigAuditEntry":{"type":"object","description":"One change to a routing config: who made it, when, and what it was.","properties":{"id":{"type":"string","format":"uuid","description":"The entry's id (UUID)."},"config_id":{"type":"string","format":"uuid","description":"The id of the config the entry is about (UUID)."},"action":{"type":"string","description":"What happened: `CREATE` or `UPDATE`."},"actor_id":{"type":"string","description":"Who did it: an identifier of the user, or of the API key, that made the request."},"detail":{"type":"object","additionalProperties":{},"description":"Details of the change: the config's `slug`, and on `CREATE` its `name`."},"created_at":{"type":"string","format":"date-time","description":"When it happened (ISO 8601 date-time)."}}},"RoutingConfigAuditResponse":{"type":"object","description":"One page of a routing config's audit log, newest first.","properties":{"data":{"type":"array","description":"The entries on this page, newest first.","items":{"$ref":"#/components/schemas/RoutingConfigAuditEntry"}},"page":{"type":"integer","format":"int32","description":"This page's number, starting at 1."},"page_size":{"type":"integer","format":"int32","description":"The page size used (at most 200)."},"total":{"type":"integer","format":"int64","description":"How many entries the log has, across every page."}}},"Plan":{"type":"object","description":"A plan: its price and the limits and features it includes. A null limit means no limit.","properties":{"id":{"type":"string","format":"uuid","description":"The plan's id (UUID)."},"name":{"type":"string","description":"The plan's name, e.g. `free`, `pro` or `enterprise`."},"monthly_price_usd":{"type":"number","format":"double","description":"The plan's monthly price in USD, before any regional pricing; null when the plan has no list price."},"currency":{"type":"string","description":"The currency of `monthly_price` (ISO 4217, e.g. `USD`); null when the plan has no price."},"monthly_price":{"type":"number","format":"double","description":"The monthly price in the caller's pricing region, in `currency`."},"max_workspaces":{"type":"integer","format":"int32","description":"The most workspaces an organization can have. Null means no limit."},"max_virtual_keys_per_workspace":{"type":"integer","format":"int32","description":"The most virtual keys each workspace can have. Null means no limit."},"max_consumer_keys_per_workspace":{"type":"integer","format":"int32","description":"Not used; always null."},"max_rpm_per_workspace":{"type":"integer","format":"int32","description":"The most requests per minute each workspace can send through the gateway; more are refused with 429. Null means no limit."},"max_monthly_budget_usd":{"type":"number","format":"double","description":"The plan's stated monthly spend ceiling, in USD. For information: requests are not refused when it is reached. Null means no limit."},"monthly_included_credits_usd":{"type":"number","format":"double","description":"Credits the plan grants each month, in USD. No longer granted: usage on platform (PLATFORM) keys is paid from purchased credits."},"max_logs_per_month":{"type":"integer","format":"int32","description":"The most request logs stored per month; requests over it are still served but not logged. Null means no limit."},"log_retention_days":{"type":"integer","format":"int32","description":"How many days request logs are kept before they are deleted. Null means no limit."},"max_prompt_templates_per_workspace":{"type":"integer","format":"int32","description":"The most prompts each workspace can have. Null means no limit."},"max_guardrails_per_workspace":{"type":"integer","format":"int32","description":"The most guardrails each workspace can have. Null means no limit."},"max_api_keys_per_org":{"type":"integer","format":"int32","description":"The most platform API keys (`va_...`) an organization can have. Null means no limit."},"semantic_caching_enabled":{"type":"boolean","description":"Whether the plan includes the semantic cache (`x-cache-mode: semantic`)."},"ai_guardrails_enabled":{"type":"boolean","description":"Whether the plan includes the AI guardrail checks (toxic language, jailbreak, prompt injection, ...)."},"mcp_gateway_enabled":{"type":"boolean","description":"Whether the plan includes the MCP Gateway."},"tool_inventory_enabled":{"type":"boolean","description":"Whether the plan includes the tool inventory."},"trust_pack_enabled":{"type":"boolean","description":"Whether the plan includes the AI Trust Pack reports."},"trust_controls_enabled":{"type":"boolean","description":"Whether the plan includes the AI Trust Pack controls: the approved sub-processor policy, change alerts and evidence bundles."}}},"Subscription":{"type":"object","description":"The organization's subscription to a plan.","properties":{"id":{"type":"string","format":"uuid","description":"The subscription's id (UUID)."},"organization":{"type":"string","description":"The slug of the organization."},"plan":{"$ref":"#/components/schemas/Plan"},"status":{"type":"string","description":"The subscription's status: `active`, `trialing`, `past_due` (a payment failed) or `  canceled`.","enum":["active","past_due","canceled","trialing"]},"current_period_end":{"type":"string","format":"date-time","description":"When the current billing period ends (ISO 8601 date-time); absent on the free plan."},"payment_gateway":{"type":"string","description":"The payment provider that bills the subscription, e.g. `STRIPE`."},"gateway_subscription_id":{"type":"string","description":"The subscription's id at the payment provider; absent on the free plan."},"created_at":{"type":"string","format":"date-time","description":"When the subscription was created (ISO 8601 date-time)."},"updated_at":{"type":"string","format":"date-time","description":"When the subscription last changed (ISO 8601 date-time)."}}},"PricingMetadataResponse":{"type":"object","description":"Every plan with its limits and features, priced for the caller's pricing region.","properties":{"pricing_region":{"type":"string","description":"The pricing region the prices are for, e.g. `US`."},"currency":{"type":"string","description":"The currency of the regional prices (ISO 4217)."},"plans":{"type":"array","description":"The plans, cheapest first.","items":{"$ref":"#/components/schemas/Plan"}}},"required":["plans"]},"WorkspaceEntitlements":{"type":"object","description":"The limits and features the organization has now: its plan's values with any adjustments made for the organization applied. A null limit means no limit; limits named per workspace apply to each workspace.","properties":{"workspace_id":{"type":"string","format":"uuid","description":"The workspace id (UUID) the request named, returned as sent; it does not change the values."},"plan_name":{"type":"string","description":"The name of the organization's plan."},"max_virtual_keys":{"type":"integer","format":"int32","description":"The most virtual keys each workspace can have. Null means no limit."},"max_consumer_keys":{"type":"integer","format":"int32","description":"Not used; always null."},"max_rpm":{"type":"integer","format":"int32","description":"The most requests per minute each workspace can send through the gateway; more are refused with 429. Null means no limit."},"max_monthly_budget_usd":{"type":"number","format":"double","description":"The stated monthly spend ceiling, in USD. For information: requests are not refused when it is reached. Null means no limit."},"max_logs_per_month":{"type":"integer","format":"int32","description":"The most request logs stored per month; requests over it are still served but not logged. Null means no limit."},"log_retention_days":{"type":"integer","format":"int32","description":"How many days request logs are kept before they are deleted. Null means they are kept until the organization is closed."},"max_prompt_templates":{"type":"integer","format":"int32","description":"The most prompts each workspace can have. Null means no limit."},"max_guardrails":{"type":"integer","format":"int32","description":"The most guardrails each workspace can have. Null means no limit."},"max_api_keys":{"type":"integer","format":"int32","description":"The most platform API keys (`va_...`) the organization can have. Null means no limit."},"semantic_caching_enabled":{"type":"boolean","description":"Whether the organization can use the semantic cache (`x-cache-mode: semantic`)."},"ai_guardrails_enabled":{"type":"boolean","description":"Whether the organization can use the AI guardrail checks; saving a guardrail with one fails with 402 otherwise."},"mcp_gateway_enabled":{"type":"boolean","description":"Whether the organization can use the MCP Gateway."},"tool_inventory_enabled":{"type":"boolean","description":"Whether the organization can read the tool inventory."},"trust_pack_enabled":{"type":"boolean","description":"Whether the organization can read the AI Trust Pack reports."},"trust_controls_enabled":{"type":"boolean","description":"Whether the organization can use the AI Trust Pack controls."},"subscription_status":{"type":"string","description":"The subscription's status: `active`, `trialing`, `past_due` or `canceled`.","enum":["active","past_due","canceled","trialing"]}}},"CreditTransaction":{"type":"object","description":"One movement of credit on the organization's account.","properties":{"id":{"type":"string","format":"uuid","description":"The transaction's id (UUID)."},"organization":{"type":"string","description":"The slug of the organization."},"type":{"type":"string","description":"What moved the credit: `PURCHASE`, `PLAN_ALLOCATION`, `CONSUMPTION` (use by a PLATFORM key), `REFUND`, `AUTO_RECHARGE` or `WITHDRAWAL`.","enum":["PURCHASE","PLAN_ALLOCATION","CONSUMPTION","REFUND","AUTO_RECHARGE","WITHDRAWAL"]},"amount_usd":{"type":"number","format":"double","description":"The change to the balance, in USD: positive for credit added, negative for credit used or withdrawn."},"balance_after":{"type":"number","format":"double","description":"The balance after this transaction, in USD."},"description":{"type":"string","description":"A short description of the transaction."},"virtual_key_slug":{"type":"string","description":"For `CONSUMPTION`, the PLATFORM key that used the credit; absent otherwise."},"created_at":{"type":"string","format":"date-time","description":"When the transaction happened (ISO 8601 date-time)."}}},"CreditTransactionListResponse":{"type":"object","description":"One page of credit transactions, newest first.","properties":{"transactions":{"type":"array","description":"The transactions on this page.","items":{"$ref":"#/components/schemas/CreditTransaction"}},"total":{"type":"integer","format":"int32","description":"The number of transactions across all pages."},"page":{"type":"integer","format":"int32","description":"This page's number, starting at 0."},"page_size":{"type":"integer","format":"int32","description":"The most transactions per page."}}},"BatchListResponse":{"type":"object","description":"One page of batches, as the provider lists them, with cursor pagination.","properties":{"object":{"type":"string","description":"Always `list`."},"data":{"type":"array","description":"The batches on this page.","items":{"$ref":"#/components/schemas/BatchObject"}},"first_id":{"type":"string","description":"The id of the first batch on this page."},"last_id":{"type":"string","description":"The id of the last batch on this page: pass it as `after` to get the next page."},"has_more":{"type":"boolean","description":"`true` when there are more batches after this page."}}},"PlatformApiKeyListResponse":{"type":"object","description":"Platform API keys.","properties":{"keys":{"type":"array","description":"The keys, revoked ones included; the list is not paginated.","items":{"$ref":"#/components/schemas/PlatformApiKey"}},"total":{"type":"integer","format":"int32","description":"The number of entries in `keys`."}}},"TimeSeriesPoint":{"type":"object","description":"One time bucket of a time series.","properties":{"timestamp":{"type":"string","format":"date-time","description":"The start of the bucket (ISO 8601 date-time)."},"value":{"type":"number","format":"double","description":"The metric's value in the bucket; 0 for a bucket with no requests."}}},"TimeSeriesResponse":{"type":"object","description":"One metric over time, one point per bucket.","properties":{"metric":{"type":"string","description":"The metric charted, as requested."},"granularity":{"type":"string","description":"The bucket size: `hour`, `day` or `week`."},"points":{"type":"array","description":"The metric per bucket, oldest first, over every request matching the filters. Empty buckets are included as 0.","items":{"$ref":"#/components/schemas/TimeSeriesPoint"}},"series":{"type":"array","description":"With `split_by=model`: one series per model for the models with the most requests, then one `other` series for every other model. Absent otherwise.","items":{"$ref":"#/components/schemas/TimeSeriesSeries"}}}},"TimeSeriesSeries":{"type":"object","description":"One model's share of a time series split by model, or every other model together.","properties":{"name":{"type":"string","description":"The model id; null for the `other` series."},"other":{"type":"boolean","description":"True for the series that sums every model without a series of its own."},"points":{"type":"array","description":"The metric per bucket for this model, on the same buckets as the total.","items":{"$ref":"#/components/schemas/TimeSeriesPoint"}}}},"AnalyticsSummary":{"type":"object","description":"Totals over every request matching the filters.","properties":{"total_requests":{"type":"integer","format":"int64","description":"How many requests matched."},"total_cost_usd":{"type":"number","format":"double","description":"What they cost, in USD (cache hits cost 0)."},"total_cost_saved_usd":{"type":"number","format":"double","description":"What cache hits saved, in USD: the sum of `cost_saved_usd`."},"total_tokens":{"type":"integer","format":"int64","description":"Input plus output tokens."},"prompt_tokens":{"type":"integer","format":"int64","description":"Input tokens."},"completion_tokens":{"type":"integer","format":"int64","description":"Output tokens."},"avg_duration_ms":{"type":"number","format":"double","description":"The average request duration, in milliseconds; 0 when nothing matched."},"p50_duration_ms":{"type":"number","format":"double","description":"The median request duration, in milliseconds; null when nothing matched."},"p95_duration_ms":{"type":"number","format":"double","description":"The 95th percentile request duration, in milliseconds; null when nothing matched."},"p99_duration_ms":{"type":"number","format":"double","description":"The 99th percentile request duration, in milliseconds; null when nothing matched."},"error_rate":{"type":"number","format":"double","description":"The share of requests that ended with a status of 400 or above, 0 to 1; 0 when nothing matched."},"cache_hit_rate":{"type":"number","format":"double","description":"The share of requests answered from the cache (`HIT` or `SEMANTIC_HIT`), 0 to 1; 0 when nothing matched."}}},"LatencyDataPoint":{"type":"object","description":"Latency for one time bucket, or for the whole window. The top-level figures are the total latency, from the request's arrival at the gateway until the response was complete; the nested figures split it. Percentiles are within about 3% of the exact value (exact below 18 ms); the average and maximum are exact.","properties":{"timestamp":{"type":"string","format":"date-time","description":"the start of the bucket (ISO 8601 date-time); null on the summary"},"requests":{"type":"integer","format":"int64","description":"how many matching requests the bucket holds; when 0, the figures are null"},"avg":{"type":"integer","format":"int64","description":"the average total latency, in milliseconds"},"p50":{"type":"integer","format":"int64","description":"the median total latency, in milliseconds"},"p90":{"type":"integer","format":"int64","description":"the 90th percentile total latency, in milliseconds"},"p95":{"type":"integer","format":"int64","description":"the 95th percentile total latency, in milliseconds"},"p99":{"type":"integer","format":"int64","description":"the 99th percentile total latency, in milliseconds"},"max":{"type":"integer","format":"int64","description":"the slowest total latency, in milliseconds"},"provider":{"$ref":"#/components/schemas/LatencyStats","description":"time spent waiting on the provider, every attempt included; only requests that called a provider (cache hits are left out)"},"gateway_overhead":{"$ref":"#/components/schemas/LatencyStats"},"first_token":{"$ref":"#/components/schemas/LatencyStats"},"provider_first_token":{"$ref":"#/components/schemas/LatencyStats"}}},"LatencyGraphResponse":{"type":"object","description":"The latency graph: a summary of the whole window and one data point per time bucket, empty buckets included. Requests logged before the latency breakdown was recorded count with their recorded duration as total latency.","properties":{"object":{"type":"string","description":"always `analytics-graph`"},"organization":{"type":"string","description":"the organization's slug"},"workspace_ids":{"type":"array","description":"The workspaces covered (UUIDs); null when every workspace of the organization is covered.","items":{"type":"string","format":"uuid"}},"start_time":{"type":"string","format":"date-time","description":"The start of the window, inclusive (ISO 8601 date-time)."},"end_time":{"type":"string","format":"date-time","description":"The end of the window, exclusive (ISO 8601 date-time)."},"granularity":{"type":"string","description":"the bucket size used: `minute`, `hour`, `day` or `week`"},"tz":{"type":"string","description":"the IANA time zone the buckets are aligned to"},"summary":{"$ref":"#/components/schemas/LatencyDataPoint","description":"the figures over the whole window"},"data_points":{"type":"array","description":"One entry per time bucket, oldest first, empty buckets included.","items":{"$ref":"#/components/schemas/LatencyDataPoint"}},"regions":{"type":"array","description":"the regions whose logs were read","items":{"type":"string"}},"unavailable_regions":{"type":"array","description":"Regions that hold the organization's logs but did not answer, so the figures leave them out.","items":{"type":"string"}}}},"LatencyStats":{"type":"object","description":"Latency figures for a set of requests, in milliseconds. Percentiles are within about 3% of the exact value (exact below 18 ms); the average and maximum are exact.","properties":{"requests":{"type":"integer","format":"int64","description":"how many requests the figures cover; when 0, the other figures are null"},"avg":{"type":"integer","format":"int64","description":"the average, in milliseconds"},"p50":{"type":"integer","format":"int64","description":"the median, in milliseconds"},"p90":{"type":"integer","format":"int64","description":"the 90th percentile, in milliseconds"},"p95":{"type":"integer","format":"int64","description":"the 95th percentile, in milliseconds"},"p99":{"type":"integer","format":"int64","description":"the 99th percentile, in milliseconds"},"max":{"type":"integer","format":"int64","description":"the slowest, in milliseconds"}}},"BreakdownEntry":{"type":"object","description":"One group of a usage breakdown.","properties":{"dimension_value":{"type":"string","description":"The group's value of the dimension, e.g. a provider or a model id."},"request_count":{"type":"integer","format":"int64","description":"How many requests are in the group."},"error_count":{"type":"integer","format":"int64","description":"How many of them ended with a status of 400 or above."},"total_cost_usd":{"type":"number","format":"double","description":"What they cost, in USD (cache hits cost 0)."},"total_cost_saved_usd":{"type":"number","format":"double","description":"What cache hits in the group saved, in USD."},"total_tokens":{"type":"integer","format":"int64","description":"Input plus output tokens."},"avg_duration_ms":{"type":"number","format":"double","description":"The average request duration, in milliseconds."}}},"BreakdownResponse":{"type":"object","description":"Usage grouped by one dimension, highest cost first.","properties":{"dimension":{"type":"string","description":"The dimension the requests are grouped by, as requested."},"entries":{"type":"array","description":"The groups, highest `total_cost_usd` first. Requests with no value for `organization`, `  user_id`, `virtual_key_slug` or `cache_status` are left out of those breakdowns.","items":{"$ref":"#/components/schemas/BreakdownEntry"}}}},"DeleteFileResponse":{"type":"object","description":"Confirms that a file was deleted.","properties":{"id":{"type":"string","description":"The VectorAxis id (`vxf-...`) of the deleted file."},"deleted":{"type":"boolean","description":"`true`: the file was deleted at the provider and in VectorAxis."}}}},"securitySchemes":{"platformKey":{"type":"http","description":"A platform API key (`va_...`), created under Settings > API keys. Scoped to an organization or one workspace, with an admin or member role. Used by the management API.","scheme":"bearer","bearerFormat":"va_"},"virtualKey":{"type":"http","description":"A virtual key's API key (`vk-....<secret>`), as `Authorization: Bearer`. What the OpenAI SDK sends from its `api_key`. Used by the inference endpoints.","scheme":"bearer","bearerFormat":"<slug>.<secret>"},"virtualKeyHeader":{"type":"apiKey","description":"A virtual key's API key in the `x-virtual-key` header, for clients that keep `Authorization` for something else.","name":"x-virtual-key","in":"header"},"providerKey":{"type":"apiKey","description":"Direct credentials: the provider's own API key in `x-api-key`, with the provider named in `x-provider` (for example `openai`). On `/v1/messages` a virtual key is accepted in `x-api-key` too, which is what the Claude SDK sends.","name":"x-api-key","in":"header"}}},"x-tagGroups":[{"tags":["Chat completions","Claude Messages","Claude Message Batches","Embeddings","Responses","Audio","Images","Files","Batches","Decisions","System One"],"name":"Inference"},{"tags":["Virtual keys","Routing configs","Prompts","Guardrails","Providers","Pricing"],"name":"Gateway"},{"tags":["Logs and analytics","Tool inventory"],"name":"Observability"},{"tags":["MCP integrations","MCP servers","MCP keys","MCP runs","MCP tool search"],"name":"MCP Gateway"},{"tags":["Trust Pack","Public trust pages"],"name":"AI Trust Pack"},{"tags":["Organization","Workspaces","API keys","Billing"],"name":"Administration"}]}