# Изменения API: 13 сентября 2026

[← Журнал изменений](/docs/changelog) · [Сентябрь 2026](/docs/changelog/2026-09)

### FIX-0913-1: описание API называет отказы, общие для всех операций

**Было**

Машинное описание (`/v1/openapi.json`) не называло отказы, которые отдают не сами ручки, а общие слои платформы, — и клиент, собранный по описанию генератором, встречал их как неизвестный ответ.

Отказ по балансу `402 ACCOUNT_FROZEN` (счёт заморожен за долг) возможен на любой операции с ключом, кроме нескольких информационных и служебных, — а описан был у 22 операций из 842. Ответы `429 RATE_LIMITED` (Битрикс24 ограничил частоту), `429 ERROR_LOOP_DETECTED`, `429 QUEUE_OVERFLOW`, `429 QUEUE_TIMEOUT`, `429 OPERATION_TIME_LIMIT`, `429 TIMEOUT_QUARANTINE`, `502 BITRIX_UNAVAILABLE` (портал недоступен) и `503 BITRIX_TIMEOUT` (портал не ответил в срок) возможны на каждой операции, обращающейся к порталу, — `502 BITRIX_UNAVAILABLE` был описан у 11 операций, `503 BITRIX_TIMEOUT` у 4, остальные почти нигде. Операции шаблонов, роботов и действий бизнес-процессов (`/v1/bizproc-templates`, `/v1/bizproc-robots`, `/v1/bizproc-activities`) отвечают личному ключу `403 OAUTH_REQUIRED` — описание молчало; [GET /v1/triggers](/docs/automation/triggers/list) описывал только успех, тогда как личному ключу портал отвечает `403 BITRIX_ACCESS_DENIED`. Ответ `400 INVALID_PARAMS` на нечисловой номер записи в пути не был описан у чтения записи ни одной сущности с числовым номером (`GET /v1/tasks/{id}`, `GET /v1/workgroups/{id}` и остальных) и у большинства подчинённых ручек задач, скрама, таймлайна и журнала таймлайна.

**Стало**

Поведение ручек не менялось — исправлено описание. Успешные ответы по-прежнему те же `200`, `201` и `204`, что и были: меняется описание отказов, не ответ.

`402 ACCOUNT_FROZEN` описан ровно у тех операций, которые общий гейт заморозки может отбить: у всех операций с ключом, кроме `GET /v1/me`, `GET /v1/me/sources`, `GET /v1/guide`, четырёх вызовов переписки по обращению (`GET /v1/feedback`, `POST /v1/feedback`, `GET /v1/feedback/{id}`, `POST /v1/feedback/{id}/comments`) и `DELETE /v1/cowork/key`. В описании названо, что отказ приходит до любых проверок самой операции и всегда в общем конверте ответа (на OpenAI-совместимых операциях ИИ тоже), и что по мере раскатки сужения отказ останется только у операций, оплачиваемых кошельком, — успешный ответ на замороженном счёте не означает, что счёт в порядке (состояние — в `infraState` ответа [GET /v1/me](/docs/keys-auth/me)).

`429`, `502` и `503` с перечисленными выше кодами описаны у операций, обращающихся к порталу: у сгенерированных операций сущностей (список, чтение, создание, правка, удаление, поиск, пакет, импорт, агрегация, связи, товарные позиции, действия — кроме `GET /v1/{entity}/fields`, которая при отказе портала отвечает `200` со статическим набором полей и предупреждением `fields_partial`), у пакетного вызова `POST /v1/batch` (там свой набор: лимит Битрикс24 на самом конверте приходит не как `429`, а как `502 BITRIX_UNAVAILABLE` в штатной форме или `422 BITRIX_ERROR`, с кодом портала в `error.bitrixError.error`; `429` там — лимит пакетов и очередь) и у рукописных семей: подчинённые ручки задач, скрам, таймлайн, журнал таймлайна, рабочий день, звонки, бизнес-процессы (`/v1/workflows`), пользовательские поля CRM (`/v1/userfields`), история стадий, загрузка файлов, поиск дублей, `GET /v1/addresses/fields`, `POST /v1/doc-templates`. Там, где у операции уже был свой `429` (лимит чтений или пакетов, свой лимит ручки), свой `502` или `503`, прежний текст сохранён и дополнен. У каждой такой операции описан и `422 BITRIX_ERROR` — общий ответ на ошибку портала, не подпадающую под более узкий код.

У всех операций трёх сущностей бизнес-процессов описан `403 OAUTH_REQUIRED`; у записывающих — рядом с `WRITE_BLOCKED_READONLY_KEY`. [GET /v1/triggers](/docs/automation/triggers/list) и [POST /v1/triggers/fire](/docs/automation/triggers/fire) описывают `401`, `403` (`SCOPE_DENIED`, `BITRIX_ACCESS_DENIED`, у запуска — и `WRITE_BLOCKED_READONLY_KEY`), `422` и, у запуска, `400` (`MISSING_PARAMS`, `INVALID_ENTITY_TYPE`, `INVALID_ENTITY_TYPE_ID`).

`400 INVALID_PARAMS` на нечисловой номер записи описан у чтения, правки и удаления записи каждой сущности с числовым номером и у подчинённых ручек задач, скрама, таймлайна, журнала таймлайна, расшифровки звонка (`GET /v1/activities/{activityId}/transcript`), участников рабочей группы и конвертации лида. Свои коды того же отказа названы там, где ручка отвечает ими: `INVALID_DYNAMIC_PARAM` (все операции смарт-процессов по `{entityTypeId}`), `INVALID_ENTITY_TYPE_ID` (запись смарт-процесса, пользовательские поля смарт-процессов, конфигурация карточки CRM), `INVALID_ROW_ID` (товарная позиция), `INVALID_ANCHOR` (связи реквизитов), `VALIDATION_ERROR` (настраиваемые дела), `INVALID_ID` (фото сотрудника), `INVALID_BOT_ID` (передача бота), `UNKNOWN_ENTITY` (пользовательские поля CRM по `{entity}`).

Что описание ПО-ПРЕЖНЕМУ не называет — сознательно: отказ по суточной квоте вызовов (`429 QUOTA_EXCEEDED`) — общий для всего API и не входит в это изменение; у пакетных чтений, которые сообщают отказ портала внутри успешного ответа по каждому под-вызову (`POST /v1/mail/mailboxes/batch`, `POST /v1/tasks/{taskId}/comments/batch`), отказы портала на уровне ответа не описаны — их там нет.

Общие ответы вынесены в переиспользуемые компоненты описания `AccountFrozen`, `PortalRateLimited`, `PortalUnavailable`, `PortalTimeout` и `OauthAppKeyRequired`. Интерактивный справочник (`/docs` → API reference) перегенерирован из исправленного описания. Подробности по кодам — на странице [Ошибки](/docs/errors).

### NEW-0913-2: приложение Partner Connect запрашивает право vibe:ai само

`vibe:ai` теперь перечисляется в правах Connect-приложения при регистрации и правке — как любое право Битрикс24, без заявки и проверки. Дальше право идёт обычным путём: приложение передаёт его в параметре `scope` у `/v1/connect/authorize`, пользователь видит строку «AI-модели» на экране согласия и подтверждает набор целиком, и выданный ключ несёт это право. Вызовы AI-роутера таким ключом работают, расход покрывает месячный AI-лимит аккаунта.

Автоматически право не добавляется: приложение, которое его не запросило, работает как раньше, и у ранее выданных ключей набор прав не меняется. Остальные платформенные права — `vibe:search`, `vibe:infra`, `vibe:storage`, `vibe:feedback` — выдаёт платформенный администратор, и запрос с ними при саморегистрации отклоняется кодом `SCOPE_NOT_ALLOWED`. Документ `/.well-known/oauth-authorization-server` перечисляет `vibe:ai` в поле `scopes_supported`.

### FIX-0913-3: товарные позиции несуществующей записи отвечают «не найдено», как соседние методы

**Было**

[GET /v1/deals/{id}/products](/docs/entities/deals/products-get) по несуществующему `id` отвечал `403 BITRIX_ACCESS_DENIED` — так Битрикс24 отвечает на запрос товарных позиций у владельца, которого нет, и Вайбкод передавал этот ответ как есть. Соседние методы на тот же `id` — сама запись, её контакты, запись товарных позиций — отвечали `404 ENTITY_NOT_FOUND`. Клиент, получив «доступ запрещён», шёл проверять права вместо того, чтобы проверить `id`. То же у лидов, предложений, счетов и элементов смарт-процессов.

**Стало**

Получив от Битрикс24 отказ на чтение товарных позиций, Вайбкод один раз проверяет саму запись — тем же вызовом, что и `GET /v1/{entity}/{id}`. Записи нет — ответ `404 ENTITY_NOT_FOUND`, как у соседних методов. Запись есть, но закрыта правами сотрудника, — по-прежнему `403 BITRIX_ACCESS_DENIED`. Успешные запросы дополнительного вызова не делают. В OpenAPI у метода объявлен ответ `404`; страница счетов больше не описывает `403` как ответ на несуществующую запись.

**Затронутые эндпоинты:** [GET /v1/deals/{id}/products](/docs/entities/deals/products-get), [GET /v1/leads/{id}/products](/docs/entities/leads/products-get), [GET /v1/quotes/{id}/products](/docs/entities/quotes/products-get), [GET /v1/invoices/{id}/products](/docs/entities/invoices/products-get), [GET /v1/items/{entityTypeId}/{id}/products](/docs/entities/items/products-get).

### FIX-0913-4: заморозка счёта проверяется у ключа приложения и без сессии пользователя

**Было**

Ключ приложения (`vibe_app_*`), присланный без заголовка `Authorization: Bearer` с сессией пользователя, на заморозку счёта не проверялся: вызов шёл дальше, к собственным проверкам операции. На замороженном счёте такой ключ проходил в двери, которые оплачиваются балансом Вайбкод, — [создание приложения](/docs/apps/create) с парным ключом, загрузку и скачивание вложений обращений, [правку обращения](/docs/feedback/update), [поиск](/docs/search/run) и [глубокий поиск](/docs/search/research), список серверов — тогда как личный ключ и тот же ключ приложения с сессией получали `402 ACCOUNT_FROZEN`.

**Стало**

Заморозка — состояние счёта, а не сессии: на замороженном счёте ключ приложения без сессии отвечает `402 ACCOUNT_FROZEN` ровно там же, где личный ключ, — состав закрытых и открытых вызовов описан в разделе [«Что закрывает заморозка счёта»](/docs/errors). Открытые под заморозкой вызовы — самоописание, справочник, спека, переписка по обращениям — открыты и для такого ключа. На счёте без заморозки ответы не меняются: успешный ответ сохраняется.

**Влияние на интеграторов**

Клиент ничего не меняет. Если интеграция ходила ключом приложения без сессии и на замороженном счёте вдруг получила `402 ACCOUNT_FROZEN` — это не поломка ключа, а долг: пополните баланс, состояние счёта видно в блоке `infraState` ответа [`GET /v1/me`](/docs/keys-auth/me).

### FIX-0913-5: пакетный вызов отвечает 429 ERROR_LOOP_DETECTED, а не 500, когда платформа приостановила его после серии отказов

**Было**

Когда пакетные вызовы одного ключа раз за разом отклонялись порталом и платформа Вайбкод временно приостанавливала их (см. [ERROR_LOOP_DETECTED](/docs/errors/limits)), сам [POST /v1/batch](/docs/batch) отвечал `500 INTERNAL_ERROR` без заголовка `Retry-After` и без подсказки, — тогда как любая другая операция в том же состоянии отвечает `429 ERROR_LOOP_DETECTED`. Клиент читал внутреннюю ошибку платформы там, где действовал её же защитный механизм, и не знал, сколько ждать.

**Стало**

[POST /v1/batch](/docs/batch) отвечает `429 ERROR_LOOP_DETECTED` с заголовком `Retry-After`, а в `error.message` и `error.hint` — число отказов за последний час и с какой частотой пробные запросы пропускаются для проверки, что серия закончилась. Отдельные вызовы внутри пакета и раньше получали этот код в `data.errors.<id>` — изменился только ответ на весь пакет.

**Влияние на интеграторов**

Ничего менять не нужно. Обработчик, который на `429 ERROR_LOOP_DETECTED` выдерживает паузу из `Retry-After`, теперь срабатывает и на пакетном вызове. Если на `500` от пакетного вызова была настроена тревога — она перестанет срабатывать на этом состоянии.
