# Your own keys (BYOK)

Connecting your own provider keys (`Bring Your Own Key`). All requests through your key go directly to the provider and are **not charged** against your Vibecode balance — you pay the provider at its own rates.

Supported providers: OpenAI, Anthropic, OpenRouter, Google Gemini, Mistral AI, Groq, Together AI, DeepSeek, Fireworks AI, Cerebras, Cohere, Minimax, Qwen, Yi, plus **Custom OpenAI-Compatible** for connecting any API-compatible service (requires a `baseUrl`).

Scope: `vibe:ai`

## What to know before you start

1. **One key per provider.** Connecting the same provider again via `POST /v1/ai/credentials` returns `409 already_exists`. To replace a key — update the existing one via `PATCH`.
2. **Verification on save.** On creation and on updates to the `credentials` field, the key is verified with the provider (`POST` to `/chat/completions` or `GET /v1/models`). An invalid key — `422 credential_invalid` with a message from the provider.
3. **`Custom OpenAI-Compatible`.** Requires a `baseUrl` in the `https://...` or `http://...` format. Private networks (loopback, RFC 1918, link-local) are blocked as `SSRF` (Server-Side Request Forgery) protection.
4. **The model table depends on the provider.** For most providers the catalog is fixed. For a Custom service the catalog is either fetched from the provider's endpoint via `fetch-models` or assembled manually via `models-add`.
5. **Key priority.** Your USER key takes priority over a key that the Bitrix24 account administrator connected for everyone. If both are configured — yours is used.
6. **V1 manages only USER keys.** Portal-level keys (PORTAL scope, available to all members) are connected by a Bitrix24 account administrator in the Vibecode dashboard, not through V1.

## Limits

| Limit | Value |
|-------|----------|
| Key creation | 10 requests per minute |
| Key verification | 10 requests per minute |
| Key update (with verification) | 10 requests per minute |
| Model catalog fetch | 10 requests per minute |
| Manual model registration / deletion | 30 requests per minute |

Limits are counted **per portal**: all API keys of one portal share a single bucket. On exceeding a limit you get `429` with a `Retry-After` header.

## A key doesn't work from our region {#geo-block-faq}

OpenAI, Anthropic, and some other providers block requests by server IP.
If you see a `PROVIDER_GEOBLOCKED` error when saving a key, pick one
of two paths:

1. **Use OpenRouter** — they have a POP in Singapore, with no blocks.
   Get your own key at [openrouter.ai](https://openrouter.ai/) and connect it
   as the BYOK provider "openrouter". Through it you can run models from OpenAI, Anthropic,
   Google, Meta, and dozens of others.

2. **Specify your own proxy** — if you already have an HTTP/HTTPS proxy in an
   unblocked jurisdiction, expand "Advanced settings" in the key connection form and
   provide a URL in the `https://user:pass@host:port` format. All requests through this
   key will go through your proxy (including the initial key check).

### How the platform detects a geo-block

Signals that trigger "the provider blocks by region":

- HTTP 403 + a response body containing `country` / `region` / `territory` / `unsupported location`
- HTTP 451 (Unavailable For Legal Reasons)
- The structured OpenAI error code `unsupported_country_region_territory`
- A network drop on `api.openai.com` / `api.anthropic.com` (`ECONNREFUSED` / `EHOSTUNREACH` / `ETIMEDOUT`)

If the key passed the initial check but later broke on real `/v1/chat/completions`
calls, a "Geo-blocked" badge appears on the key's card in `/ai`.
This means the provider started blocking requests after the key was saved —
the actions are the same: add a proxy or migrate to OpenRouter.

> ⚠️ **Legal note.** Using a proxy to bypass geographic
> restrictions may violate the provider's Terms of Service. Responsibility for
> complying with the key's usage terms rests with you.

## Operations

- [List providers](./credentials/providers.md) — `GET /v1/ai/providers`
- [List keys](./credentials/list.md) — `GET /v1/ai/credentials`
- [Connect a key](./credentials/create.md) — `POST /v1/ai/credentials`
- [Update a key](./credentials/update.md) — `PATCH /v1/ai/credentials/:id`
- [Delete a key](./credentials/delete.md) — `DELETE /v1/ai/credentials/:id`
- [Test a key](./credentials/test.md) — `POST /v1/ai/credentials/:id/test`
- [Key usage stats](./credentials/usage.md) — `GET /v1/ai/credentials/:id/usage`
- [Fetch the model catalog](./credentials/fetch-models.md) — `POST /v1/ai/credentials/:id/fetch-models` (Custom)
- [List a key's models](./credentials/models-list.md) — `GET /v1/ai/credentials/:id/models`
- [Add a model manually](./credentials/models-add.md) — `POST /v1/ai/credentials/:id/models` (Custom)
- [Delete a key's model](./credentials/models-delete.md) — `DELETE /v1/ai/credentials/:credId/models/:modelRowId`

## Typical scenario

### Connecting a standard provider

1. Get the provider ID: [`GET /v1/ai/providers`](/docs/ai/credentials/providers).
2. Connect the key: [`POST /v1/ai/credentials`](./credentials/create.md). The key is automatically verified with the provider before saving — if the key is invalid, `422` is returned.
3. After connecting, the provider's models appear in [`GET /v1/models`](/docs/ai/models/list).

### Connecting a Custom service (OpenAI-compatible)

1. Connect the key with a `baseUrl`: [`POST /v1/ai/credentials`](./credentials/create.md) with `providerId: cprv_custom_seed`.
2. Fetch the model catalog: [`POST /v1/ai/credentials/:id/fetch-models`](./credentials/fetch-models.md). If the service does not support `GET /v1/models` — add models manually: [`POST /v1/ai/credentials/:id/models`](./credentials/models-add.md).
3. Use the `modelId` in [chat completion](/docs/ai/chat/completions).

## See also

- [AI Router](/docs/ai)
- [List of providers](/docs/ai/credentials/providers)
- [Models](/docs/ai/models)
