# Авторизация, ключи и права

Подробный разбор кодов, которыми API Вайбкод отвечает, когда ключ не опознан, ему не хватает прав или он работает в режиме «только чтение».

Сводная таблица всех кодов API Вайбкод — [Коды ошибок](/docs/errors).

## `MISSING_API_KEY` (401)

Запрос не содержит заголовка `X-Api-Key`.

```json
{
  "success": false,
  "error": {
    "code": "MISSING_API_KEY",
    "message": "API key required. Pass via X-Api-Key header."
  }
}
```

**Причины:**
- Не передан заголовок `X-Api-Key` или `Authorization`.
- Заголовок передан с пустым значением.

**Решение:**
- Добавить заголовок `X-Api-Key: vibe_api_...` или `X-Api-Key: vibe_app_...`.
- Проверить, что переменная окружения с ключом установлена корректно (для CLI-утилит и SDK).

---

## `INVALID_API_KEY` (401)

Переданный ключ не существует или его формат не распознан.

```json
{
  "success": false,
  "error": {
    "code": "INVALID_API_KEY",
    "message": "Invalid API key"
  }
}
```

**Причины:**
- Опечатка или лишние пробелы в ключе.
- Ключ удалён владельцем или администратором.
- Ключ от другого окружения — тестового вместо боевого или наоборот.
- Префикс не из числа поддерживаемых: `vibe_api_`, `vibe_app_`, `vibe_live_`.

**Решение:**
- Сверить ключ в личном кабинете на странице `/keys`.
- Создать новый ключ, если старый удалён.

---

## `TOKEN_MISSING` (401)

У ключа нет кредов Битрикс24, поэтому вызов к порталу выполнить нечем. Причина зависит
от типа ключа, и это два разных сценария.

**Личный ключ (`vibe_api_*`)** ходит в портал по вебхуку. Если вебхука на ключе нет,
ответ на вызовах сущностей (`/v1/{сущность}` и `POST /v1/batch`) несёт машиночитаемую
причину в `error.details`. На остальных маршрутах приходит тот же код без `details`:

```json
{
  "success": false,
  "error": {
    "code": "TOKEN_MISSING",
    "message": "This personal API key (vibe_api_*) has no Bitrix24 webhook credentials, ...",
    "details": {
      "reason": "B24_MARKET_SUBSCRIPTION_REQUIRED",
      "paywallCode": "B24_MARKET_SUBSCRIPTION_REQUIRED"
    }
  }
}
```

Значения `details.reason`:

| Причина | Что означает | Что делать |
|---|---|---|
| `B24_MARKET_SUBSCRIPTION_REQUIRED` | На портале нет активной подписки BitrixGPT + Маркетплейс | Оформить подписку или активировать её пробный период, затем переподключить ключ |
| `B24_MARKET_TRIAL_USED` | Пробный период подписки BitrixGPT + Маркетплейс уже использован, платной подписки нет | Оформить подписку, затем переподключить ключ |
| `INT_TARIFF_REQUIRED` | У портала нет платного тарифа Битрикс24 (регионы с тарифной моделью доступа) | Подключить платный тариф, затем переподключить ключ |
| `VIBE_SCOPES_ONLY` | Ключ не запрашивал ни одного скоупа Битрикс24 — вебхук такому ключу не выдаётся | Создать ключ с нужными скоупами Битрикс24 |
| `WEBHOOK_NOT_CONFIGURED` | Доступ Битрикс24 в порядке либо неизвестен, а вебхука на ключе нет | Переподключить ключ. При `details.hint` — повторить проверку через `GET /v1/me?refresh=tariff` |

**Переподключение** — `POST /api/keys/:id/reconnect`: выдаёт ключу вебхук, не меняя саму
строку ключа (интеграции перенастраивать не нужно), и снимает авто-блокировку со связанных
ботов. Не применимо к ключам приложения, системным ключам и ключам без скоупов Битрикс24 —
для них остаётся создание нового ключа.

`paywallCode` приходит только для тарифных причин. Вместе с ним может прийти
`upgradeUrl` — ссылка на страницу подключения на портале. У `INT_TARIFF_REQUIRED`
её нет.

Те же три условия закрывают установку приложения и привязку места встраивания —
там они приходят самостоятельными кодами `403`, разбор — [Биллинг, тариф и подписка](/docs/errors/billing).

**Ключ приложения (`vibe_app_*`)** держит токены портала в пользовательской сессии, а не
на ключе. Вызов только с `X-Api-Key`, без `Authorization: Bearer <токен сессии>`, законно
отвечает `TOKEN_MISSING` — `details` в этой ветке не приходит, а `message` описывает
пропущенный шаг OAuth. Полный поток — [Ключи и авторизация](/docs/keys-auth).

**Как посмотреть состояние ключа заранее:** `GET /v1/me` для личного ключа отдаёт блок
`b24Credentials` (`ready`, а при `ready: false` — та же `reason` и действия), а
`GET /v1/keys` — признак `b24Ready` на каждом ключе. Ответ `/v1/me` кэшируется на 30 секунд,
поэтому сразу после починки на портале читайте его как `GET /v1/me?refresh=tariff` — иначе
до полуминуты будет отдаваться прежнее состояние. У `GET /v1/keys` кэша нет.

---

## `SCOPE_DENIED` (403)

У ключа нет нужного скоупа для запрошенной операции.

```json
{
  "success": false,
  "error": {
    "code": "SCOPE_DENIED",
    "message": "This endpoint requires 'crm' scope"
  }
}
```

**Причины:**
- Для CRM-сущностей нужен скоуп `crm`, для задач — `task`, для бот-платформы — `imbot`, для AI Router — `vibe:ai`, для инфраструктуры — `vibe:infra`.
- Скоуп ключа сужен на этапе создания.

**Решение:**
- Открыть страницу ключа в личном кабинете и выпустить новый ключ с расширенным набором скоупов.
- Полный список скоупов и их назначение — на странице [Ключи и авторизация](/docs/keys-auth).

---

## `BITRIX_ACCESS_DENIED` (403)

Битрикс24 ответил `ACCESS_DENIED`: у пользователя или приложения нет прав на сущность или операцию.

```json
{
  "success": false,
  "error": {
    "code": "BITRIX_ACCESS_DENIED",
    "message": "ACCESS_DENIED"
  }
}
```

**Причины:**
- У пользователя нет прав на сущность в CRM (например, чужая сделка с ограничением видимости).
- Набор скоупов на портале уже, чем набор скоупов ключа. Скоупы Битрикс24 закрепляются за ключом в момент выпуска, поэтому скоуп, добавленный к уже выпущенному ключу, `GET /v1/me` покажет, а к данным портала ключ обратится с прежним набором.
- Запрашиваемый модуль выключен на портале (отсутствует CRM, бот-платформа и тому подобное).

**Решение зависит от типа ключа.** Когда отказ вызван набором скоупов, в `error.hint` приходит подсказка с конкретным случаем. Подсказка приходит не всегда: голому `ACCESS_DENIED` без пояснений от Битрикс24 её может не быть.

- **API-ключ (`vibe_api_`).** Набор скоупов, с которым ключ обращается к порталу, хранится на портале отдельно от набора у самого ключа. [Перевыпустить ключ](/docs/keys-auth#перевыпуск), переподключить его или создать новый с отмеченным скоупом — правка разрешений приложения на портале в этом случае ничего не меняет.
- **Ключ авторизации (`vibe_app_`).** Создать приложение заново с нужным скоупом и пройти авторизацию заново. Перевыпуск ключа здесь скоуп не выдаёт.
- **Методы чатов и ботов.** Для них того же отказа недостаточно объяснить скоупом: владелец ключа должен быть администратором портала. Выпустить ключ под учётной записью администратора — расширение скоупов тут не поможет.
- Если дело в правах сотрудника, а не в скоупах ключа — проверить права пользователя в карточке сущности Битрикс24.

Полное описание того, как скоупы закрепляются за ключом и что делать, если после перевыпуска отказ повторяется, — [Ключи и авторизация](/docs/keys-auth).

---

## `WRITE_BLOCKED_READONLY_KEY` (403)

У ключа задан режим «только чтение» (`accessMode: "READONLY"`), а запрос выполняет запись. Полное описание режима, переключения и политики портала — [Режим доступа](/docs/keys-auth/access-mode).

```json
{
  "success": false,
  "error": {
    "code": "WRITE_BLOCKED_READONLY_KEY",
    "message": "Key is in read-only mode. Switch to read+write in /keys to enable writes.",
    "details": {
      "method": "crm.item.add",
      "keyName": "MCP key",
      "currentMode": "READONLY",
      "switchUrl": "/keys"
    }
  }
}
```

**Поля `details`:**

| Поле | Когда возвращается | Описание |
|------|-------------------|----------|
| `method` | Только при проксировании в Битрикс24 | Имя метода Битрикс24, который был бы вызван при успешной записи (например, `crm.item.add`). Для менеджмент-ключей не возвращается — блокировка идёт по HTTP-методу запроса |
| `keyName` | Всегда | Название ключа из личного кабинета. Если у ключа нет названия — возвращается `"unnamed"` |
| `currentMode` | Всегда | Действующий режим ключа — всегда `"READONLY"` для этой ошибки |
| `switchUrl` | Всегда | Путь до страницы личного кабинета, где режим переключается, — `"/keys"` |

**Причины:**

- **API-ключ или ключ авторизации (`vibe_api_`, `vibe_app_`)** в режиме `READONLY` выполнил вызов, который проксируется в Битрикс24 как операция записи: создание, обновление, удаление, действие над сущностью.
- **Менеджмент-ключ (`vibe_live_`)** в режиме `READONLY` выполнил запрос с HTTP-методом `POST`, `PATCH`, `PUT` или `DELETE` — например, попытка создать ключ через `POST /v1/keys` или удалить запись обратной связи.

**Решение:**

- Владельцу ключа — открыть [Ключи API](/keys), в карточке нужного ключа в блоке **Режим доступа** выбрать «Чтение и запись» и сохранить. Режим применяется к следующему запросу, перевыпуск не нужен.
- Если в карточке выбор переключателя недоступен — администратор портала ограничил режим. Запросить у администратора снятие ограничения для этого ключа.
- При работе через AI-агента — действующий режим возвращает `GET /v1/me` в поле `data.accessMode`. Если запись нужна постоянно, выпустить отдельный ключ с режимом «чтение и запись».

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

- [Коды ошибок](/docs/errors)
- [Биллинг, тариф и подписка](/docs/errors/billing)
- [Ключи и авторизация](/docs/keys-auth)
- [Режим доступа](/docs/keys-auth/access-mode)
- [Менеджмент-ключи](/docs/management-keys)
- [Скоупы](/docs/scopes)
- [Повторы и обработка ошибок в коде](/docs/errors/handling)
