# Bring your own provider key

Bring your own key (BYOK) routes inference through your organization's own OpenAI, Anthropic or
Azure API keys, or an AWS Bedrock workload role. You still call the gateway with a RouterPlus
key. RouterPlus stores the provider credential encrypted, and the provider bills you directly.
RouterPlus charges nothing for BYOK inference.

In the console, open [Access > Provider connections](https://demo.routerplus.com/console/byok), or use the
API below.

## Set up in the console

1. Sign in, open [`/console/byok`](https://demo.routerplus.com/console/byok) and select your organization.
2. Click **Add connection**. Name it, choose a provider, enter its credential and add exact
   model IDs.
   - Azure also needs a resource and a deployment mapping.
   - You can select Bedrock only when RouterPlus has approved a role for your organization.
   - You cannot change the provider or model list after you save. Create a new connection
     instead.
3. Click **Save and validate**. If validation fails, the connection stays pending. Rotate its
   credential or retry validation. Do not create a duplicate.
4. Choose the limits of an existing provider account, or enter RPM, TPM, concurrency and
   headroom for a new account. Credentials for the same account should share one pool or
   parent. A connection with no pool cannot serve requests.
5. Create a new RouterPlus key or select an existing one.
   - RouterPlus creates and binds a new BYOK key in one transaction before it returns it.
   - The page warns before it replaces an existing key's connection or key-level policy. An
     organization or workspace policy still applies.
6. Copy the new key once and use the generated request example. The optional
   **Send test request** sends "Reply OK" with at most 8 output tokens. It uses provider quota
   and can cost a small provider charge.

Each connection card can validate, edit shared-account limits, rotate, disable and delete.

- Viewers can read metadata. Owners and admins make changes.
- RouterPlus never returns provider secrets.
- A disabled connection becomes active again only after rotation and a successful validation.
- You cannot restore a deleted connection.

When you issue a key, you can select workspaces and principals from the
[identity API](/docs/identity). The console keeps their limits and restrictions.

## Set up with the API

1. Sign in to the console and create a virtual key. BYOK inference needs no marketplace credit.
2. Send `POST /api/connections` on the **site origin**, with JSON:

   ```json
   {"profile":"openai","models":["your-exact-provider-model-id"],"api_key":"YOUR_PROVIDER_KEY"}
   ```

   | Field | Rule |
   |---|---|
   | `profile` | `openai` or `anthropic`. `azure` needs a deployment mapping: see [Azure and policy setup](/docs/routing-policies). `bedrock` takes `workload_role` instead of `api_key`: see [Bedrock](/docs/bedrock). |
   | `models` | 1 to 100 exact model IDs. No wildcards. |
   | `name` | Optional label. |

   The response is `201` with `connection_id` and `status: "pending"`. It never returns the key.
3. Send `POST /api/connections/{connection_id}/validate` with `{}`. Success returns
   `valid: true` and `status: "active"`. For API-key profiles, validation makes one
   authenticated model-list GET, with a 10-second timeout and no generated tokens. It does not
   check access to every declared model or reserve capacity.
4. Send `POST /api/connections/{connection_id}/bind` with `{"key_id":"YOUR_VIRTUAL_KEY_UUID"}`.
   This binds an enabled virtual key in the same org to an active connection. A key that served
   marketplace traffic takes up to 5 seconds to switch. You can use a new virtual key instead.
5. [Declare a quota pool](/docs/admission) for the provider account and assign the connection
   to it. A route with no declared pool returns 503. Credentials for the same account must share
   one pool or parent.
6. Use the virtual key with `/v1/chat/completions` or `/v1/messages`. Both request formats and
   streaming work with each profile, within the wire compatibility limits.

Management rules:

- Management needs the `tm_s` session cookie.
- Writes also need `Content-Type: application/json` and an `Origin` header equal to
  `https://demo.routerplus.com`.
- A same-origin browser `fetch` sends the cookie and Origin for you. A CLI client must send
  both. Keep cookies and provider keys out of shell history.
- An inference key cannot manage connections.
- Viewers can read. Owners and admins can write.

## Management operations

| Method and site path | JSON body | Effect |
|---|---|---|
| `GET /api/connections` | none | Newest 100 connections of your org, deleted ones included |
| `GET /api/connections/{id}` | none | One connection's metadata and fully masked label |
| `POST /api/connections` | `profile`, `models`, `api_key` or `workload_role`, optional `name`, `endpoint_config` | Create a pending connection |
| `POST /api/connections/{id}/validate` | `{}` | Check the credential and activate on success. A failed validation leaves the connection pending. |
| `POST /api/connections/{id}/rotate` | `api_key` or `workload_role` | Revoke old versions and create a pending version. Validate it before use. |
| `POST /api/connections/{id}/disable` | `{}` | Disable the connection and revoke its credential versions |
| `POST /api/connections/{id}/bind` | `key_id` | Bind or rebind a virtual key of your org to an active connection |
| `DELETE /api/connections/{id}` | `{}` | Revoke and mark deleted. Attribution and bindings are kept. |

Lifecycle rules:

- To restore a disabled connection, rotate and validate a new credential.
- You cannot restore a deleted connection.
- Rotation stops new inference until validation succeeds.
- A profile or model-list change needs a new connection and an explicit rebind.
- You cannot unbind a key back to marketplace routing. Use a `house_only` policy from the
  [policy API](/docs/routing-policies) instead.
- Management responses never show a secret suffix, ciphertext, envelope or provider validation
  body.

## Inference behavior

### Routing

- A bound key can use only its connection's exact models. It never falls back to marketplace
  supply on its own.
- `/v1/models` lists the connection's models.
- Anthropic token counting uses the same connection, on an Anthropic profile only.
- Image generation works through an `openai` connection. List the exact image model ids you
  will send (matching is literal). OpenAI bills the render to your account, so `usage.cost` is
  `0`. See [POST /v1/images/generations](/docs/api-images).
- Supported destinations are OpenAI, Anthropic and configured Azure v1 public endpoints. Bedrock
  uses the [workload-role profile](bedrock.md). RouterPlus refuses redirects and arbitrary
  endpoints.
- BYOK gives no private-link, residency or retention guarantee.
- [Routing policies](/docs/routing-policies) add ordering, filtering and funding controls.

### Errors

| Status | Cause |
|---|---|
| `401 auth` | The virtual key is invalid. |
| `404 model_unavailable` | The binding is unavailable, disabled or deleted. |
| `503 gateway_error` | A database or decryption failure. |
| 400 | The request sends its own credentials or destination (`api_key`, `base_url` and the like). |

RouterPlus never relays provider HTTP error bodies, so an echoed credential cannot leak.

### Billing

- RouterPlus meters and audits BYOK inference.
- RouterPlus charges `0`. The attempt's `billing_source` is `byok` and its `cost_usd` is `0`.
- The inference cost is `null`, because RouterPlus does not price your provider account. The
  provider bills your account.
- Marketplace spend caps do not limit that provider bill. Virtual-key RPM limits and your
  organization's token and concurrency limits still apply, including to token counting.
- A BYOK key spends RouterPlus credit in one case: a policy with marketplace fallback. The
  marketplace attempt reserves and charges like any marketplace call.

### Changes and outages

- New calls see a disable or rotation within 5 seconds. Calls and streams already started can
  finish on their original credential version.
- When the configuration database is unreachable, authority that RouterPlus already verified
  can serve for a bounded time. See [limits and outage behavior](/docs/admission).
- Validation and token-count calls are not inference ledger attempts. Validation writes a
  management audit event with no content.
- Shared limits and pilot fairness are in the [admission guide](/docs/admission).

## Related

- [Workspaces and principals](identity.md): scoped keys and trusted end-user limits.
- [Bedrock workload-role profile](bedrock.md): native regional Claude inference. Its write-only
  `workload_role` replaces `api_key`.

The connection lifecycle, the quota-pool rule and the zero RouterPlus charge are the same for
every profile.
