Для AI-агентов: markdown этой страницы — /docs-content/errors.md индекс документации — /llms.txt

Коды ошибок

Справочник кодов ошибок API Вайбкод: единый формат ответа, перечень кодов, типичные причины и способы устранения. Применяется ко всем эндпоинтам /v1/....

Формат ответа при ошибке

Каждый ответ с ошибкой возвращается в едином виде. error — объект.

JSON
{
  "success": false,
  "error": {
    "code": "ENTITY_NOT_FOUND",
    "message": "Элемент не найден"
  }
}
Поле Тип Обяз. Описание
success boolean да При ошибке всегда false
error.code string да Машиночитаемый код ошибки. Используйте для различения типов ошибок в коде клиента
error.message string да Описание ошибки для разработчика. Язык заранее не известен и зависит от источника: технические сообщения платформы приходят на английском, сообщения от Битрикс24 — на языке портала, сообщения о сбоях облачного провайдера локализуются под язык пользователя. Не разбирайте текст и не полагайтесь на его язык — ветвитесь по error.code
error.hint string | object нет Подсказка для разработчика: что попробовать дальше, на какие пределы обратить внимание. Строка с текстом либо, на эндпоинтах создания инфраструктуры POST /v1/infra/servers, объект с полями reason, recovery и example — в example готовое тело запроса для исправления
error.userMessage string нет Сообщение для конечного пользователя на русском языке. Появляется в биллинговых, инфраструктурных и тарифных ошибках, при перегрузке очереди портала и в отказах лимитера рабочего времени портала
error.details object нет Машиночитаемый контекст отдельных кодов. Примеры: reason в INVALID_STATE, deployableKeys в INFRA_FORBIDDEN_FOR_COWORK_KEY, upgradeUrl в отказах по подписке, method и switchUrl в WRITE_BLOCKED_READONLY_KEY. Набор полей зависит от кода — читайте его описание
error.warning string нет Появляется при повторяющихся одинаковых ошибках на одном ключе — вероятный признак ошибки в коде клиента. Счётчик эвристический, поэтому предупреждение не гарантирует наличие ошибки
error.retryAfter number нет Секунды до следующей попытки. Появляется в 429 (rate-limit, очередь портала — QUEUE_OVERFLOW/QUEUE_TIMEOUT, лимитер рабочего времени портала — OPERATION_TIME_LIMIT) и в транзиентных 503 (BITRIX_TIMEOUT, POOL_EXHAUSTED, DB_TRANSIENT, SERVICE_UNAVAILABLE). У LARGE_BODY_BACKEND_BUSY поле приходит не на всех путях отказа — там берите срок из заголовка Retry-After
error.b24Code string нет Машиночитаемый код причины от Битрикс24 в ответах 422 BITRIX_ERROR. Приходит не всегда — только когда Битрикс24 прислал отдельный код
error.release string нет Идентификатор обновления Битрикс24, которого ждёт портал: имя модуля и номер версии одной строкой, например imopenlines 26.700.0. Приходит только в METHOD_NOT_YET_AVAILABLE
error.scope string нет Радиус отказа по лимиту: "apiKey" — приостановлен только вызывающий ключ, "portal" — пауза действует на весь портал Битрикс24 и её видят все его ключи. Появляется в OPERATION_TIME_LIMIT ("apiKey"), TIMEOUT_QUARANTINE ("portal") и FEEDBACK_QUOTA_EXCEEDED (оба значения). Различает «чинить свой код» и «ждать вместе с порталом»

Пример ответа с дополнительными полями (429 RATE_LIMITED):

JSON
{
  "success": false,
  "error": {
    "code": "RATE_LIMITED",
    "message": "QUERY_LIMIT_EXCEEDED",
    "hint": "Wait 1-2 seconds and retry. Use POST /v1/batch to combine up to 50 calls in 1 request.",
    "retryAfter": 2
  }
}

HTTP-заголовок Retry-After дублирует значение error.retryAfter для совместимости со стандартом HTTP. Есть отказы, где поле в теле не приходит, а заголовок — приходит, поэтому опирайтесь на заголовок.

Сводная таблица кодов

Таблица покрывает основные коды, которые встречаются на любом эндпоинте API Вайбкод. Доменные коды (BOT_NOT_FOUND, SERVER_NOT_RUNNING, AGENT_LIMIT_REACHED и подобные) описаны на страницах соответствующих разделов.

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

Код HTTP Когда возникает
MISSING_API_KEY 401 Запрос без заголовка X-Api-Key
INVALID_API_KEY 401 Ключ не найден в системе или формат не распознан
INVALID_APP_KEY 401 Передан vibe_app_*, но без сопровождающего Authorization: Bearer ...
WRONG_AUTH_SCHEME 401 API-ключ передан в заголовке Authorization: Bearer. Ключ OAuth-приложения (vibe_app_*) передаётся в X-Api-Key, а Authorization: Bearer несёт сессионный токен (vibe_session_*). Клиенту, который умеет только Bearer, используйте личный ключ (vibe_api_*) — он принимается в Authorization: Bearer
TOKEN_EXPIRED 401 Срок действия OAuth-токена истёк
TOKEN_REFRESH_FAILED 401 Не удалось обновить OAuth-токен на стороне Битрикс24
WRONG_KEY_TYPE 401 Тип ключа не подходит к эндпоинту: например, management-ключ на entity-маршруте
WRONG_KEY 403 Сервер существует, но привязан к другому API-ключу. Операции над содержимым приложения — выкладка, команда, загрузка файла и чтение логов — принимают либо управляющий ключ сервера, либо ключ, приложение которого привязано к этому серверу. Управление машиной, токены доступа и загрузка значка требуют управляющего ключа. В ответе — hint с восстановлением из двух шагов: перепривязать сервер в кабинете и сменить ключ, которым обращается клиент. Подробнее — восстановление доступа
TOKEN_MISSING 401 У ключа нет кредов Битрикс24. Для личного ключа (vibe_api_*) — нет вебхука портала, причина приходит в error.details. Для ключа приложения (vibe_app_*) — не передан Authorization: Bearer с токеном сессии
SESSION_REQUIRED 401 Операция с местами встраивания выполнена без заголовка Authorization: Bearer с токеном сессии там, где аккаунт его требует
SESSION_APP_MISMATCH 403 Сессия в Authorization: Bearer выписана другому приложению или другому аккаунту Битрикс24, чем ключ в X-Api-Key. Передайте ключ авторизации того приложения, которое выписало сессию через POST /v1/oauth/token
PERSONAL_KEY_WEBHOOK_SCOPES_INVALID 400 Выписка или обновление ключа портала, где placement и entity запрошены, а кроме них в наборе прав ничего нет. Ключ портала стоит на входящем вебхуке Битрикс24, а такие права вебхук не несёт — добавьте право на данные либо заведите OAuth-приложение. Приходит на создании и обновлении ключа, подробнее — менеджмент-ключи
ACCOUNT_PENDING_ERASURE 503 Аккаунт владельца ключа ждёт удаления данных — на это время ключ заморожен. В ответе заголовок Retry-After: 3600. Действует на любой ключ владельца, включая менеджмент-ключ. Отмена запроса на удаление возвращает ключу работу, перевыпускать его не нужно

Состояние аккаунта Битрикс24

Состояние аккаунта, к которому привязан ключ, проверяется на каждом вызове. Отказы этой группы не привязаны к эндпоинту: пока аккаунт в одном из перечисленных состояний, ключ получает их на маршрутах /v1/..., у которых нет собственного отказа для этого состояния, и повтор запроса ничего не меняет.

Код HTTP Когда возникает
PORTAL_SUSPENDED 403 Аккаунт приостановлен
PORTAL_DELETED 403 Аккаунт удалён
PORTAL_BLOCKED 403 Аккаунт заблокирован. Рядом с кодом приходит blockedAt — момент блокировки в формате ISO 8601. Причину блокировки ответ не раскрывает
NO_PORTAL 401 Ключ не привязан ни к одному аккаунту. Исключение — маршруты хранилища: непривязанный ключ получает там 403 STORAGE_REQUIRES_PORTAL_BINDING. Тот же код с HTTP 500 приходит на маршрутах авторизации пользователей приложения и означает там другое — приложение не связано с аккаунтом

Авторизация пользователей приложения (OAuth)

Код HTTP Когда возникает
INVALID_REDIRECT_URI 400 redirect_uri не зарегистрирован у приложения на входе GET /v1/oauth/authorize
INVALID_STATE 400 state не найден или истёк за 20 минут на приёме ответа Битрикс24. В error.details.reasonNOT_FOUND или EXPIRED
INVALID_CODE 400 Код авторизации не найден или принадлежит другому приложению
CODE_EXPIRED 400 Срок действия кода авторизации прошёл — 5 минут
CODE_ALREADY_USED 400 Код авторизации уже обменян на токен сессии
REDIRECT_URI_MISMATCH 400 redirect_uri при обмене кода не совпадает с переданным на входе
DOMAIN_MISMATCH 400 domain в POST /v1/oauth/placement-session не совпадает с порталом приложения
USER_AUTH_REQUIRED 401 Токен пользователя Битрикс24 не подтвердил авторизацию на портале
MISSING_TOKEN 400 POST /v1/oauth/revoke без заголовка Authorization: Bearer с токеном сессии

Отказ на приёме возврата может прийти не кодом, а параметром ?error= в адресе redirect_uritoken_exchange_failed, invalid_domain или profile_fetch_failed.

Полное описание потока — Авторизация пользователей приложения.

Права и скоупы

Код HTTP Когда возникает
SCOPE_DENIED 403 У ключа нет нужного скоупа (например, crm для сделок, imbot для ботов)
WRITE_BLOCKED_READONLY_KEY 403 У ключа задан режим «только чтение», а вызов выполняет запись
INFRA_FORBIDDEN_FOR_COWORK_KEY 403 Ключ подписки Cowork (vibe:cowork) — только data-plane: запрещены provision / deploy / exec / upload / lifecycle сервера и публикация в каталог. Используйте проектный ключ с правами на деплой. В error.details.deployableKeys ответ перечисляет ваши другие активные ключи с правом деплоя (name / prefix / suffix, до 5)
INFRA_SCOPE_REQUIRED 403 У ключа нет скоупа vibe:infra — управление инфраструктурой недоступно. Добавьте скоуп или используйте ключ с правами на инфраструктуру
KEY_POLICY_READONLY_REQUIRED 403 Политика портала разрешает обычным пользователям создавать только ключи с режимом «только чтение» — выпуск ключа с записью отклонён
MANAGEMENT_KEY_READ_ONLY 403 Management-ключ без прав на запись пытается выполнить POST/PATCH/DELETE
MANAGEMENT_KEY_NO_ENTITY_ACCESS 403 Management-ключ обращается к entity-эндпоинту — нужен APP-ключ с нужным скоупом
BITRIX_ACCESS_DENIED 403 Битрикс24 ответил ACCESS_DENIED: у пользователя нет прав на операцию или сущность
OAUTH_REQUIRED 403 Эндпоинт требует пользовательский контекст — нужен ключ типа vibe_app_* + Bearer-токен
WAITLIST_PENDING 403 Аккаунт ожидает активации в waitlist
OAUTH_SCOPE_CHANGE_REQUIRES_REISSUE 403 Попытка добавить право Битрикс24 к OAuth-app-ключу (vibe_app_*) через PATCH /v1/keys/:id или к приложению через PATCH /v1/apps/:id. Права OAuth-приложения фиксируются при выпуске — снятие прав работает, а для нового права создайте приложение заново с нужным набором и пройдите авторизацию заново: перевыпуск ключа права не выдаёт
OAUTH_APP_REQUIRED 400 Операция с местами встраивания выполнена личным ключом vibe_api_*. Привязка, отвязка и список привязанных мест доступны только ключу авторизации приложения vibe_app_*
PLACEMENT_SCOPE_MISSING 403 У ключа нет скоупа placementпривязка и отвязка мест встраивания недоступны
SESSION_REQUIRES_ADMIN 403 Привязка места встраивания на коробочном аккаунте выполняется под учётной записью без прав администратора аккаунта
B24_EMBEDDING_APP_NOT_FOUND 404 Битрикс24 не знает идентификатор приложения: локальное приложение на аккаунте удалили или переустановили. Создайте локальное приложение заново и вызовите POST /v1/apps/:id/relink-oauth с новыми bitrixClientId и bitrixClientSecret. Не путать с APP_NOT_FOUND — тот про связку ключа и приложения на стороне платформы Вайбкод
B24_EMBEDDING_INSTALL_DENIED 403 Битрикс24 отказал в установке встройки при действующей подписке: у пользователя, чьим ключом разработчика идёт вызов, нет права ставить локальные приложения и/или нет доступа к самому приложению. Подписка считается действующей в двух случаях — её подтвердил Битрикс24 либо проверку выполнить не удалось, а аккаунт уже числится подписанным в Вайбкод. Если действующей подписки нет ни по одному из источников, тот же отказ приходит как 502
APP_NOT_REGISTERED 400 У приложения нет идентификатора приложения Битрикс24 — привязать или отвязать место встраивания нельзя
BOX_NO_DEVELOPER_KEY 400 У автора приложения не настроен ключ разработчика — операция с местами встраивания на коробочном аккаунте недоступна
OAUTH_APP_KEY_CANNOT_RELINK 403 POST /v1/apps/:id/relink-oauth вызван ключом самого OAuth-приложения (vibe_app_*). Перепривязывать учётные данные приложения таким ключом нельзя — используйте личный ключ (vibe_api_*) или кабинет

Валидация запроса

Код HTTP Когда возникает
VALIDATION_ERROR 400 Тело или query не прошли проверку схемы. message содержит подробности по полям
INVALID_JSON_BODY 400 Тело запроса не разбирается как JSON. Приходит до проверки схемы, поэтому полей в message нет. Этот код возвращают маршруты сущностей /v1/<сущность>, а также /v1/apps, /v1/bots, /v1/keys, /v1/note, все операции сервера /v1/infra/servers/:id, /v1/infra/runtimes, маршруты пользовательских полей, чатов /v1/chats/* и открытых линий /v1/openlines/*
FST_ERR_CTP_INVALID_JSON_BODY 400 Тот же случай — тело не разбирается как JSON — на остальных маршрутах: POST /v1/search, POST /v1/research, POST /v1/batch и прочих
fst_err_ctp_invalid_json_body 400 Тот же случай на OpenAI-совместимых маршрутах AI Router/v1/ai/, /v1/chat/, /v1/models, /v1/audio/. На них коды приводятся к нижнему регистру, а ответ идёт в OpenAI-конверте: error.type, error.code, без поля success
INVALID_PARAMS 400 Битрикс24 вернул INVALID_PARAMS или route-handler нашёл некорректное значение параметра
INVALID_REQUEST 400 Структура запроса не соответствует требуемой — например, calls в /v1/batch пустой массив или содержит больше 50 элементов, создание сервера без обязательных полей, не-объект вместо тела на маршрутах пользовательских полей
MISSING_PARAMS 400 Не передан обязательный параметр, явно перечисленный в схеме эндпоинта
MISSING_REQUIRED_FILTER 400 Не передан обязательный фильтр для list-эндпоинтов, требующих контекста: timelines (entityType + entityId), catalog-products и catalog-sections (iblockId), catalog-product-property-enums (propertyId). Он же приходит на агрегацию дел без сужающего фильтра — там достаточно одного сужения из нескольких, и message их перечисляет
MISSING_REQUIRED_PARAMS 400 Не переданы обязательные параметры контекста для поиска или списка вложенных данных: files требует folderId, foldersparentId, calendar-eventstype и ownerId. message перечисляет недостающие поля
MISSING_REQUIRED_FIELDS 400 Не передано поле тела, объявленное обязательным при создании сущности. message называет недостающее поле
MISSING_FIELD 400 Создание пользовательского поля без userTypeId. message приводит примеры допустимых типов
EMPTY_CREATE_BODY 400 Тело запроса на создание пустое — не передано ни одного поля
EMPTY_UPDATE_BODY 400 Тело запроса на обновление пустое — не передано ни одного поля
INVALID_FILTER_FIELD 400 Имя поля фильтра начинается с родного префикса Битрикс24 @ (IN) или !@ (NOT IN) — используйте операторы $in / $nin
UNKNOWN_FILTER_FIELD 400 Фильтрация по полю, которого нет в схеме сущности (для сущностей с полной схемой полей). Когда поле отклонил валидатор Вайбкод, message перечисляет допустимые имена после слова Available. Когда поле отклонил Битрикс24, список полей приходит в error.hint
UNKNOWN_SELECT_FIELD 400 Отбор полей select по имени, которого нет в схеме событий календаря — единственной сущности, где незнакомое имя отклоняется. message перечисляет допустимые имена после слова Available. На остальных сущностях запрос выполняется, а имя перечисляется предупреждением в meta.warnings. Рядом со значением * незнакомое имя тоже не отклоняется — приходит предупреждение
UNKNOWN_SORT_FIELD 400 Сортировка по несуществующему полю (для сущностей, у которых валидатор сортировки активен)
BATCH_LIMIT_EXCEEDED 400 Запрос содержит больше 50 элементов в массивной операции (vipchats, task-comments и подобные)
MESSAGE_REQUIRED 400 POST /v1/chats/{dialogId}/messages без текста: поле message пустое и нет блока attach. Частая причина — текст передан под неизвестным именем поля, например text. Ответ перечисляет нераспознанные поля
INVALID_EVENT 400 Код события подписки портала не соответствует формату ^[A-Z][A-Z0-9_]+$. См. Подписки на события портала
INVALID_APP_PATH 400 Путь доставки appPath не начинается с / либо содержит управляющие символы. См. Подписки на события портала
PLATFORM_HANDLER_UNRESOLVABLE 400 Адрес обработчика указывает на технический адрес сервера приложения, а платформенный обработчик определить не удалось. Место встраивания не зарегистрировано. См. Привязать место

Пустое тело с заголовком Content-Type: application/json принимается как {} на маршрутах /v1/infra/*, а также на всех маршрутах пользовательских полей: /v1/userfields/:entity, /v1/userfields/:entity/types и /v1/userfields/:entity/:id, те же три пути под /v1/items/:entityTypeId/userfields, а также короткие адреса счетов /v1/userfields/invoices, /v1/userfields/invoices/types и /v1/userfields/invoices/:id. Операции, которым тело не нужно — POST /v1/infra/servers/:id/wake, DELETE /v1/infra/servers/:id/access-tokens/:tokenId и подобные, — отвечают по существу, а не отклоняют запрос на разборе тела. Так ведут себя клиенты, которые ставят этот заголовок на любой запрос (например, axios и PowerShell Invoke-RestMethod).

Дальше запрос проверяет сама операция, и код отказа зависит от маршрута — берите его из таблицы выше или со страницы нужной операции. Тело, которое не разбирается как JSON, на этих маршрутах отклоняется кодом INVALID_JSON_BODY, то есть пустое и битое тело различаются.

Размер тела запроса

Код HTTP Когда возникает
PAYLOAD_TOO_LARGE 413 Тело запроса больше потолка этого маршрута
LARGE_BODY_BACKEND_BUSY 429 Платформа уже обрабатывает предельное число крупных тел. Запрос не выполнялся, повторите его через Retry-After секунд

Потолок зависит от маршрута. По умолчанию — 1 МБ. Создание и обновление записей, файлы ботов и чатов, note.file.add — 40 МиБ. Загрузка на Диск — 70 МБ. Файл внутри тела едет в base64 и растёт примерно на треть, поэтому исходный файл при потолке 40 МиБ — чуть меньше 30 МиБ. Тот же код приходит от пограничного слоя на его собственном пороге. Тело под необъявленным типом содержимого — например, text/plain — на маршрутах сущностей, пользовательских полей, чатов, заметок и ключей отклоняется кодом 415 FST_ERR_CTP_INVALID_MEDIA_TYPE, а пустое тело под тем же типом принимается там как {}. На /v1/infra/* и /v1/apps, включая публикацию исходников и места встраивания, потолок тела для непонятого типа равен одному байту, поэтому тот же запрос отвечает 413.

Крупным считается тело больше 1 МиБ — это тот же порог, что и потолок по умолчанию, — и число одновременно обрабатываемых крупных тел ограничено. Отказ приходит только там, где потолок тела поднят: записи сущностей, файлы ботов и файлы чатов. На загрузке на Диск и на note.file.add его не бывает. Когда свободного места нет, приходит 429 LARGE_BODY_BACKEND_BUSY с заголовком Retry-After: 5. Так же отвечает запрос без заголовка Content-Length, если объём переваливает тот же порог уже по ходу передачи. Срок повтора берите из заголовка: поле error.retryAfter в теле этого отказа приходит не на всех путях.

Исключение — маршруты AI (/v1/ai/*, /v1/chat/*, /v1/audio/*, /v1/models): у них конверт ошибки, совместимый с OpenAI, и на превышении тела в error.code приходит служебный код фреймворка в нижнем регистре, а не PAYLOAD_TOO_LARGE.

Загрузка файлов

Код HTTP Когда возникает
STORAGE_FORBIDDEN_CONTENT_TYPE 415 Для PUBLIC-объектов запрещены типы text/html, application/javascript, application/x-javascript, image/svg+xml — они опасны межсайтовым выполнением скриптов. Загружайте такой файл как PRIVATE

Предусловия подписок на события портала

Код HTTP Когда возникает
NOT_OAUTH_APP 400 Сервер не привязан к OAuth-приложению с application_token — подписку на событие зарегистрировать нельзя
NO_USER_TOKEN 400 У приложения нет OAuth-токена — сначала авторизуйте приложение на портале

Полное описание операций — Подписки на события портала.

Установка приложения через модуль-коннектор

Код HTTP Когда возникает
CONNECTOR_APP_INSTALL_FORBIDDEN 403 Администратор аккаунта Битрикс24 запретил этому сотруднику устанавливать приложения. Право выдаёт администратор аккаунта, повтор запроса состояние не меняет
CONNECTOR_MODULE_NOT_INSTALLED 409 Модуль-коннектор на аккаунте не установлен. Состояние постоянное — пока модуль не установят, повтор бессмыслен
CONNECTOR_APP_INSTALL_FAILED 502 Другой сбой установки на стороне модуля-коннектора. Запрос можно повторить
CONNECTOR_REST_UNAVAILABLE 502 Подписка или пробный период действуют, но Битрикс24 отказал в выписке парного ключа. Исходная причина — в error.details.reason, error.details.retryable: true говорит, что состояние временное

Коды приходят на создании приложения там, где приложение устанавливает модуль-коннектор: на коробочном аккаунте, а на облачном — когда такой выпуск для аккаунта включён. При любом из этих отказов ни приложение, ни парный ключ не создаются.

Ресурс не найден

Код HTTP Когда возникает
ROUTE_NOT_FOUND 404 Маршрута или HTTP-глагола не существует: опечатка в пути, несуществующая сущность, неподдерживаемый метод, а также операция, которой у этой сущности нет. Сверьте путь со списком в GET /v1/guide
ENTITY_NOT_FOUND 404 Запись CRM-сущности с указанным id не существует. Канонический код для /v1/deals/:id, /v1/contacts/:id и подобных
NOT_FOUND 404 Только GET /:id: Битрикс24 вернул success, но result пустой (применимо к нескольким смарт-методам)
OPERATION_NOT_FOUND 404 Операции выкладки с таким идентификатором нет, она принадлежит другому ключу либо запись уже удалена. Три случая отвечают одинаково намеренно — см. Исход выкладки

Доменные *_NOT_FOUND (BOT_NOT_FOUND, SERVER_NOT_FOUND, AGENT_NOT_FOUND, APP_NOT_FOUND, PORTAL_NOT_FOUND, USER_NOT_FOUND, FILE_NOT_FOUND, SUBSCRIPTION_NOT_FOUND) описаны на страницах соответствующих разделов.

B24_EMBEDDING_APP_NOT_FOUND (404) — отдельный случай: приложение есть на платформе Вайбкод, но Битрикс24 не знает его идентификатор, потому что локальное приложение на аккаунте удалили или переустановили. Лечится пересозданием локального приложения и вызовом POST /v1/apps/:id/relink-oauth с новыми bitrixClientId и bitrixClientSecret. Не путать с APP_NOT_FOUND — тот про связку ключа и приложения на стороне платформы Вайбкод.

Два вида 404. Один и тот же HTTP-статус 404 означает два разных состояния — различайте их по error.code. ROUTE_NOT_FOUND — маршрута или глагола не существует, повторять запрос бессмысленно: проверьте путь по GET /v1/guide. ENTITY_NOT_FOUND и доменные коды вида *_NOT_FOUND — маршрут существует, не найден запрошенный объект. Оба состояния отвечают в едином конверте V1.

Маршрута не существует:

JSON
{
  "success": false,
  "error": {
    "code": "ROUTE_NOT_FOUND",
    "message": "Route GET:/v1/dealz not found. Check GET /v1/guide for available endpoints and verbs."
  }
}

Маршрут существует, объекта нет:

JSON
{
  "success": false,
  "error": {
    "code": "ENTITY_NOT_FOUND",
    "message": "Элемент не найден"
  }
}

Конфликты состояния

Код HTTP Когда возникает
CONFLICT 409 Текущее состояние ресурса несовместимо с запросом
ALREADY_EXISTS 409 Запись с такими ключевыми полями уже существует
EVENT_BOUND_ELSEWHERE 409 Событие портала уже привязано к другому серверу того же OAuth-приложения. См. Подписки на события портала
OAUTH_CLIENT_ID_IN_USE 409 POST /v1/apps/:id/relink-oauth: указанный bitrixClientId уже привязан к другому приложению. Один client_id — одно приложение
OPERATION_OUTCOME_EXPIRED 410 Операция выкладки ваша и она точно была, но её исход больше не хранится (срок — 7 суток). См. Исход выкладки

Биллинг и тариф

Возникают на эндпоинтах создания и пробуждения инфраструктуры (серверы, агенты, управляемые боты). Ответ содержит userMessage на русском языке для показа в интерфейсе клиента.

Код HTTP Когда возникает
BILLING_EXHAUSTED 402 Баланс ушёл в красную зону, аккаунт заморожен. Нужен top-up
ACCOUNT_FROZEN 402 Платёжный аккаунт заморожен по другим причинам
COMMERCIAL_PLAN_REQUIRED 402 Бесплатный тариф Битрикс24, пробный период недоступен или уже использован
MARKETPLACE_REQUIRED 402 На портале нет активной подписки BitrixGPT + Маркетплейс — оформите её, чтобы открыть создание серверов, деплой и пробуждение
INT_VIBE_PLUS_REQUIRED 402 На портале не подключён тариф Vibe+. Подключите тариф Vibe+ и повторите запрос
TRIAL_EXPIRED 402 14-дневный пробный период завершён
TRIAL_PORTAL_LIMIT 402 На пробном периоде превышен общий лимит серверов на портал
TRIAL_USER_LIMIT 402 На пробном периоде превышен лимит серверов на пользователя
PLAN_NOT_ALLOWED_ON_TRIAL 402 Запрошенный план сервера/агента недоступен на пробном периоде
SERVER_WAKE_BLOCKED 403 Пробуждение сервера заблокировано по небиллинговой причине
B24_MARKET_SUBSCRIPTION_REQUIRED 403 На аккаунте нет активной подписки BitrixGPT + Маркетплейс. Приходит на привязке места встраивания и на установке приложения — в том числе на коробочном портале, где ключ выдаёт модуль-коннектор
B24_MARKET_TRIAL_USED 403 Пробный период подписки BitrixGPT + Маркетплейс уже использован — привязка места встраивания и установка приложения требуют платной подписки
INT_TARIFF_REQUIRED 403 Аккаунт работает по тарифной модели доступа, при этом как привязка места встраивания, так и установка приложения требуют коммерческого тарифа Битрикс24

Ограничение частоты

Код HTTP Когда возникает
RATE_LIMITED 429 Битрикс24 ограничил частоту запросов или превышен внутренний лимит. В ответе — retryAfter (секунды) и заголовок Retry-After
ERROR_LOOP_DETECTED 429 Блокировка на стороне Вайбкод: один и тот же запрос повторяется с одинаковой ошибкой. Сигнал о баге в коде клиента. Каждый N-й запрос пробрасывается дальше для проверки восстановления
OPERATION_TIME_LIMIT 429 Битрикс24 приостановил ЭТОТ метод для ВАШЕГО ключа примерно на 5 минут: метод исчерпал бюджет рабочего времени. В ответе scope: "apiKey", retryAfter и заголовок Retry-After. Остальные методы и другие ключи портала работают
TIMEOUT_QUARANTINE 429 Блокировка на стороне Вайбкод: метод несколько раз подряд не ответил порталу за отведённое вызову время, и пара «портал + метод» поставлена на паузу. В ответе scope: "portal", retryAfter и заголовок Retry-After. Пауза общая для ВСЕХ ключей портала и снимается автоматически

Backend и сторонние сервисы

Код HTTP Когда возникает
BITRIX_ERROR 422 Битрикс24 вернул бизнес-ошибку, не подпадающую под более узкие категории (ACCESS_DENIED, NOT_FOUND, INVALID_PARAMS)
AGGREGATION_LIMIT_EXCEEDED 422 Агрегация отказалась отвечать: выборка шире 5000 записей, оценённая стоимость вызова превысила безопасный бюджет, страница записей не догрузилась — либо (для дел без сужающего фильтра) Битрикс24 не ответил за отведённое на вызов время. message говорит, какой именно случай. Заголовка Retry-After нет: отказ не временный
METHOD_NOT_YET_AVAILABLE 422 Метод выходит в обновлении Битрикс24 и на этот портал ещё не приехал. Ответ содержит поле error.release с идентификатором обновления, например imopenlines 26.700.0. Это признак раскатки, а не ошибка вызова — подробнее
BITRIX_UNAVAILABLE 502 Битрикс24 вернул 5xx или не ответил вовремя
BIND_FAILED 502 Битрикс24 отклонил регистрацию события (event.bind) — например, портал не на коммерческом тарифе. См. Подписки на события портала
WINDOWED_SEARCH_FAILED Больше не возвращается: при полном отказе авто-окон /search возвращается реальный код Битрикс24 — UNKNOWN_FILTER_FIELD / INVALID_PARAMS / BITRIX_ACCESS_DENIED / RATE_LIMITED / BITRIX_UNAVAILABLE / BITRIX_TIMEOUT (503), как для узкого диапазона
QUEUE_OVERFLOW 429 Очередь портала переполнена: слишком много одновременных вызовов Битрикс24. Отклоняется мгновенно, Retry-After в заголовке
QUEUE_TIMEOUT 429 Очередь портала перегружена: больше 30 секунд ожидания на стороне Вайбкод. Запрос не был отправлен в Битрикс24 — безопасно повторить
BITRIX_TIMEOUT 503 Битрикс24 принял запрос, но не ответил за 15 секунд — исход неизвестен. Для write: сначала перечитайте сущность, изменение могло примениться
POOL_EXHAUSTED 503 Сервис временно перегружен — исчерпан пул соединений с базой данных. В ответе retryAfter и заголовок Retry-After, повторите через несколько секунд
DB_TRANSIENT 503 Транзакция в базе данных закрылась или истекла до того, как операция завершилась, — платформа откатила её целиком. Отказ временный: в ответе retryAfter и заголовок Retry-After, повторите через несколько секунд. Изменение не применилось ни частично, ни полностью
SERVICE_UNAVAILABLE 503 Граница платформы не смогла передать запрос бэкенду (например, в момент редеплоя) — либо не дождалась ответа. В ответе retryAfter и заголовок Retry-After. Если запрос мог быть выполнен (истёк таймаут ожидания ответа), для не-идемпотентных операций перед повтором сверьте состояние сущности
INTERNAL_ERROR 500 Непредвиденная ошибка backend Вайбкод
NETWORK_DEVKEY_REQUIRED 503 Ключ разработчика для автора приложения ещё не выдан — привязка места встраивания временно недоступна

Подробное описание

`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"
  }
}

Причины:

  • Опечатка или лишние пробелы в ключе.
  • Ключ удалён владельцем или администратором.
  • Ключ от другого окружения (staging/production).
  • Префикс не из числа поддерживаемых: vibe_api_, vibe_app_, vibe_live_, vibe_mgmt_.

Решение:

  • Сверить ключ в личном кабинете на странице /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 На портале нет активной подписки на Битрикс24 Маркет Активировать демо Маркета или оформить подписку, затем переподключить ключ
B24_MARKET_TRIAL_USED Демо Маркета уже использовано, платной подписки нет Оформить подписку на Маркет, затем переподключить ключ
INT_TARIFF_REQUIRED У портала нет платного тарифа Битрикс24 (регионы с тарифной моделью доступа) Подключить платный тариф, затем переподключить ключ
VIBE_SCOPES_ONLY Ключ не запрашивал ни одного скоупа Битрикс24 — вебхук ему не выдаётся by design Создать ключ с нужными скоупами Битрикс24
WEBHOOK_NOT_CONFIGURED Доступ Битрикс24 в порядке либо неизвестен, а вебхука на ключе нет Переподключить ключ. При details.hint — повторить проверку через GET /v1/me?refresh=tariff

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

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

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

Как посмотреть состояние ключа заранее: 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.
  • Скоуп ключа сужен на этапе создания.

Решение:

  • Открыть страницу ключа в личном кабинете и выпустить новый ключ с расширенным набором скоупов.
  • Полный список скоупов и их назначение — на странице Ключи и авторизация.

`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_). Набор скоупов, с которым ключ обращается к порталу, хранится на портале отдельно от набора у самого ключа. Перевыпустить ключ, переподключить его или создать новый с отмеченным скоупом — правка разрешений приложения на портале в этом случае ничего не меняет.
  • Ключ авторизации (vibe_app_). Создать приложение заново с нужным скоупом и пройти авторизацию заново. Перевыпуск ключа здесь скоуп не выдаёт.
  • Методы чатов и ботов. Для них того же отказа недостаточно объяснить скоупом: владелец ключа должен быть администратором портала. Выпустить ключ под учётной записью администратора — расширение скоупов тут не поможет.
  • Если дело в правах сотрудника, а не в скоупах ключа — проверить права пользователя в карточке сущности Битрикс24.

Полное описание того, как скоупы закрепляются за ключом и что делать, если после перевыпуска отказ повторяется, — Ключи и авторизация.


`WRITE_BLOCKED_READONLY_KEY` (403)

У ключа задан режим «только чтение» (accessMode: "READONLY"), а запрос выполняет запись. Полное описание режима, переключения и политики портала — Режим доступа.

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, в карточке нужного ключа в блоке Режим доступа выбрать «Чтение и запись» и сохранить. Режим применяется к следующему запросу, перевыпуск не нужен.
  • Если в карточке выбор переключателя недоступен — администратор портала ограничил режим. Запросить у администратора снятие ограничения для этого ключа.
  • При работе через AI-агента — действующий режим возвращает GET /v1/me в поле data.accessMode. Если запись нужна постоянно, выпустить отдельный ключ с режимом «чтение и запись».

`VALIDATION_ERROR` (400)

Тело или query-параметры не прошли проверку схемы. Для большинства V1-эндпоинтов обработка реализована через Zod, поэтому сообщение содержит конкретные поля с проблемами.

JSON
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "fields.title: Required; fields.stageId: Expected string, received number"
  }
}

Причины:

  • Отсутствуют обязательные поля.
  • Тип значения не соответствует схеме (строка вместо числа, неверный формат даты).
  • Отсутствует заголовок Content-Type: application/json. Тело, которое не разбирается как JSON, отклоняется отдельными кодами — INVALID_JSON_BODY, FST_ERR_CTP_INVALID_JSON_BODY или fst_err_ctp_invalid_json_body на маршрутах AI Router. Какой из них придёт, зависит от маршрута — см. таблицу выше.

Решение:

  • Сверить body со схемой эндпоинта в справочнике сущностей или на странице конкретного эндпоинта.
  • Числа передавать без кавычек, даты — в формате ISO 8601 (2026-04-29T10:00:00).
  • Добавить заголовок Content-Type: application/json.

`INVALID_PARAMS` (400)

Битрикс24 или route-handler нашёл некорректное значение параметра. Ошибки Битрикс24 формата INVALID_PARAMS: ... приходят под этим же кодом.

JSON
{
  "success": false,
  "error": {
    "code": "INVALID_PARAMS",
    "message": "Path parameter :id must be a positive integer"
  }
}

Причины:

  • Некорректное значение path-параметра (например, не число там, где ожидается число).
  • Битрикс24 отверг параметр запроса (например, неподходящее значение enum-поля).

Решение:

  • Проверить страницу эндпоинта: какие значения допустимы для каждого параметра.
  • Для filter использовать список полей из GET /v1/<entity>/fields.

`MISSING_REQUIRED_FILTER` (400)

Не передан обязательный фильтр на list-эндпоинте, который требует контекста.

JSON
{
  "success": false,
  "error": {
    "code": "MISSING_REQUIRED_FILTER",
    "message": "filter[entityType] and filter[entityId] are required for /v1/timelines"
  }
}

Причины:

  • Список тайм-лайн-записей требует пары родительских идентификаторов entityType + entityId.
  • Список товаров и разделов каталога требует iblockId, а список значений списочного свойства — propertyId.
  • Агрегация дел требует сужающего фильтра: пара ownerTypeId + ownerId, либо responsibleId, либо граница по дате на createdAt / updatedAt / deadline. Здесь требование не «все перечисленные», а «любое одно» — Битрикс24 не успевает посчитать все дела аккаунта за отведённое на вызов время. Требование включается платформой отдельно на каждый аккаунт. Проверить состояние — data.aggregateFilterRequirement.enforcement в ответе GET /v1/activities/fields.

Проверка выполняется до обращения к Битрикс24 и действует на GET /v1/{entity}, POST /v1/{entity}/search и POST /v1/{entity}/aggregate.

Решение:

  • Добавить обязательные параметры фильтра, перечисленные в message или на странице эндпоинта.

`BATCH_LIMIT_EXCEEDED` (400)

Запрос превышает лимит элементов в массивной операции. На уровне /v1/batch лимит проверяется через INVALID_REQUEST со ссылкой на Array must contain at most 50 element(s). На доменных bulk-эндпоинтах (например, chats, task-comments) — отдельный код BATCH_LIMIT_EXCEEDED.

JSON
{
  "success": false,
  "error": {
    "code": "BATCH_LIMIT_EXCEEDED",
    "message": "Maximum 50 dialogs per bulk request (Bitrix24 batch limit)."
  }
}

Причины:

  • В массиве больше 50 элементов.

Решение:

  • Разделить операцию на несколько запросов по 50 элементов.
  • Использовать batch-запросы для последовательных вызовов с одного ключа.

`ENTITY_NOT_FOUND` (404)

Запись CRM-сущности с указанным id не существует или была удалена.

JSON
{
  "success": false,
  "error": {
    "code": "ENTITY_NOT_FOUND",
    "message": "Элемент не найден"
  }
}

Причины:

  • Запись с таким id действительно не существует.
  • Запись была удалена параллельным процессом.
  • Перепутана сущность: запрос идёт на /v1/deals/:id, а ID — от лида.

Решение:

  • Проверить наличие записи через list-эндпоинт сущности.
  • Восстановить из корзины Битрикс24, если запись была удалена недавно (через интерфейс портала).

`RATE_LIMITED` (429)

Битрикс24 ограничил частоту запросов либо сработал внутренний лимит Вайбкод.

JSON
{
  "success": false,
  "error": {
    "code": "RATE_LIMITED",
    "message": "QUERY_LIMIT_EXCEEDED",
    "hint": "Wait 1-2 seconds and retry. Use POST /v1/batch to combine up to 50 calls in 1 request.",
    "retryAfter": 2
  }
}

Заголовки ответа:

Retry-After: 2

Причины:

  • Сложилось слишком много одновременных запросов от одного ключа: общий лимит платформы считается по API-ключу. Исключение — POST /v1/search, POST /v1/research и POST /v1/batch: там лимит считается на портал, и все его ключи делят один счётчик.
  • Превышен лимит запросов в секунду на стороне Битрикс24. Он считается на портал.

Решение:

  • Дождаться времени из error.retryAfter или заголовка Retry-After.
  • Реализовать повторные попытки с экспоненциальной задержкой.
  • Объединять до 50 вызовов через POST /v1/batch.
  • Кэшировать редко изменяемые справочные данные — поля, статусы, валюты.

`ERROR_LOOP_DETECTED` (429)

Вайбкод фиксирует серию одинаковых ошибок на одном ключе для одного метода Битрикс24 — и временно блокирует запрос на стороне Вайбкод, чтобы не накручивать счётчики Битрикс24. Каждый N-й запрос пробрасывается дальше: если backend восстановился, блокировка снимается автоматически.

JSON
{
  "success": false,
  "error": {
    "code": "ERROR_LOOP_DETECTED",
    "message": "Vibe-side block (not a Bitrix24 limit). 12 failures on crm.deal.list in the last hour.",
    "hint": "Every 50th request will probe for recovery — keep retrying with backoff. If you suspect a platform-side issue (e.g. 5xx during an outage), platform admin can clear the block via POST /api/platform/analytics/circuit-breaker/<apiKeyId>/clear.",
    "retryAfter": 60
  }
}

Причины:

  • В коде клиента баг: запрос с одинаковыми параметрами повторяется и стабильно даёт ошибку.
  • Платформенная авария на стороне Битрикс24 в момент серии запросов.

Решение:

  • Прочитать message — там указан конкретный метод с серией ошибок.
  • Найти источник запроса в коде, исправить параметры или логику.
  • При платформенной аварии — повторять с задержкой: каждый N-й запрос платформа пропускает для проверки восстановления, и блокировка снимается сама. Если она держится дольше самой аварии, обратитесь в поддержку.
  • Маршрут, названный в поле hint ответа, — служебный эндпоинт платформы. Своим ключом его не вызвать, и вмешательство не требуется: он адресован поддержке.

`BILLING_EXHAUSTED` (402)

Платёжный аккаунт ушёл в красную зону: баланс отрицательный, грейс-период исчерпан. Запросы на создание и пробуждение инфраструктуры блокируются до пополнения.

JSON
{
  "success": false,
  "error": {
    "code": "BILLING_EXHAUSTED",
    "message": "Account is frozen due to negative balance.",
    "userMessage": "Платёжный аккаунт заморожен из-за отрицательного баланса. Пополните счёт, чтобы продолжить работу с серверами и агентами.",
    "hint": "Top up the account at /billing/topup, then call POST /v1/portals/:id/refresh-tariff."
  }
}

Причины:

  • На балансе нет средств для оплаты часовой стоимости серверов и агентов.

Решение:

  • Пополнить баланс на странице /billing/topup.
  • После пополнения вызвать POST /v1/portals/:id/refresh-tariff для обновления статуса.

`COMMERCIAL_PLAN_REQUIRED` (402)

Создание серверов и агентов недоступно на бесплатном тарифе Битрикс24 после окончания пробного периода.

JSON
{
  "success": false,
  "error": {
    "code": "COMMERCIAL_PLAN_REQUIRED",
    "message": "Commercial Bitrix24 plan required for infrastructure operations.",
    "userMessage": "Создание инфраструктуры доступно на коммерческих тарифах Битрикс24. Пробный период уже использован.",
    "hint": "Upgrade plan at https://www.bitrix24.ru/prices/, then call POST /v1/portals/:id/refresh-tariff."
  }
}

Решение:

  • Обновить тариф Битрикс24 до коммерческого.
  • После обновления вызвать POST /v1/portals/:id/refresh-tariff либо GET /v1/me?refresh=tariff.

`TRIAL_EXPIRED` (402)

14-дневный пробный период завершился, тариф остался бесплатным.

JSON
{
  "success": false,
  "error": {
    "code": "TRIAL_EXPIRED",
    "message": "Trial period has ended.",
    "userMessage": "Пробный период (14 дней) завершён. Перейдите на коммерческий тариф Битрикс24, чтобы продолжить пользоваться серверами и агентами."
  }
}

Решение:

  • Перейти на коммерческий тариф Битрикс24.
  • Обновить статус через POST /v1/portals/:id/refresh-tariff.

Отказы по подписке и тарифу (403)

Три кода одного класса: доступ к операции закрыт условиями подписки или тарифа аккаунта, а не правами ключа. Приходят на установке приложения и на привязке места встраивания — в том числе на коробочном аккаунте, где ключ выдаёт модуль-коннектор.

Код Когда приходит error.details.upgradeUrl
B24_MARKET_SUBSCRIPTION_REQUIRED На аккаунте нет активной подписки BitrixGPT + Маркетплейс передаётся
B24_MARKET_TRIAL_USED Пробный период подписки уже использован — нужна платная передаётся
INT_TARIFF_REQUIRED Аккаунт получает доступ по тарифу Битрикс24, а не по подписке: нужен коммерческий тариф. Приходит вместо двух кодов выше, а также когда модель доступа аккаунта определить не удалось не передаётся
JSON
{
  "success": false,
  "error": {
    "code": "INT_TARIFF_REQUIRED",
    "message": "Paid Bitrix24 plan required (international region)",
    "userMessage": "Для доступа нужен платный тариф Битрикс24."
  }
}

Решение:

  • Отказ окончательный — повторять запрос бессмысленно. Пока условие доступа не изменилось на аккаунте, тот же вызов будет отклоняться.
  • Если пришёл error.details.upgradeUrl — это готовый адрес страницы оформления на самом аккаунте. Ведите пользователя по нему, а не собирайте адрес сами.
  • Если upgradeUrl не пришёл, на установке приложения и привязке места встраивания оформлять нечего: у аккаунта тарифная модель доступа, и нужен коммерческий тариф Битрикс24.
  • Различайте эти коды в клиенте по error.code, а не по тексту: у трёх отказов разные действия пользователя.

`BITRIX_ERROR` (422)

Битрикс24 вернул бизнес-ошибку, которая не подпадает под более узкие категории (ACCESS_DENIED, NOT_FOUND, INVALID_PARAMS, RATE_LIMITED).

JSON
{
  "success": false,
  "error": {
    "code": "BITRIX_ERROR",
    "message": "The requested period exceeds the maximum of 1 year",
    "b24Code": "PERIOD_TOO_LARGE"
  }
}

Причины:

  • Битрикс24 отверг операцию по бизнес-причине: несовместимое состояние, неподдерживаемое значение, бизнес-правило.
  • Запрос работает на портале, где соответствующий модуль отключён.

Решение:

  • Прочитать message — там оригинальный текст ошибки от Битрикс24.
  • При наличии hint — использовать его как первый шаг диагностики.
  • Для программной обработки читать поле error.b24Code — машиночитаемый код причины от Битрикс24, например BOT_TYPE_NOT_ALLOWED или PERIOD_TOO_LARGE. Ветвиться в коде по нему, а не по тексту message.
  • Поле error.b24Code приходит не всегда: когда Битрикс24 не прислал отдельный код, его в ответе нет.

`METHOD_NOT_YET_AVAILABLE` (422)

Метод выходит в обновлении Битрикс24, которое на этот портал ещё не приехало. Это признак раскатки, а не ошибка вызова: тот же запрос начнёт работать сам, как только обновление дойдёт до портала. На отдельных методах после этого добавляется своя проверка прав — она описана на странице метода.

JSON
{
  "success": false,
  "error": {
    "code": "METHOD_NOT_YET_AVAILABLE",
    "message": "Method \"imopenlines.v2.Stat.get\" is rolling out in update imopenlines 26.700.0 and is not yet available on this portal — this is not a call error.",
    "release": "imopenlines 26.700.0"
  }
}

Решение:

  • Ветвиться по error.code, а не по тексту message.
  • Поле error.release — идентификатор обновления целиком: имя модуля и номер версии одной строкой. Сравнивать его на равенство как строку, разбирать как номер версии нельзя.
  • Частые повторы ничего не меняют: состояние переключается приездом обновления на портал, а не повтором вызова. Заголовка Retry-After и поля retryAfter в этом отказе нет, потому что срока платформа не знает. Пока обновление не пришло, показывайте пользователю ожидание названной версии, а не ошибку интеграции.

`BITRIX_UNAVAILABLE` (502)

Битрикс24 вернул 5xx или не ответил в отведённое время.

JSON
{
  "success": false,
  "error": {
    "code": "BITRIX_UNAVAILABLE",
    "message": "Bitrix24 returned 503 Service Unavailable"
  }
}

Причины:

  • Технические работы или перегрузка на стороне Битрикс24.
  • Сетевые проблемы между Вайбкод и порталом.

Решение:

  • Повторить запрос через несколько минут, реализовав повторные попытки с экспоненциальной задержкой.
  • Для записывающих операций (POST/PATCH) — сначала проверьте, не применился ли исходный запрос. Медленный портал может обработать запись уже ПОСЛЕ того, как API вернул таймаут — слепой повтор создаст дубль (задачи, эпика, комментария). Перед ретраем сделайте GET по списку/записи (например, поиск по только что отправленному названию) и повторяйте только если записи нет.
  • Проверить статус портала по адресу /bitrix/admin/site_checker.php (для администратора портала).

`QUEUE_OVERFLOW` (429)

Очередь запросов к Битрикс24 для конкретного портала переполнена: слишком много вызовов уже в ожидании (по умолчанию — более 100). Ответ возвращается мгновенно, за миллисекунды, с HTTP-заголовком Retry-After: N (секунды).

JSON
{
  "success": false,
  "error": {
    "code": "QUEUE_OVERFLOW",
    "message": "Portal queue overloaded — 100 Bitrix24 calls already pending",
    "userMessage": "Слишком много одновременных запросов к Bitrix24 — повторите через несколько секунд.",
    "hint": "Honor the Retry-After header. Use exponential backoff with jitter for repeated failures.",
    "retryAfter": 10
  }
}

Решение:

  • Очередь портала переполнена — повторите запрос через Retry-After секунд, используя backoff с джиттером (случайной добавкой к паузе), чтобы повторы от разных клиентов не пришли одной волной.
  • Уменьшить параллелизм на стороне клиента.
  • Объединить вызовы через POST /v1/batch.

`QUEUE_TIMEOUT` (429)

Очередь запросов к Битрикс24 для конкретного портала перегружена: больше 30 секунд ожидания.

JSON
{
  "success": false,
  "error": {
    "code": "QUEUE_TIMEOUT",
    "message": "Portal queue saturated — too many concurrent Bitrix24 calls",
    "userMessage": "Запросы к Битрикс24 в очереди дольше 30 секунд. Вероятно, на портале много одновременных операций.",
    "hint": "If this is a /search request with a wide date range, try adding \"autoWindow\": false OR narrow the date range to <14 days. See /v1/guide for optimization tips.",
    "retryAfter": 10
  }
}

Запрос НЕ был отправлен в Битрикс24 — безопасно повторить.

Решение:

  • Повторить через retryAfter секунд, используя backoff с джиттером.
  • Уменьшить параллелизм.
  • Для /search-эндпоинтов — сузить диапазон дат либо передать autoWindow: false.
  • Объединить вызовы через POST /v1/batch.
  • Проверить таймаут на своей стороне: ожидание в очереди входит во время ответа, поэтому клиенту нужен запас — Клиентский таймаут.

`TIMEOUT_QUARANTINE` (429)

Метод несколько раз подряд не ответил вашему порталу Битрикс24 за отведённое вызову время, поэтому Вайбкод поставил пару «портал + метод» на паузу и больше не отправляет к ней запросы.

В процессе раскатки. Механизм включается на порталах постепенно. Пока он не включён на вашем, этот код не приходит: вызовы уходят в Битрикс24 как раньше и упираются в таймаут BITRIX_TIMEOUT.

JSON
{
  "success": false,
  "error": {
    "code": "TIMEOUT_QUARANTINE",
    "message": "Vibe-side block (not a Bitrix24 limit). crm.item.list timed out 5 times in a row on this portal, so calls to it are paused.",
    "hint": "Портал не отвечал на этот метод за отведённое вызову время, поэтому каждый следующий вызов только добавлял бы нагрузку. Дождитесь срока из Retry-After и НЕ сокращайте интервал повторов: агрессивный повтор занимает слот пробы восстановления и держит метод закрытым для всего портала дольше. Раз в 5 мин один вызов пропускается как проба, и первый успешный ответ снимает паузу немедленно. Облегчите запрос — меньше полей, меньше страница, более узкий фильтр: пару снимает с паузы именно лёгкий вызов.",
    "retryAfter": 288,
    "scope": "portal"
  }
}

Заголовки ответа:

Retry-After: 288

Причины:

  • Метод стабильно не отвечает порталу за отведённое вызову время — обычно из-за тяжёлого запроса: широкий диапазон дат, много полей в select, большая страница, фильтр по неиндексированному полю.
  • Пауза считается на пару «портал + метод» и не зависит от того, каким ключом сделан вызов: scope: "portal" означает, что её видят ВСЕ ключи портала, включая чужие интеграции. Контраст — OPERATION_TIME_LIMIT со scope: "apiKey": тот отказ про ваш ключ, этот — про весь портал.
  • Это отказ на стороне Вайбкод, а не лимит Битрикс24: запрос до портала не дошёл, поэтому ничего не изменилось — повтор безопасен даже для методов записи.
  • Код приходит и внутри 200-ответа — на подвызовах POST /v1/batch, которые Вайбкод исполняет отдельными запросами (data.errors[<id>]), и на элементах батча одной сущности (data[i].error). У 200-конверта нет заголовка Retry-After для отдельного подвызова, поэтому срок приходит полем retryAfter, а scope и hint — те же, что в одиночном 429.

Решение:

  • Дождаться срока из retryAfter (или заголовка Retry-After) и не сокращать интервал повторов: пока пауза действует, один вызов раз в 5 минут пропускается как проба восстановления, и агрессивный повтор занимает этот слот собой — метод остаётся закрытым для всего портала дольше, чем если бы вы просто подождали.
  • Добавлять к паузе случайную добавку (джиттер), чтобы повторы разных клиентов не пришли одной волной.
  • Облегчить сам вызов: меньше полей в select, меньше страница, более узкий фильтр или более узкий интервал дат. Пауза снимается первым успешным ответом, поэтому её снимает именно лёгкий вызов — тяжёлый снова упрётся в таймаут и продлит окно.
  • Не искать эндпоинт для снятия паузы — его нет, и вмешательство не требуется.
  • Сам конверт POST /v1/batch под паузу не попадает: он объединяет разные методы, и его собственная задержка не говорит о том, какие из них перестали отвечать.

`OPERATION_TIME_LIMIT` (429)

Битрикс24 приостановил ЭТОТ метод примерно на 5 минут, потому что метод исчерпал бюджет рабочего времени на портале. Отказ приходит и когда его прислал сам портал, и когда Вайбкод отбивает вызов на входе, зная, что пауза ещё действует.

JSON
{
  "success": false,
  "error": {
    "code": "OPERATION_TIME_LIMIT",
    "message": "Bitrix24 operation-time limiter banned crm.item.list on this portal, retry in 245s",
    "userMessage": "Битрикс24 приостановил этот запрос на несколько минут: метод исчерпал лимит рабочего времени на портале. Дождитесь срока из Retry-After — остальные методы работают.",
    "hint": "Bitrix24 banned THIS method on this portal for ~5 minutes because it exhausted the portal's operating-time budget. Honor Retry-After — the same call cannot succeed sooner and retrying earlier only adds load. Other methods on the portal are unaffected; spread heavy reads over time or narrow them (fewer fields, smaller pages, POST /v1/batch).",
    "retryAfter": 245,
    "scope": "apiKey"
  }
}

Заголовки ответа:

Retry-After: 245

Причины:

  • Метод израсходовал бюджет рабочего времени, который Битрикс24 считает на скользящем окне.
  • Пауза адресная: scope: "apiKey" означает, что Битрикс24 приостановил связку «ваш ключ + этот метод». Другие методы работают, и другие ключи портала тот же метод вызывать могут. Контраст — TIMEOUT_QUARANTINE со scope: "portal": там пауза общая для всего портала.
  • Запрос не был выполнен — повтор безопасен, в том числе для методов записи.
  • Код приходит и внутри 200-ответа — на подвызовах POST /v1/batch, которые Вайбкод исполняет отдельными запросами (data.errors[<id>]), и на элементах батча одной сущности (data[i].error). У 200-конверта нет заголовка Retry-After для отдельного подвызова, поэтому срок приходит полем retryAfter, а scope и hint — те же, что в одиночном 429. Поля userMessage в конверте нет.

Решение:

  • Дождаться срока из retryAfter (или заголовка Retry-After): раньше этого срока тот же вызов не пройдёт, а повторы только добавляют нагрузку.
  • Разнести тяжёлые чтения по времени, а не запускать их пачкой.
  • Облегчить вызовы: меньше полей в select, меньше страница, объединение через POST /v1/batch.

`BITRIX_TIMEOUT` (503)

Битрикс24 принял запрос, но не ответил за 15 секунд — исход неизвестен: запрос МОГ примениться на стороне портала.

JSON
{
  "success": false,
  "error": {
    "code": "BITRIX_TIMEOUT",
    "message": "Bitrix24 accepted the request but did not respond within 15s",
    "hint": "For WRITE operations, verify whether the change was applied (re-read the entity) before retrying. Reads are safe to retry.",
    "retryAfter": 10
  }
}

Решение:

  • Для чтения (GET//search) — повторить безопасно, после более длинного backoff, чем при 429.
  • Для записывающих операций (POST/PATCH) — сначала перечитайте сущность. Изменение могло уже примениться на стороне Битрикс24, несмотря на то, что ответ не пришёл. Слепой повтор создаст дубль (задачи, эпика, комментария). Проверьте наличие записи (например, поиск по только что отправленному названию) и повторяйте запись только если её нет.

`INTERNAL_ERROR` (500)

Непредвиденная ошибка на стороне API Вайбкод.

JSON
{
  "success": false,
  "error": {
    "code": "INTERNAL_ERROR",
    "message": "Internal server error"
  }
}

Решение:

  • Повторить запрос.
  • Если ошибка воспроизводится стабильно — отправить тикет через POST /v1/feedback с указанием времени запроса. Заголовок X-Request-Id из ответа ускоряет диагностику.

Повторы и backoff

Сводка по кодам, которые сигнализируют о временной проблеме и подразумевают повтор:

Код HTTP Стратегия повтора
RATE_LIMITED, QUEUE_OVERFLOW, QUEUE_TIMEOUT 429 Повтор через Retry-After + backoff с джиттером (случайной добавкой к паузе)
LARGE_BODY_BACKEND_BUSY 429 Повтор через Retry-After + джиттер. Запрос не выполнялся и состояние не менял — повтор безопасен и для записи
OPERATION_TIME_LIMIT 429 Повтор строго через Retry-After: раньше этого срока тот же вызов не пройдёт. scope: "apiKey" — пауза только на вызывающем ключе
TIMEOUT_QUARANTINE 429 Повтор через Retry-After + джиттер, и не сокращая интервал: агрессивный повтор занимает слот пробы восстановления и держит метод закрытым для всего портала дольше. scope: "portal" — пауза общая для всех ключей портала
BITRIX_TIMEOUT 503 Более длинный backoff, чем при 429. Для write-операций — сначала verify-before-retry: перечитайте сущность, изменение могло уже примениться
BITRIX_UNAVAILABLE 502 Повтор не поможет без изменения запроса — это 5xx самого Битрикс24 или сетевая проблема между Вайбкод и порталом, а не временная перегрузка очереди

Обработка ошибок в коде

JavaScript

javascript
async function vibeRequest(url, options = {}) {
  const response = await fetch(url, {
    ...options,
    headers: {
      'X-Api-Key': process.env.VIBE_API_KEY,
      'Content-Type': 'application/json',
      ...options.headers,
    },
  });

  const data = await response.json();

  if (!data.success) {
    const { code, message, retryAfter } = data.error;

    switch (code) {
      case 'RATE_LIMITED':
      case 'QUEUE_TIMEOUT': {
        const wait = retryAfter ?? Number(response.headers.get('Retry-After') ?? 1);
        await new Promise(r => setTimeout(r, wait * 1000));
        return vibeRequest(url, options);
      }

      case 'BITRIX_UNAVAILABLE':
        await new Promise(r => setTimeout(r, 5000));
        return vibeRequest(url, options);

      case 'MISSING_API_KEY':
      case 'INVALID_API_KEY':
        throw new Error('Проверьте API-ключ');

      default:
        throw new Error(`${code}: ${message}`);
    }
  }

  return data;
}

Python

Python
import os
import time
import requests

def vibe_request(url, method="GET", json_data=None):
    headers = {
        "X-Api-Key": os.environ["VIBE_API_KEY"],
        "Content-Type": "application/json",
    }

    response = requests.request(method, url, headers=headers, json=json_data)
    data = response.json()

    if not data.get("success"):
        err = data.get("error", {})
        code = err.get("code")
        message = err.get("message")
        retry_after = err.get("retryAfter") or int(response.headers.get("Retry-After", 1))

        if code in ("RATE_LIMITED", "QUEUE_TIMEOUT"):
            time.sleep(retry_after)
            return vibe_request(url, method, json_data)

        if code == "BITRIX_UNAVAILABLE":
            time.sleep(5)
            return vibe_request(url, method, json_data)

        raise Exception(f"{code}: {message}")

    return data

PHP

php
function vibeRequest(string $url, string $method = 'GET', ?array $data = null): array {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CUSTOMREQUEST => $method,
        CURLOPT_HTTPHEADER => [
            'X-Api-Key: ' . getenv('VIBE_API_KEY'),
            'Content-Type: application/json',
        ],
    ]);
    if ($data !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    }
    $body = json_decode(curl_exec($ch), true);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($body === null) {
        throw new Exception("HTTP error: $httpCode");
    }

    if (empty($body['success'])) {
        $errCode = $body['error']['code'] ?? 'UNKNOWN';
        $errMsg = $body['error']['message'] ?? 'Unknown error';
        $retryAfter = $body['error']['retryAfter'] ?? 1;

        if (in_array($errCode, ['RATE_LIMITED', 'QUEUE_TIMEOUT'], true)) {
            sleep((int) $retryAfter);
            return vibeRequest($url, $method, $data);
        }

        if ($errCode === 'BITRIX_UNAVAILABLE') {
            sleep(5);
            return vibeRequest($url, $method, $data);
        }

        throw new Exception("$errCode: $errMsg");
    }

    return $body;
}

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