> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbitrage.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Bring your own key (BYOK)

> Frontier models run on your own provider key — your rate, your contract, and $0 added by Orbitrage.

Orbitrage splits the catalog in two:

<CardGroup cols={2}>
  <Card title="Open-weight — we serve it" icon="server">
    Qwen, DeepSeek, GLM, Kimi, MiniMax, Mistral, Nemotron, Gemma, `gpt-oss-*` and
    the rest run on **our** infrastructure. Billed to your Orbitrage credits at the
    upstream price plus a 2.5% infra fee. Nothing to configure.
  </Card>

  <Card title="Frontier — your key" icon="key">
    Every `claude-*`, `gpt-*` (excluding `gpt-oss-*`), `gemini-*` and `grok-*` chat
    model is **BYOK-only**. The request goes to the vendor with your key, your
    provider bills you at your rate, and Orbitrage charges **\$0**.
  </Card>
</CardGroup>

You still get the full platform on both paths — routing, tracing, cost analytics,
guardrails, the Tools Gateway and Outage Shield.

<Note>
  This applies to **chat** models only. Image generation (`gpt-image-2`) and audio
  (Deepgram `nova-*` / `aura-*`) remain managed and pooled — no key needed.
</Note>

## Why we do it this way

No markup on frontier inference, no reseller margin buried in your bill, and no
lock-in: you keep your own OpenAI/Anthropic/Google/xAI contract, your negotiated
rates, your rate limits and your data-processing terms. Orbitrage earns on the
open-weight inference it actually runs for you.

## Setting up a key

<Steps>
  <Step title="Save a provider key">
    On the [Models page](https://app.orbitrage.ai/models), add a key for OpenAI,
    Anthropic, Google or xAI. Optionally set a custom base URL (e.g. an Azure
    endpoint).
  </Step>

  <Step title="Orbitrage encrypts it">
    Keys are encrypted at rest with AES-256-GCM. The plaintext is never logged and
    never returned to the browser again.
  </Step>

  <Step title="Enable it">
    A saved key must also be **enabled**. A disabled key means those models are off
    entirely — see [Disabling a key](#disabling-a-key).
  </Step>

  <Step title="Call the model normally">
    Nothing changes in your code. The gateway decrypts your key in-memory, forwards
    the request to the real provider endpoint, and records the call with
    `cost_usd = 0`.
  </Step>
</Steps>

## Your own cloud: Azure AI Foundry & Amazon Bedrock

Beyond the four frontier vendors, you can connect the clouds **you** already run
models on. These are addressed explicitly — prefix the model id with the cloud
and everything after the prefix is sent to your account verbatim:

<CardGroup cols={2}>
  <Card title="Azure AI Foundry" icon="microsoft">
    Save your Azure key **and resource endpoint** (any of
    `*.openai.azure.com`, `*.cognitiveservices.azure.com`,
    `*.services.ai.azure.com`), then call any deployment as
    `azure/<deployment-name>` — e.g. `azure/gpt-4o` or `azure/my-fine-tune`.
  </Card>

  <Card title="Amazon Bedrock" icon="aws">
    Save your Bedrock API key and pick a region, then call any model your
    account serves as `bedrock/<model-id>` — e.g.
    `bedrock/anthropic.claude-sonnet-4-5` or an inference-profile id/ARN.
  </Card>
</CardGroup>

```python theme={null}
client.chat.completions.create(
    model="azure/my-gpt5-deployment",   # or bedrock/amazon.nova-pro-v1:0
    messages=[{"role": "user", "content": "hello"}],
)
```

Same deal as every BYOK call: full routing, tracing and analytics, and **\$0**
billed by Orbitrage — Microsoft or AWS bill you directly. An Azure key saved
without its endpoint returns `403` with reason `endpoint-required`.

## Calling a frontier model without a key

There is no silent pooled fallback. A frontier model with no enabled key for its
vendor returns **HTTP 403**:

```json theme={null}
// 403 — no enabled Anthropic key on this organization
{
  "error": {
    "message": "claude-sonnet-4-6 is a bring-your-own-key model. Add and enable an Anthropic key on the Models page to use it.",
    "type": "permission_error",
    "code": "byok_key_required",
    "requested_model": "claude-sonnet-4-6",
    "provider": "anthropic"
  }
}
```

<Steps>
  <Step title="Add the key">
    Open the [Models page](https://app.orbitrage.ai/models) and save a key for the
    provider named in `error.provider`.
  </Step>

  <Step title="Enable it">
    Toggle the key on. Saved-but-disabled still returns `byok_key_required`.
  </Step>

  <Step title="Retry">
    Retry the request unchanged — key resolution is cached briefly, so allow a few
    seconds.
  </Step>
</Steps>

<Tip>
  Don't want to manage keys at all? Route to `model: "auto"`, or pin an open-weight
  model. Auto routing only ever selects models your organization can actually
  reach, so it never produces a `byok_key_required`.
</Tip>

## Billing on a BYOK turn

| What ran                                                                    | Who bills you                                              |
| --------------------------------------------------------------------------- | ---------------------------------------------------------- |
| The frontier model's tokens                                                 | Your provider, directly. Orbitrage records `cost_usd = 0`. |
| [Managed Tools Gateway](/concepts/tools-gateway) calls made during the turn | **Orbitrage** — those tools run on *our* pooled tool keys. |

So a BYOK turn that called two managed tools costs exactly the price of those two
tool calls, and nothing for the LLM tokens.

<Note>
  Your Orbitrage credit balance is still checked before the call, because a turn
  can incur tool cost. A BYOK-only turn with no managed tools debits nothing.
</Note>

## Disabling a key

Toggling a key off **turns those models off** — it does not fall back to pooled
inference. Requests for that vendor's frontier models return `403
byok_key_required` until you re-enable it. This is deliberate: a disabled key
should never quietly become a bill.

## Seeing the split

Every call surfaces which path it took — in the dashboard (`byok=true`) and in the
response headers:

| Header                    | Value                                                   |
| ------------------------- | ------------------------------------------------------- |
| `X-Orbitrage-BYOK`        | The provider name used (e.g. `anthropic`), or `pooled`. |
| `X-Orbitrage-BYOK-Reason` | Why BYOK did or didn't apply (see below).               |

Common `X-Orbitrage-BYOK-Reason` values:

| Reason                       | Meaning                                                                  |
| ---------------------------- | ------------------------------------------------------------------------ |
| `applied`                    | Your key was found, enabled, and used.                                   |
| `applied-with-model-rewrite` | Used, with the upstream model id adjusted.                               |
| `no-key-for-provider`        | No key saved for this vendor. Frontier models → `403`.                   |
| `key-disabled`               | You saved the key but toggled it off. Frontier models → `403`.           |
| `unmapped-model`             | An open-weight model — served pooled, billed to credits.                 |
| `decrypt-failed`             | The stored key couldn't be decrypted (re-save it).                       |
| `endpoint-required`          | An Azure key with no endpoint saved — re-save it with your resource URL. |

## Security

* Keys are encrypted with AES-256-GCM using a server-only key; plaintext is never
  stored or logged.
* Decryption happens in-memory at the gateway, per request, only for the matching
  provider.
* Provider keys are scoped to your organization and protected by row-level
  security — no other org can read them.
