# Свои ключи (BYOK)

Управление личными ключами для платных движков веб-поиска. После добавления своего ключа последующие вызовы [`POST /v1/search`](/docs/search/run) и [`POST /v1/research`](/docs/search/research) с этим провайдером не списывают Ꝟ — оплата идёт напрямую с вашего аккаунта у поставщика.

Раздел поддерживает восемь BYOK-провайдеров: `tavily`, `brave`, `exa`, `you-com`, `linkup`, `perplexity`, `jina`, `z-ai`. Платформенный `bitrix-search` через эти эндпоинты не настраивается — токен выпускает платформа централизованно.

Скоуп: `vibe:search`

## Операции

- [Список своих ключей](./credentials/list.md) — `GET /v1/search/credentials`
- [Добавить ключ](./credentials/create.md) — `POST /v1/search/credentials`
- [Удалить ключ](./credentials/delete.md) — `DELETE /v1/search/credentials/:id`
- [Проверить ключ](./credentials/test.md) — `POST /v1/search/credentials/:id/test`

## Типовой сценарий

1. Получить токен у выбранного провайдера: например, `tvly-…` в [личном кабинете Tavily](https://tavily.com), токен подписки в [Brave Search API](https://brave.com/search/api/) или ключ в кабинете Exa, You.com, Linkup, Perplexity, Jina, Z.AI.
2. Добавить ключ через [`POST /v1/search/credentials`](./credentials/create.md) с `isDefault: true`. Сервер проверяет ключ у провайдера и сохраняет запись только при успешной проверке.
3. Запросы [`POST /v1/search`](/docs/search/run) и [`POST /v1/research`](/docs/search/research) без поля `provider` теперь идут через ваш дефолтный BYOK-ключ.
4. Если ключ был отозван у провайдера — повторный вызов [`POST /v1/search/credentials/:id/test`](./credentials/test.md) обновит статус, поле `lastError` зафиксирует причину.

## Известные особенности

**Восемь BYOK-провайдеров.** Платформенный `bitrix-search` не принимает пользовательские ключи — токен выпускает платформа централизованно. При попытке передать `provider: "bitrix-search"` приходит `400 INVALID_REQUEST` с сообщением `Expected 'tavily' | 'brave' | 'exa' | 'you-com' | 'linkup' | 'perplexity' | 'jina' | 'z-ai'`.

**Корректность ключа проверяется при создании.** Сервер делает пробный вызов к провайдеру до сохранения записи. Если ключ отклонён — возвращается `400 INVALID_CREDENTIAL` с сообщением провайдера, запись не создаётся. Это закрывает класс ошибок «дефолтным выбран ключ, который провайдер уже отозвал».

**Один дефолтный ключ на провайдер.** При добавлении нового ключа с `isDefault: true` предыдущий дефолтный ключ того же провайдера автоматически перестаёт быть дефолтным.

**Ротация токена — через удаление и создание.** Отдельного `PATCH` для обновления токена нет. Чтобы заменить ключ — сначала [`POST /v1/search/credentials`](./credentials/create.md) с новым токеном (с `isDefault: true`, если старый был дефолтным), затем [`DELETE /v1/search/credentials/:id`](./credentials/delete.md) для прежнего.

**Скоуп USER.** Через v1-эндпоинты добавляется только USER-ключ — он действует для запросов конкретного пользователя.

**OAuth-приложения требуют Bearer.** При вызове через ключ `vibe_app_…` нужен заголовок `Authorization: Bearer <session_token>` — без него сервер возвращает `401 UNAUTHORIZED`. Подробнее в [Ключи и авторизация](/docs/keys-auth).

## Смотрите также

- [Web Search для AI](/docs/search)
- [Поиск (POST /v1/search)](/docs/search/run)
- [Глубокий поиск (POST /v1/research)](/docs/search/research)
- [Провайдеры](/docs/search/providers)
- [Ключи и авторизация](/docs/keys-auth)
