# Your own keys (BYOK)

Management of personal keys for paid web-search engines. After you add your own key, subsequent calls to [`POST /v1/search`](/docs/search/run) and [`POST /v1/research`](/docs/search/research) with that provider do not charge Ꝟ — billing goes directly from your account at the provider.

The section supports eight BYOK providers: `tavily`, `brave`, `exa`, `you-com`, `linkup`, `perplexity`, `jina`, `z-ai`. The platform `bitrix-search` is not configured through these endpoints — the platform issues its token centrally.

Scope: `vibe:search`

## Operations

- [List your keys](./credentials/list.md) — `GET /v1/search/credentials`
- [Add a key](./credentials/create.md) — `POST /v1/search/credentials`
- [Delete a key](./credentials/delete.md) — `DELETE /v1/search/credentials/:id`
- [Test a key](./credentials/test.md) — `POST /v1/search/credentials/:id/test`

## Typical scenario

1. Obtain a token from the chosen provider: for example, `tvly-…` in the [Tavily dashboard](https://tavily.com), a subscription token in [Brave Search API](https://brave.com/search/api/), or a key in the Exa, You.com, Linkup, Perplexity, Jina, or Z.AI dashboard.
2. Add the key via [`POST /v1/search/credentials`](./credentials/create.md) with `isDefault: true`. The server validates the key with the provider and saves the record only on a successful check.
3. Requests to [`POST /v1/search`](/docs/search/run) and [`POST /v1/research`](/docs/search/research) without the `provider` field now go through your default BYOK key.
4. If the key was revoked at the provider, a repeat call to [`POST /v1/search/credentials/:id/test`](./credentials/test.md) updates the status, and the `lastError` field records the reason.

## Known specifics

**Eight BYOK providers.** The platform `bitrix-search` does not accept user keys — the platform issues the token centrally. Attempting to pass `provider: "bitrix-search"` returns `400 INVALID_REQUEST` with the message `Expected 'tavily' | 'brave' | 'exa' | 'you-com' | 'linkup' | 'perplexity' | 'jina' | 'z-ai'`.

**Key correctness is verified on creation.** The server makes a trial call to the provider before saving the record. If the key is rejected — `400 INVALID_CREDENTIAL` is returned with the provider's message, and the record is not created. This eliminates a class of errors: a default key that the provider has already revoked.

**One default key per provider.** When you add a new key with `isDefault: true`, the previous default key of the same provider automatically stops being default.

**Token rotation — via delete and create.** There is no separate `PATCH` to update a token. To replace a key — first [`POST /v1/search/credentials`](./credentials/create.md) with the new token (with `isDefault: true` if the old one was default), then [`DELETE /v1/search/credentials/:id`](./credentials/delete.md) for the previous one.

**USER scope.** Through the v1 endpoints only a USER key is added — it applies to a specific user's requests.

**OAuth apps require Bearer.** When calling through a `vibe_app_…` key you need the `Authorization: Bearer <session_token>` header — without it the server returns `401 UNAUTHORIZED`. More in [Keys and authorization](/docs/keys-auth).

## See also

- [Web Search for AI](/docs/search) — section overview, pricing
- [Search (POST /v1/search)](/docs/search/run) — BYOK key selection cascade in the main endpoint
- [Deep search (POST /v1/research)](/docs/search/research) — research mode uses BYOK of the same providers
- [Providers](/docs/search/providers) — which engines accept BYOK keys
- [Keys and authorization](/docs/keys-auth) — personal key and authorization key
