# Изменения API: 14 октября 2026

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

### FIX-1014-1: Списки эпиков и спринтов соблюдают limit до 50

**Было**

[GET /v1/scrum/epics](/docs/scrum/epics/list) и [GET /v1/scrum/sprints](/docs/scrum/sprints/list) при `limit` от 1 до 50 возвращали всю первую страницу Битрикс24, до 50 записей. Например, запрос с `limit=2` мог вернуть 6 эпиков.

**Стало**

Оба метода возвращают не больше `limit` записей при любом значении от 1 до 1000, как обещает документация. Порядок записей не изменился.

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

Менять ничего не нужно. Если код опирался на то, что при малом `limit` приходит больше записей, передайте нужный `limit` явно — по умолчанию он равен 200.

### FIX-1014-2: защита от повторных ошибок сохраняет блок до успешного вызова

**Было**

Блокировка `ERROR_LOOP_DETECTED` сбрасывалась по истечении часа даже при активных повторах. Подсказка предлагала продолжать повторять запрос, а срок следующей попытки приходил только заголовком `Retry-After`.

**Стало**

Активные повторы сохраняют блокировку до первого успешного вызова. Проверочные вызовы требуют и установленного количества запросов, и паузы: 1, 5, 15, затем 60 минут после неудачных проб. `Retry-After` и `error.retryAfter` сообщают остаток паузы; если время уже истекло, но вызов ещё блокируется, — 60 секунд до повторной проверки. Подсказка предлагает исправить запрос; владелец ключа получает уведомление не чаще раза в сутки для одного метода. Локальные отказы без отправки в Битрикс24 не увеличивают паузу пробы. Радиус `scope` совпадает в одиночных и пакетных ответах об очереди, таймауте и авторизации ключа. Отказы `RATE_LIMITED` от Битрикс24 теперь содержат `scope: "portal"`, включая прежние методы чатов и чтение уведомлений без `format=v2`; это добавление поля в прежний контракт ошибок. Блок также снимается после длительного простоя.

### FIX-1014-3: выдача ключа в пустой слот ждёт другую операцию с приложением

**Было**

[POST /v1/cowork/applications/{id}/key](/docs/cowork/applications-key) на приложении без личного ключа выдавал ключ, даже если в тот же момент над этим приложением шла другая операция с его ключами или владельцем, например передача приложения другому человеку. Выданный ключ мог разойтись с итогом этой операции.

**Стало**

Пока над приложением идёт другая операция с его ключами или владельцем, выдача в пустой слот отвечает `409 APPLICATION_KEY_REPLACE_IN_PROGRESS` и ничего не выпускает — тот же отказ, который у метода уже описан. Замена уже выданного ключа под такой операцией работает как раньше, и вне таких операций успешный ответ `201` остаётся прежним.

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

Менять ничего не нужно: код `APPLICATION_KEY_REPLACE_IN_PROGRESS` и совет по нему у метода прежние, новых кодов не добавилось. Отказ теперь приходит и тогда, когда параллельная операция началась не через этот метод. Обрабатывайте его как штатный исход: подождите, прочитайте карточку приложения и посмотрите, нужен ли ещё ключ.

### FIX-1014-4: Владелец и организатор события группового календаря

**Было**

У события группового календаря `include=owner` мог возвращать карточку чужого сотрудника, так как `ownerId` содержит ID рабочей группы. Для события без встречи та же ошибка возникала при `include=host`: Битрикс24 передаёт ID рабочей группы в `meetingHost`.

**Стало**

Для любого события с `type=group` связь `_included.owner` возвращает `null`, в том числе для встреч. Связь `_included.host` возвращает `null`, если `isMeeting` не подтверждает встречу. Исходные значения `ownerId` и `meetingHost` сохраняются. Создатель события указан в `createdBy`.

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

При чтении группового события учитывайте `owner: null`, а без подтверждённой встречи также `host: null`. Для групповых встреч связь `host` работает как прежде. Личные и корпоративные события сохраняют обе связи, в том числе с `select`.

**Затронутые эндпоинты:** [GET /v1/calendar-events/{id}](/docs/entities/calendar-events/get), [GET /v1/calendar-events](/docs/entities/calendar-events/list), [POST /v1/calendar-events/search](/docs/entities/calendar-events/search).

### FIX-1014-5: Списки складских документов и позиций соблюдают withTotal=false

**Было**

При вызове [GET /v1/catalog-documents](/docs/entities/catalog-documents/list) или [GET /v1/catalog-document-elements](/docs/entities/catalog-document-elements/list) с `withTotal=false` ответ всё равно содержал `meta.total`.

**Стало**

При явном `withTotal=false` ключ `meta.total` отсутствует. Без параметра и с `withTotal=true` сохраняется прежнее поведение подсчёта.

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

Если интеграция запрашивала `withTotal=false`, ей больше не следует ожидать `meta.total` в ответе.

### FIX-1014-6: вход через Connect принимает адрес возврата на localhost у обоих типов клиента

**Было**

[GET /v1/connect/authorize](/docs/partner-connect) отклонял адрес возврата на localhost у конфиденциального клиента, хотя кабинет такой адрес сохранял: `http://localhost:3030/callback` давал `400 invalid_request`. Публичный клиент так же отклонялся на адресе `https://localhost`. Любой отказ по адресу возврата приходил с одним описанием `Redirect URI not registered`, даже если адрес был искажён или схема не подходила.

**Стало**

Адрес на `127.0.0.1`, `localhost` или `[::1]` по `http` или `https` принимается у обоих типов клиента. У публичного клиента порт такого адреса не сверяется, у конфиденциального адрес сверяется целиком, включая порт. Отказ по адресу возврата по-прежнему отвечает `400 invalid_request`, а `error_description` называет причину: `Redirect URI is malformed` для искажённого адреса, `Redirect URI scheme is not allowed for this host` для неподходящей схемы, `Redirect URI not registered` для незарегистрированного адреса. Адрес с логином или паролем в URL теперь всегда считается искажённым. Зарегистрировать такой адрес в кабинете нельзя.

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

Конфиденциальный клиент с сохранённым адресом на localhost начинает проходить вход без правки регистрации. Если приложение разбирает `error_description` как строку, учтите два новых текста. Если приложение передавало в `redirect_uri` логин или пароль, которых нет в зарегистрированном адресе, такой вход теперь отклоняется: передавайте адрес ровно в том виде, в каком он зарегистрирован.

### FIX-1014-7: Справочник учитывает запрет фильтрации в советах пагинации

**Было**

Карточки [секций календаря](/docs/entities/calendar-sections/list) и [событий календаря](/docs/entities/calendar-events/list) советовали продолжать обход фильтром по id, который эти методы отклоняют с `400 UNSUPPORTED_FILTER`.

**Стало**

Совет больше не предлагается сущностям с запретом фильтрации. Карточки прямо сообщают об отсутствии keyset-пагинации и гарантии стабильного обхода при параллельных изменениях. Ограничение offset у секций календаря остаётся описанным. Поведение методов не изменилось.

### NEW-1014-8: Результат чтения 1С файлом CSV или ZIP

Большую выборку 1С теперь может вернуть одним файлом, а не строками. Тогда в ответе [GET /v1/onec/operations/{operationId}](/docs/onec/operation) успешной операции вместо `columns`, `rows`, `truncated` и `nextOffset` приходит `result.file` с полями `url`, `contentType` (`text/csv` или `application/zip`), `sizeBytes` и `expiresAt`. Файл содержит всю выборку по фильтрам вызова: `limit` и `offset` к нему не применяются, следующей страницы нет. `url` — подписанная ссылка на скачивание без ключа API, она действует 15 минут, до `expiresAt`. Каждое чтение операции выпускает новую ссылку, пока результат хранится — 24 часа. Архив содержит один файл `data.csv`: UTF-8, первая строка — имена колонок, разделитель — запятая. Ответы со строками не изменились: файлом 1С отвечает только на большие выборки. Скачивайте файл по ссылке, если в результате есть `file`, и читайте `rows`, если его нет.

### FIX-1014-9: Отсутствующий метод больше не означает пропавшую запись

**Было**

При отказе Битрикс24 с кодом отсутствующего метода ответ V1 зависел от языка описания: русский текст мог давать `404 ENTITY_NOT_FOUND`, английский — `422 BITRIX_ERROR`.

**Стало**

Такой отказ возвращает `422 BITRIX_ERROR` с исходным кодом в `error.b24Code`. Специальные ответы `409` для недоступных модулей, `422 METHOD_NOT_YET_AVAILABLE`, ошибки временной недоступности и сроки повтора сохраняются.

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

Не считайте отказ из-за отсутствующего метода подтверждением отсутствия записи. Ответы о действительно отсутствующих записях и форма ошибок отдельных вызовов внутри пакета не изменились.

### NEW-1014-10: ссылки на подключение 1С и рецепты 1С в самоописании API

`GET /v1/guide` в блоке `onecApi.docs` возвращает новую ссылку `connect` — на страницу о подключении базы 1С к Битрикс24 и выдаче доступа сотрудникам. Блок по-прежнему приходит только ключу со скоупом `vibe:onec`. Карта рецептов `GET /v1/me` (`data.api.entityApi.docs.recipes`) и `GET /v1/guide` (`data.recipes.docs`) пополнилась двумя ключами: `onec-report-to-chat` — сводка из 1С в чат Битрикс24, и `onec-counterparties-to-crm` — контрагенты 1С в компаниях CRM. Остальные поля ответов не изменились.

### FIX-1014-11: Повтор в оборванном JSON не предлагает увеличить лимит

**Было**

При запросе [POST /v1/chat/completions](/docs/ai/chat/completions) с [JSON-ответом](/docs/ai/chat/json) модель могла повторять незавершённый JSON до лимита токенов. Ошибка `structured_output_truncated` предлагала увеличить `max_tokens` и тем самым продлить повтор.

**Стало**

Если в непустом незавершённом JSON после `finish_reason: "length"` обнаружен повтор, приходит `reasoning_repetition` с сообщением про JSON, без `param` и `suggestedMaxTokens`. В [потоке](/docs/ai/chat/streaming) это событие ошибки перед `data: [DONE]`.

**Влияние**

Эвристика может сработать и на ожидаемом повторяющемся массиве, которому не хватило бюджета: в этом случае больший лимит может помочь. Учёт завершённого запроса сохраняется и в sync, и в SSE. Проверка выполняется после генерации: ожидание до лимита сохраняется. Целый JSON и короткая обрезка без обнаруженного повтора сохраняют прежнее поведение. Успешный ответ остаётся успешным.

### FIX-1014-12: справочник полей товарной позиции больше не помечает productId обязательным

**Было**

Справочник полей товарной позиции отдавал `productId` с `isRequired: true`. При этом запись позицию без `productId` принимала: позиция создавалась с `productId` равным `0` и названием из `productName`.

**Стало**

У всех полей товарной позиции `isRequired` равен `false`, как и у записи: она принимает позицию, в которой есть хотя бы одно записываемое поле. Запись товарных позиций не изменилась.

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

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

Менять ничего не нужно. Форма, которая строит обязательность полей по этому справочнику, перестанет требовать `productId`. Если для вашей задачи позиция без товара из каталога недопустима, проверяйте `productId` на своей стороне.

### BC-1014-13: описание записи справочника CRM приходит в поле description вместо DESCRIPTION

> Поддержка старого формата до: не предусмотрена

**Было**

Записи справочника CRM в ответах [GET /v1/statuses](/docs/entities/statuses/list), [GET /v1/statuses/:id](/docs/entities/statuses/get) и [POST /v1/statuses](/docs/entities/statuses/create) несли описание записи под ключом `DESCRIPTION`, а [GET /v1/statuses/fields](/docs/entities/statuses/fields) показывал его отдельным полем `DESCRIPTION`. Значение `description`, переданное при создании или обновлении записи, не сохранялось.

**Стало**

Описание записи приходит под ключом `description` в тех же ответах и описано в справочнике полей как `description`. Ключа `DESCRIPTION` нет ни в ответах, ни в справочнике полей. Поле `description` принимается при создании и обновлении записи. Поле есть не на всех порталах Битрикс24. Фильтр по `description` не поддерживается и отвечает `400 UNSUPPORTED_FILTER`.

**Что делать интеграторам**

Читайте описание записи из `description` вместо `DESCRIPTION`. Чтобы записать описание, передавайте `description` в теле создания или обновления записи.

### BC-1014-14: PKCE проверяется и у клиента с секретом

> Поддержка старого формата до: не предусмотрена

**Было**

[GET /v1/connect/authorize](/docs/partner-connect) игнорировал `code_challenge` у клиента с секретом, если PKCE не был обязательным. Код можно было обменять без `code_verifier`.

**Стало**

Любой присланный `code_challenge` должен быть валидным и сопровождаться `code_challenge_method=S256`. Ошибка возвращается на проверенный адрес возврата с `error=invalid_request`. При обмене через `POST /v1/connect/token` требуется соответствующий `code_verifier` вместе с `client_secret`, иначе ответ — `400 invalid_grant`. Без `code_challenge` обмен с секретом работает как раньше.

**Что делать интеграторам**

Если передаёте `code_challenge`, сохраняйте исходный `code_verifier` до обмена кода и отправляйте его в `/v1/connect/token`. Используйте только `S256`.

### BC-1014-15: Фильтры по датам товаров, SKU и услуг каталога отклоняются

> Поддержка старого формата до: не предусмотрена

**Было**

Фильтры по `dateCreate`, `timestampX`, `dateActiveFrom` и `dateActiveTo` отвечали `200` со всем каталогом вместо выбранного диапазона.

**Стало**

[GET /v1/catalog-products](/docs/entities/catalog-products/list), [POST /v1/catalog-products/search](/docs/entities/catalog-products/search), [GET /v1/catalog-skus](/docs/entities/catalog-skus/list), [POST /v1/catalog-skus/search](/docs/entities/catalog-skus/search), [GET /v1/catalog-services](/docs/entities/catalog-services/list) и [POST /v1/catalog-services/search](/docs/entities/catalog-services/search) возвращают `400 UNKNOWN_FILTER_FIELD` при фильтре по этим датам. То же ограничение действует в [POST /v1/catalog-products/aggregate](/docs/entities/catalog-products/aggregate), [POST /v1/catalog-skus/aggregate](/docs/entities/catalog-skus/aggregate), [POST /v1/catalog-services/aggregate](/docs/entities/catalog-services/aggregate) и в прежних `GET /v1/catalog-products/aggregate`, `GET /v1/catalog-skus/aggregate`, `GET /v1/catalog-services/aggregate`. В списочном подвызове этих трёх сущностей в [POST /v1/{entity}/batch](/docs/batch) и [POST /v1/batch](/docs/batch) тот же код приходит в поле ошибки своего подвызова, остальные подвызовы выполняются. Сами даты остаются доступны в ответах и `select`.

**Что делать интеграторам**

Удалите эти даты из `filter` на всех перечисленных маршрутах, включая списочные подвызовы batch. Используйте поддерживаемые поля, например `id`, либо фильтруйте прочитанные записи по датам в своей интеграции с учётом всех страниц.

### FIX-1014-16: ключ ИИ, подключённый администратором для всего портала, работает у участников портала

**Было**

Администратор портала подключал в кабинете Вайбкод ключ провайдера с отметкой «Доступен всем пользователям портала». Участник портала видел этот ключ в списке своих ключей, но моделей провайдера не было в списке моделей, а запрос к модели отвечал `402 ai_credentials_not_configured`.

**Стало**

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

**Затронутые эндпоинты:** [GET /v1/models](/docs/ai/models/list), [POST /v1/chat/completions](/docs/ai/chat/completions).

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

Менять ничего не нужно. Приложение, которое получало `402 ai_credentials_not_configured` на портале с подключённым ключом портала, получит ответ модели.
