---
title: "Create a BYOK provider credential"
method: POST
path: "/byok"
tags: ["BYOK"]
---

# Create a BYOK provider credential

`POST /byok`

Create a new bring-your-own-key (BYOK) provider credential. The raw key is encrypted at rest and never returned in API responses. When `workspace_id` is omitted, the credential is created in the default workspace; if that default has been deleted, the request returns a 400 and you must pass `workspace_id` explicitly. Treat the raw key as write-only; it is never returned after creation. Use `allowed_api_key_hashes` to restrict the credential to specific OpenRouter API keys. [Management key](/docs/guides/overview/auth/management-api-keys) required.

## Request body

- CreateBYOKKeyRequest
  - `allowed_api_key_hashes` string[], nullable — Optional allowlist of OpenRouter API key hashes (`api_keys.hash`) that may use this credential. `null` means no restriction. Must contain at least one hash if provided. Hashes that do not belong to your account return a 400.
  - `allowed_models` string[], nullable — Optional allowlist of model slugs this credential may be used for. `null` means no restriction.
  - `allowed_user_ids` string[], nullable — Optional allowlist of user IDs that may use this credential. `null` means no restriction.
  - `declared_zdr` boolean, nullable — Your declaration of whether the upstream provider account behind this credential has zero data retention (ZDR). `null` inherits OpenRouter's data policy for the provider's endpoint; `true` declares the account ZDR so requests that require ZDR may route to this credential even when the shared endpoint retains data; `false` declares it non-ZDR so such requests never route to it. Self-declared and not verified by OpenRouter. Defaults to `null`.
  - `disabled` boolean — Whether this credential should be created in a disabled state.
  - `is_byok_only` boolean — Whether OpenRouter's shared endpoints on this provider are removed for every model, including models outside `allowed_models` and after all of your keys for the provider fail. The provider is skipped instead of spending OpenRouter credits. Only valid on non-fallback credentials. Defaults to `false`.
  - `is_fallback` boolean — Whether this credential is treated as a fallback — used only after non-fallback keys for the same provider have been tried. Cannot be combined with `is_byok_only`.
  - `is_required` boolean — Whether OpenRouter's shared endpoints on this provider are removed for the models this credential applies to (its `allowed_models`, or every model when `null`). Requests for those models run only on your keys; models outside the allowlist may still fall back to shared capacity on this provider. Defaults to `false`.
  - `key` string, required — The raw provider API key or credential. This value is encrypted at rest and never returned in API responses.
  - `name` string, nullable — Optional human-readable name for the credential.
  - `provider` 'ai21' | 'aion-labs' | 'akashml' | 'alibaba' | 'amazon-bedrock' | 'amazon-bedrock/claude-on-aws' | 'amazon-nova' | 'ambient' | 'anthropic' | 'anthropic/2' | 'arcee-ai' | 'assemblyai' | 'atlas-cloud' | 'avian' | 'azure' | 'baidu' | 'baseten' | 'black-forest-labs' | 'byteplus' | 'cerebras' | 'chutes' | 'cirrascale' | 'clarifai' | 'claude-on-aws' | 'cloudflare' | 'cohere' | 'coreweave' | 'cosine' | 'crusoe' | 'darkbloom' | 'databricks' | 'decart' | 'deepgram' | 'deepinfra' | 'deepseek' | 'dekallm' | 'digitalocean' | 'featherless' | 'fireworks' | 'fish-audio' | 'friendli' | 'gmicloud' | 'google-ai-studio' | 'google-vertex' | 'groq' | 'heygen' | 'inception' | 'inceptron' | 'inferact-vllm' | 'inference-net' | 'infermatic' | 'inflection' | 'io-net' | 'ionstream' | 'krea' | 'liquid' | 'makora' | 'mancer' | 'mara' | 'meta' | 'minimax' | 'mistral' | 'modal' | 'modelrun' | 'modular' | 'moonshotai' | 'morph' | 'near-ai' | 'nebius' | 'nex-agi' | 'nextbit' | 'novita' | 'nvidia' | 'ollama' | 'open-inference' | 'openai' | 'parasail' | 'perceptron' | 'perplexity' | 'phala' | 'poolside' | 'primeintellect' | 'quiver' | 'recraft' | 'reka' | 'relace' | 'respan' | 'runway' | 'sail-research' | 'sakana' | 'sakana-ai' | 'sambanova' | 'scaledown' | 'seed' | 'siliconflow' | 'sourceful' | 'stepfun' | 'streamlake' | 'switchpoint' | 'tencent' | 'tenstorrent' | 'thinkingmachines' | 'together' | 'typesafe' | 'unbiased' | 'upstage' | 'venice' | 'voyageai' | 'wafer' | 'wandb' | 'wandb-legacy' | 'xai' | 'xiaomi' | 'z-ai', required — The upstream provider this credential authenticates against, as a lowercase slug (e.g. `openai`, `anthropic`, `amazon-bedrock`).
  - `workspace_id` string, uuid — Optional workspace ID to scope the credential to. When omitted, the credential is created in the account's default workspace; if that default has been deleted, the request returns a 400 and you must pass `workspace_id` explicitly.

## Response `201`

BYOK credential created successfully

- CreateBYOKKeyResponse
  - `data` object, required — The created BYOK credential.
    - `allowed_api_key_hashes` string[], nullable, required — Optional allowlist of OpenRouter API key hashes (`api_keys.hash`) that may use this credential. `null` means no restriction.
    - `allowed_models` string[], nullable, required — Optional allowlist of model slugs this credential may be used for. `null` means no restriction.
    - `allowed_user_ids` string[], nullable, required — Optional allowlist of user IDs that may use this credential. `null` means no restriction.
    - `created_at` string, required — ISO timestamp of when the credential was created.
    - `declared_zdr` boolean, nullable, required — Your declaration of whether the upstream provider account behind this credential has zero data retention (ZDR). `null` inherits OpenRouter's data policy for the provider's endpoint; `true` declares the account ZDR so requests that require ZDR may route to this credential even when the shared endpoint retains data; `false` declares it non-ZDR so such requests never route to it. Self-declared and not verified by OpenRouter.
    - `disabled` boolean, required — Whether this credential is currently disabled.
    - `id` string, uuid, required — Stable public identifier for this BYOK credential.
    - `is_byok_only` boolean, required — Whether OpenRouter's shared endpoints on this provider are removed for every model, including models outside `allowed_models` and after all of your keys for the provider fail. The provider is skipped instead of spending OpenRouter credits. Only valid on non-fallback credentials.
    - `is_fallback` boolean, required — Whether this credential is treated as a fallback — used only after non-fallback keys for the same provider have been tried. Cannot be combined with `is_byok_only`.
    - `is_required` boolean, required — Whether OpenRouter's shared endpoints on this provider are removed for the models this credential applies to (its `allowed_models`, or every model when `null`). Requests for those models run only on your keys; models outside the allowlist may still fall back to shared capacity on this provider.
    - `label` string, required — Short masked snippet of the key (e.g. the first/last few characters) used to identify it in the UI.
    - `name` string, nullable — Optional human-readable name for the credential.
    - `provider` 'ai21' | 'aion-labs' | 'akashml' | 'alibaba' | 'amazon-bedrock' | 'amazon-bedrock/claude-on-aws' | 'amazon-nova' | 'ambient' | 'anthropic' | 'anthropic/2' | 'arcee-ai' | 'assemblyai' | 'atlas-cloud' | 'avian' | 'azure' | 'baidu' | 'baseten' | 'black-forest-labs' | 'byteplus' | 'cerebras' | 'chutes' | 'cirrascale' | 'clarifai' | 'claude-on-aws' | 'cloudflare' | 'cohere' | 'coreweave' | 'cosine' | 'crusoe' | 'darkbloom' | 'databricks' | 'decart' | 'deepgram' | 'deepinfra' | 'deepseek' | 'dekallm' | 'digitalocean' | 'featherless' | 'fireworks' | 'fish-audio' | 'friendli' | 'gmicloud' | 'google-ai-studio' | 'google-vertex' | 'groq' | 'heygen' | 'inception' | 'inceptron' | 'inferact-vllm' | 'inference-net' | 'infermatic' | 'inflection' | 'io-net' | 'ionstream' | 'krea' | 'liquid' | 'makora' | 'mancer' | 'mara' | 'meta' | 'minimax' | 'mistral' | 'modal' | 'modelrun' | 'modular' | 'moonshotai' | 'morph' | 'near-ai' | 'nebius' | 'nex-agi' | 'nextbit' | 'novita' | 'nvidia' | 'ollama' | 'open-inference' | 'openai' | 'parasail' | 'perceptron' | 'perplexity' | 'phala' | 'poolside' | 'primeintellect' | 'quiver' | 'recraft' | 'reka' | 'relace' | 'respan' | 'runway' | 'sail-research' | 'sakana' | 'sakana-ai' | 'sambanova' | 'scaledown' | 'seed' | 'siliconflow' | 'sourceful' | 'stepfun' | 'streamlake' | 'switchpoint' | 'tencent' | 'tenstorrent' | 'thinkingmachines' | 'together' | 'typesafe' | 'unbiased' | 'upstage' | 'venice' | 'voyageai' | 'wafer' | 'wandb' | 'wandb-legacy' | 'xai' | 'xiaomi' | 'z-ai', required — The upstream provider this credential authenticates against, as a lowercase slug (e.g. `openai`, `anthropic`, `amazon-bedrock`).
    - `sort_order` integer, required — Position within the provider — credentials are tried in ascending sort order.
    - `workspace_id` string, uuid, nullable, required — The workspace this credential is scoped to, or `null` when it is global — usable across every workspace in the account. A `null` value does not mean the default workspace.

## Other responses

- `400` — Bad Request - Invalid request parameters or malformed input
- `401` — Unauthorized - Authentication required or invalid credentials
- `403` — Forbidden - Authentication successful but insufficient permissions
- `500` — Internal Server Error - Unexpected server error

## Changes

- **2026-09-25** `31b1cd25caca` — 1 warning, 1 info
  - added the new `respan` enum value to the `data/allOf[#/components/schemas/BYOKKey]/provider` response property for the response status `201`
  - added the new `respan` enum value to the request property `provider`
- **2026-09-24** `4c8b9dc76c45` — 1 warning, 1 info
  - added the new `scaledown` enum value to the `data/allOf[#/components/schemas/BYOKKey]/provider` response property for the response status `201`
  - added the new `scaledown` enum value to the request property `provider`
- **2026-09-21** `91342dd3fd0f` — 2 info
  - added the new optional request property `declared_zdr`
  - added the required property `data/allOf[#/components/schemas/BYOKKey]/declared_zdr` to the response with the `201` status
- **2026-09-17** `3066544509b5` — 1 warning, 1 info
  - added the new `unbiased` enum value to the `data/allOf[#/components/schemas/BYOKKey]/provider` response property for the response status `201`
  - added the new `unbiased` enum value to the request property `provider`
- **2026-09-17** `2de027b6dfcd` — 1 warning, 1 info
  - added the new `typesafe` enum value to the `data/allOf[#/components/schemas/BYOKKey]/provider` response property for the response status `201`
  - added the new `typesafe` enum value to the request property `provider`

[Full history](https://skmtc.dev/openrouterteam/apis/openrouter-api/changes/byok/post.md)

---

[API](https://skmtc.dev/openrouterteam/apis/openrouter-api.md) · [All operations](https://skmtc.dev/openrouterteam/apis/openrouter-api/llms.txt) · [OpenAPI document](https://skmtc.dev/openrouterteam/apis/openrouter-api/revisions/7c237298ce97?raw)
