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

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

### BC-0926-1: ключ подписки Коворка у владельца без учётной записи Битрикс24 не ротируется, не включается заново и не продлевается

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

**Было**

Владелец ключа подписки Коворка, вошедший из портала без учётной записи Битрикс24, мог ротировать такой ключ (`POST /v1/keys/:id/rotate`), а также вернуть отозванный ключ в статус `ACTIVE` и удлинить или снять его `expiresAt` (`PATCH /v1/keys/:id`).

**Стало**

Ротация отвечает `403 COWORK_BOX_SERVICE_ACCOUNT_DENIED`. `PATCH /v1/keys/:id` отвечает тем же кодом только тогда, когда тело переводит ключ в `ACTIVE` из другого статуса либо удлиняет или снимает `expiresAt`. Остальные правки идут как раньше: переименование, отзыв ключа и сокращение срока по-прежнему успешны. Прежний ключ продолжает работать. Для владельцев с учётной записью Битрикс24 ничего не изменилось. Таблица кодов — [Управление ключами](/docs/management-keys).

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

Если вы ротируете ключ подписки Коворка или возвращаете его в работу — войти в кабинет учётной записью Битрикс24 и выпустить ключ от неё. Если вы ключи только переименовываете, отзываете или сокращаете им срок — менять ничего не нужно.

### NEW-0926-2: Прямые действия над задачей через API

Для 14 действий над задачей появились именованные маршруты `POST /v1/tasks/:taskId/{add-accomplices,add-auditors,approve,bind-crm-item,complete,defer,delegate,disapprove,pause,pause-timer,renew,start,start-timer,take}`. Каждый маршрут вызывает одноимённый метод Битрикс24 — `tasks.task.addAccomplices`, `tasks.task.addAuditors`, `tasks.task.approve`, `tasks.task.bindCrmItem`, `tasks.task.complete`, `tasks.task.defer`, `tasks.task.delegate`, `tasks.task.disapprove`, `tasks.task.pause`, `tasks.task.pauseTimer`, `tasks.task.renew`, `tasks.task.start`, `tasks.task.startTimer`, `tasks.task.take` — с теми же параметрами. `taskId` передаётся в пути, остальные именованные аргументы метода — в JSON-теле. Результат Битрикс24 возвращается в `data`. Ключ должен разрешать запись и иметь скоуп `task`.

**Маршруты и документация**

- [POST /v1/tasks/:taskId/add-accomplices](/docs/entities/tasks/add-accomplices)
- [POST /v1/tasks/:taskId/add-auditors](/docs/entities/tasks/add-auditors)
- [POST /v1/tasks/:taskId/approve](/docs/entities/tasks/approve)
- [POST /v1/tasks/:taskId/bind-crm-item](/docs/entities/tasks/bind-crm-item)
- [POST /v1/tasks/:taskId/complete](/docs/entities/tasks/complete)
- [POST /v1/tasks/:taskId/defer](/docs/entities/tasks/defer)
- [POST /v1/tasks/:taskId/delegate](/docs/entities/tasks/delegate)
- [POST /v1/tasks/:taskId/disapprove](/docs/entities/tasks/disapprove)
- [POST /v1/tasks/:taskId/pause](/docs/entities/tasks/pause)
- [POST /v1/tasks/:taskId/pause-timer](/docs/entities/tasks/pause-timer)
- [POST /v1/tasks/:taskId/renew](/docs/entities/tasks/renew)
- [POST /v1/tasks/:taskId/start](/docs/entities/tasks/start)
- [POST /v1/tasks/:taskId/start-timer](/docs/entities/tasks/start-timer)
- [POST /v1/tasks/:taskId/take](/docs/entities/tasks/take)

### FIX-0926-3: зацикленное рассуждение модели обрывается кодом reasoning_repetition

**Было**

Если модель с рассуждением начинала повторять в `reasoning_content` одни и те же фразы, поток `POST /v1/chat/completions` держался до срока обслуживания или до лимита `max_tokens`, а ответа так и не было. На запросе с `response_format` отказ приходил как `422 structured_output_truncated` с советом поднять `max_tokens` и полем `suggestedMaxTokens` — на зацикленной модели больший бюджет только удлинял повтор, и попытка оплачивалась ещё раз.

**Стало**

Повтор одних и тех же фраз в рассуждении до начала ответа останавливается, не дожидаясь срока обслуживания и лимита `max_tokens`, — и на основном потоке, и на потоке резервной модели при исчерпанной квоте. В потоке перед `data: [DONE]` приходит событие `{"error":{"code":"reasoning_repetition","type":"invalid_request_error"}}`, статус потока остаётся `200` по протоколу; синхронный запрос с `response_format` получает `422` с кодом `reasoning_repetition`, полями `finishReason` и `hint` и без `param` и `suggestedMaxTokens`. Выход — повторить запрос с `reasoning_effort: "none"`.

Обрывается только повтор одних и тех же фраз, а не перебор разных формулировок, и только в том, что приходит клиенту как `reasoning_content`: повторяющийся ответ в `content`, например массив одинаковых объектов, доходит целиком. Если модель присылает один и тот же текст сразу в оба канала, решает то, как он приходит клиенту: у модели с рассуждением этот текст приходит в `content` и доходит как ответ; если он приходит только как `reasoning_content`, его повтор обрывается так же, как рассуждение.

При `response_format: {"type": "json_object"}`, когда модель присылает сам ответ в `reasoning_content` как JSON-документ (начинается с `{` или `[`), готовый документ приходит в `content` ответом со статусом `200`; если документ так и не сложился, приходит `reasoning_repetition`, а если он слишком длинный, чтобы его восстановить, повтор обрывается сразу. Без `response_format` ответ, пришедший только в `reasoning_content`, при зацикливании обрывается `reasoning_repetition`. Обычный обрыв по `max_tokens` без повтора по-прежнему отвечает `structured_output_truncated`.

### FIX-0926-4: потоковый ответ чата всегда заканчивается причиной завершения

**Было**

Потоковый ответ [POST /v1/chat/completions](/docs/ai/chat/streaming) мог закончиться `data: [DONE]` без единого события с `finish_reason`. Так выглядели два разных случая: модель закончила ответ, но не прислала завершающего события, и соединение с моделью оборвалось посреди ответа. Клиент не мог отличить полный ответ от обрезанного, а часть клиентов не завершала ход без `finish_reason`.

**Стало**

Если модель закончила ответ без завершающего события, платформа сама добавляет перед `data: [DONE]` событие с пустым `delta` и `finish_reason: "tool_calls"`, когда в ответе были вызовы инструментов, или `finish_reason: "stop"` в остальных случаях. Если соединение оборвалось раньше, чем пришла причина завершения, перед `data: [DONE]` приходит событие ошибки с кодом `stream_incomplete`, `type: "server_error"`, `retryable: true` и `retryAfter`. Статус ответа по-прежнему `200`, как у остальных ошибок внутри потока.

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

Менять ничего не нужно. Клиент, который читает поток до конца и проверяет поле `error`, получит `stream_incomplete` тем же путём, что и `stream_idle_timeout`, и может повторить запрос с учётом `retryAfter`.
