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

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

### NEW-0903-1: `GET /v1/models` отдаёт декларацию управления рассуждением

У каждой модели в `GET /v1/models` и `GET /v1/models/{model}` появилось поле `reasoning`: `null`, если декларация не задана, иначе объект `{ map, default, budgetTokens }` — `map` переводит ступень платформы (`none|low|medium|high|max`) в родной режим модели, `default` называет ступень, которую модель применяет без параметра рассуждения, `budgetTokens` — поддержка бюджета токенов рассуждения. Поле аддитивное: форма `capabilities` не менялась, прежние запросы работают как раньше. Подробнее — `/docs/ai/models/list`.

### NEW-0903-2: управление рассуждением модели в чат-комплишенах

`POST /v1/chat/completions` принимает `reasoning_effort`, `reasoning` и `chat_template_kwargs`, нормализует их в пять ступеней платформы Вайбкод (`none`, `low`, `medium`, `high`, `max`) и применяет ближайшую поддерживаемую моделью ступень — округляя вниз и никогда не выключая рассуждение без явной просьбы. Ответ несёт поле `reasoning` (`requested`, `applied`, `native`), предупреждения `REASONING_EFFORT_ADJUSTED`, `REASONING_NOT_SUPPORTED`, `REASONING_CANNOT_BE_DISABLED`, `REASONING_BUDGET_NOT_SUPPORTED`, `TEMPERATURE_OVERRIDDEN_BY_REASONING` в `warnings` и заголовки `X-Reasoning-Applied`, `X-Reasoning-Native`, `X-Reasoning-Warnings` — в потоковом режиме заголовки единственный канал. Без параметра в запросе тело, уходящее в модель, остаётся прежним, а поведение модели не меняется. Токены рассуждения тарифицируются как выходные по той же ставке. Подробнее — `/docs/ai/chat/completions`.

### FIX-0903-3: некорректное значение параметров рассуждения отклоняется

**Было**

Неизвестные поля `reasoning_effort`, `reasoning`, `chat_template_kwargs` молча отбрасывались, и запрос с опечаткой в значении выполнялся как будто параметра не было — ответ был HTTP 200.

**Стало**

Значение вне словаря (`none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`), неположительный `reasoning.max_tokens` или `chat_template_kwargs` не-объект отклоняются кодом `400 invalid_request` в OpenAI-конверте `{ "error": { "message", "type", "code" } }`; явный `null` в любом из трёх полей принимается как «не задано»; для корректного запроса ответ остаётся HTTP 200.

### FIX-0903-4: GET /v1/me перестал объявлять region обязательным

**Было**

В ответе [GET /v1/me](/docs/keys-auth/me) описание создания сервера без `source` помечало `region` обязательным и включало его в список обязательных полей. Из-за этого клиенты, использующие self-discovery, могли требовать регион, хотя контракт создания сервера уже разрешал его не передавать.

**Стало**

[GET /v1/me](/docs/keys-auth/me) помечает `region` необязательным и объясняет, что при его отсутствии платформа использует регион по умолчанию выбранного провайдера. Изменилось только self-discovery: `GET /v1/me` остаётся HTTP 200, а существующее поведение [POST /v1/infra/servers](/docs/infra/servers/create) без `region` и его ответ HTTP 201 не изменились.

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

Клиенты, которые строят запрос по данным `GET /v1/me`, могут перестать считать `region` обязательным. Рабочие запросы с явно переданным регионом менять не нужно.

### FIX-0903-5: прямые BOX-вызовы учитывают доверие к сертификату

**Было**

На BOX-портале с доверенным самоподписанным сертификатом оконный поиск, скачивание файлов и отдельные операции с ключами могли завершаться ошибкой TLS, хотя обычные API-вызовы работали.

**Стало**

Все эти вызовы используют настройку доверия только для точного адреса BOX-портала. Облачные и OAuth-вызовы, а также переходы скачивания на внешний адрес сохраняют строгую проверку сертификата.

### BC-0903-6: ключ приложения без сессии сотрудника читает по имени только общие файлы

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

**Было**

Запрос `GET /v1/storage/objects/{key}` ключом приложения без заголовка `Authorization` возвращал файл
сотрудника, если под этим логическим именем существовал ровно один объект. Это работало лишь потому,
что имя было одно на приложение, и рассчитывать на такое поведение было нельзя: как только объектов
под именем становилось больше одного, выбор становился произвольным.

**Стало**

Такой запрос читает только общий файл приложения — с релиза, переходного режима нет. Если под этим именем есть лишь персональные файлы
сотрудников, ответ — `404 STORAGE_OBJECT_NOT_FOUND`. То же сужение действует на `HEAD` и на удаление
по имени. Листинг `GET /v1/storage/objects` состав ответа не меняет.

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

Если вы читали или удаляли файл сотрудника ключом приложения без его сессии, передайте сессию
сотрудника в заголовке `Authorization: Bearer` — тогда доступен его файл. Маршрута
`GET /v1/storage/objects/{objectId}`, который эта запись советовала раньше, в API нет: файл читается
только по ключу. Публичный файл сотрудника открывается и по ссылке
`GET /v1/public-storage/{portalId}/{objectId}`, если на портале включён анонимный доступ.

### FIX-0903-7: сотрудники одного приложения сохраняют файлы под одним именем

**Было**

Логическое имя файла было одно на приложение. Если сотрудник портала сохранял `avatar.png`, второй
сотрудник того же приложения получал `409 STORAGE_KEY_OWNED_ELSEWHERE` на прямой загрузке и
`409 STORAGE_KEY_EXISTS` на составной — хотя файлы легли бы по разным адресам, потому что в адрес
персонального файла входит идентификатор сотрудника. Отказ не истекал: имя оставалось занятым, пока
первый сотрудник не удалит файл.

**Стало**

Имя занимается отдельно для каждого сотрудника. Второй сотрудник получает `200` и свой объект с
собственным идентификатором; повторная загрузка тем же сотрудником по-прежнему заменяет его
собственный файл. Общий файл приложения и персональный файл сотрудника делят одно пространство имён,
поэтому запрос, заставший имя уже занятым объектом другого типа владения, по-прежнему получает
`409 STORAGE_KEY_OWNED_ELSEWHERE`.

### FIX-0903-8: составная загрузка различает, кто занял логическое имя

**Было**

`POST /v1/storage/objects/multipart/create` на занятое логическое имя отвечал `409 STORAGE_KEY_EXISTS` независимо от того, кто это имя держит, — и когда объект принадлежал вам, и когда речь шла об объекте другого типа владения: общий файл приложения против персонального файла сотрудника. Различить эти случаи по ответу было нельзя, хотя действия для их разрешения разные.

**Стало**

Когда имя держит объект другого типа владения, составная загрузка отвечает `409 STORAGE_KEY_OWNED_ELSEWHERE` — так же, как давно отвечает прямая загрузка. Остальные случаи занятого имени по-прежнему отвечают `409 STORAGE_KEY_EXISTS`, статус ответа во всех случаях прежний.

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

Действий не требуется: отказ остаётся отказом с тем же статусом `409`, меняется только код в теле. Если ваш клиент ветвится на конкретном коде составной загрузки, добавьте ветку для `STORAGE_KEY_OWNED_ELSEWHERE` — она означает, что имя занято объектом другого типа владения, и освободить его сменой сотрудника нельзя.

### BC-0903-9: история стадий смарт-процессов по числовому entityTypeId, параметры запроса стали строгими

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

**Было**

`GET /v1/stage-history` принимал только четыре именованных типа — `deal`, `lead`, `invoice` и
`new-invoice`. У смарт-процесса имени нет, поэтому запросить его историю стадий было нельзя:
`?entityType=128` отвечал `400 INVALID_ENTITY_TYPE`, не обращаясь к Битрикс24.

Соседние параметры (`ownerId`, `typeId`, `categoryId`, `limit`, `offset`, `createdAfter`,
`createdBefore`, `stageId`, `stageSemanticId`, `statusId`, `statusSemanticId`) при этом
принимались в формах, которые отвечали УСПЕХОМ:

`?entityType=deal&ownerId[]=5` возвращал `200` и историю владельца `5`, как если бы значение
пришло скаляром. Повтор `?entityType=deal&ownerId=5&ownerId=6` возвращал `200`, молча взяв
последнее значение. Повтор с одинаковыми значениями `?entityType=deal&limit=50&limit=50`
возвращал `200` и корректную выборку.

**Стало**

`entityType` принимает числовой `entityTypeId` смарт-процесса — `?entityType=128`. Идентификатор
возвращает `GET /v1/smart-processes`. Смарт-процессы stage-based, как сделки: доступны `stageId`,
`stageSemanticId` и `categoryId`, а ответ несёт те же поля.

Числовой идентификатор, у которого есть именованный ключ (`1`, `2`, `31`), отклоняется с подсказкой
на этот ключ. У контакта (`3`), компании (`4`), предложения (`7`) и старого счёта (`5`) истории
стадий нет — они тоже отклоняются. Идентификатор, которого нет на портале, возвращает
`400 INVALID_ENTITY_TYPE`, а не ошибку Битрикс24.

Каждый параметр из списка выше принимается ровно ОДИН раз и только одним строковым значением. Все
три формы из блока «Было» теперь отвечают `400 INVALID_PARAMS` — и скобочные (`?ownerId[]=5`,
`?ownerId[x]=1`), и плоский повтор (`?ownerId=5&ownerId=6`), в том числе когда повторённые значения
совпадают, и смесь написаний (`?ownerId[]=6&ownerId=5`) — последняя отвечала `200`, оставляя от
запроса только `5`. Скобочная форма `?ownerId[x]=1` до этого отвечала `500`.

Числовые параметры (`ownerId`, `typeId`, `categoryId`, `limit`, `offset`) вдобавок принимаются
только целым числом, записанным полностью: без знака, экспоненты, ведущих нулей и хвоста.
`?ownerId=1e3` возвращал `200` и историю владельца `1` вместо `1000`, `?typeId=2abc` — историю типа
`2`, а `?ownerId=abc` вообще терял ограничение по владельцу и отдавал выборку ШИРЕ запрошенной.
Теперь все три — `400 INVALID_PARAMS`.

Ужесточены и формы самого `entityType`: `entityType[]=` и `entityType[x]=` возвращали `500` вместо
`400`; повторённый `entityType=a&entityType=b` молча брал последнее значение, а теперь отклоняется;
`entityType=constructor` и `entityType=__proto__` отвечали `200` с пустым результатом вместо отказа.
Текст ошибки `INVALID_ENTITY_TYPE` теперь называет и числовую форму, а не только четыре имени.

Тот же класс закрыт в `POST /v1/duplicates/find` и `POST /v1/triggers/fire`: тело с нестроковым
`type` или `entityType` — числом, объектом или массивом — возвращало `500` вместо документированного
`400`. В `triggers/fire` то же сделано для `entityId` и `triggerId`: объект в этих полях раньше либо ронял
запрос в `500`, либо уезжал в Битрикс24 бессмысленным значением и отвечал `200`, ничего не запустив.
Массив из НЕСКОЛЬКИХ значений в `entityId` уходил в Битрикс24 склеенным в одну строку, ни одной
записи не адресовал и триггер не запускал, — теперь это `400`. Массив из ОДНОГО значения работал
(`[5]` читался как `5`, и триггер срабатывал) и работать не перестал. Числа в обоих полях принимаются как и раньше и уходят в Битрикс24 без изменений —
числовой `triggerId`, который работал, работать не перестал. Нестроковый `entityType` в поиске дубликатов теперь отклоняется, а не игнорируется. Оба
маршрута отвечают `400` и на запрос вовсе без тела и без заголовка `Content-Type` — раньше такой
запрос давал `500`.

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

Передавайте каждый параметр строки запроса один раз и скалярным значением: `?ownerId=5` вместо
`?ownerId[]=5` и вместо повтора `?ownerId=5&ownerId=6`. Если фильтр собирается в цикле, проверьте,
что ключ не добавляется в строку запроса дважды — раньше лишний повтор проходил незаметно, теперь
он даёт `400 INVALID_PARAMS` с именем параметра в тексте ошибки.

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

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

### FIX-0903-10: один запрос больше не ставит метод Битрикс24 на паузу своими подвызовами

**Было**

Если один запрос к пакетным и циклическим методам API Вайбкод несколько раз подряд получал таймаут от одного метода Битрикс24, он мог сам включить для этого метода 15-минутную паузу. Оставшиеся подвызовы возвращали `TIMEOUT_QUARANTINE`, а пауза затрагивала другие запросы того же портала.

**Стало**

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

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

Менять клиентский код не требуется. Исправлены [POST /v1/batch](/docs/batch), [POST /v1/{entity}/batch](/docs/batch), [GET /v1/tasks/:taskId/comments](/docs/entities/task-comments/list), [POST /v1/tasks/:taskId/comments](/docs/entities/task-comments/create), [POST /v1/tasks/:taskId/comments/batch](/docs/entities/task-comments/comments-batch), [GET /v1/task-time](/docs/entities/tasks/time/global-list) и [GET /v1/timeline-logs](/docs/timeline-logs/logs/list).

### BC-0903-11: на обновлении отклоняется фотография, из которой не собрать файл

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

**Было**

При обновлении сотрудника значение `personalPhoto`, из которого Битрикс24 не может собрать файл, доезжало до портала как команда снять текущую фотографию. Так вели себя литерал `false`, логические `true` и `false`, число `0`, строка, в которой меньше двух символов алфавита base64 — например `!!!` или `===`, — inline-пара `[имя файла, base64]`, содержимое которой одно из перечисленного, и любая другая структура, у которой второго значения нет, оно `null` или нечитаемо, включая вложенную `{fileData: [...]}`, явный `null` и структуру на месте содержимого. Вызов отвечал успехом уже после удаления, а прежний отказ покрывал только пустую строку и строку из пробельных символов.

**Стало**

Такие значения отклоняются с `INVALID_PARAMS` до вызова Битрикс24 на всех трёх поверхностях обновления, как и пустая строка. Значение с двумя и более символами base64 по-прежнему уходит на портал: из него получается файл, и решение о пригодности принимает сам Битрикс24. На CREATE в `POST /v1/users` новый отказ не действует.

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

Не подставляйте в `personalPhoto` заглушки вроде `false`, `0`, `true` или пустых строк, чтобы «ничего не менять» — просто не передавайте поле. Чтобы снять фотографию, вызовите [DELETE /v1/users/:id/personal-photo](/docs/entities/users/photo-delete).

### NEW-0903-12: появилась команда удаления фотографии сотрудника

У фотографии сотрудника появилась отдельная команда удаления — [DELETE /v1/users/:id/personal-photo](/docs/entities/users/photo-delete). Она снимает фотографию профиля и отвечает `200` с полями `id`, `personalPhoto: null` и `removed: true`. Вызов идемпотентен: у сотрудника без фотографии он тоже успешен. Операция необратима, Битрикс24 удаляет сам файл, поэтому повторная загрузка того же изображения даст новый URL. Нужен скоуп `user`, ключ только для чтения команду не выполняет, а решение о правах принимает Битрикс24 — при отказе приходит `403 UPDATE_FAILED` и фотография остаётся на месте.

Записью в поле `personalPhoto` фотографию снять нельзя ни на одной поверхности обновления, и `null` для этого тоже не подходит. На [PATCH /v1/users/:id](/docs/entities/users/update) и в пакете по одной сущности `null` принимается и игнорируется, а на общем [POST /v1/batch](/docs/batch) отклоняется с `INVALID_PARAMS`, потому что кодировщик подзапроса превратил бы его в пустое значение строки запроса — ту же команду снять фотографию. Это различие поверхностей теперь описано в документации намеренно, поведение вызовов не менялось. Чтобы заменить фотографию, отдельное удаление не нужно: отправьте пару `[имя файла, base64]` в `personalPhoto` на [POST /v1/users](/docs/entities/users/create) или [PATCH /v1/users/:id](/docs/entities/users/update).

### BC-0903-13: создание действий и роботов бизнес-процессов возвращает строковый код

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

**Было**

[POST /v1/bizproc-activities](/docs/entities/bizproc-activities/create) и [POST /v1/bizproc-robots](/docs/entities/bizproc-robots/create) отвечали HTTP 201 с булевым `data.id: true`. Это значение нельзя было использовать как `code` в PATCH или DELETE.

**Стало**

Те же запросы по-прежнему отвечают HTTP 201. При обычном ответе Битрикс24 `true` поле `data.id` содержит строковый `code`, переданный при создании; если Битрикс24 явно вернул `CODE`, используется это значение. Идентификатор подходит для последующих PATCH и DELETE.

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

Измените тип `data.id` в обработчиках этих двух ответов с boolean на string и используйте полученное значение как `code` для обновления или удаления.

### BC-0903-14: повторная загрузка личным ключом отвечает отказом там, где состояние объекта его требует

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

**Было**

Повтор на занятый `key` с личным ключом разработчика или в серверном контексте всегда отвечал
HTTP 200 и создавал вторую строку, поэтому проверки состояния объекта до него просто не доходили.

**Стало**

Повтор проходит тот же разбор состояний, что и ключ приложения, и три ситуации отвечают отказом.
Другое значение `visibility` при повторе — `400 STORAGE_VISIBILITY_MISMATCH`: поле не передавайте
либо передайте сохранённое значение, оно указано в сообщении. Составная загрузка (путь C) на
занятый адрес — `409 STORAGE_KEY_EXISTS` до создания сессии. Тело без `Content-Length` на занятый
адрес — `409 STORAGE_REPLACE_REQUIRES_LENGTH`. Дополнительно становятся достижимыми
`409 STORAGE_UPLOAD_PENDING` и `409 STORAGE_MULTIPART_IN_PROGRESS` — раньше для этих ключей они не
срабатывали никогда.

### FIX-0903-15: повторная загрузка личным ключом заменяет файл, а не создаёт второй объект

**Было**

Личный ключ разработчика и серверный контекст на повторной загрузке того же `key` создавали ВТОРОЙ
объект по тому же физическому адресу. Байты первого объекта перезаписывались вторым, размер
считался дважды, а чтение и удаление по логическому имени могли попасть в любую из строк. Гейт
опасных типов для `PUBLIC`-объектов при этом считался по заявленной видимости, поэтому `text/html`
проходил под живой публичный объект.

**Стало**

Повтор заменяет содержимое существующего объекта: сохраняются `object.id`, `createdAt`, `key`,
физический адрес и `visibility`, обновляются `sizeBytes`, `sha256`, `contentType` и
`contentUpdatedAt`. Ответ остаётся HTTP 200. Подходящий мягко удалённый объект оживляется так же,
как у ключа приложения. Гейт опасных типов считается по видимости найденной строки — до записи
байт, поэтому `text/html` под живой `PUBLIC`-объект больше не проходит.

### FIX-0903-16: выкладка Node.js 20 не зависит от репозитория пакетов при готовом образе

**Было**

Шаг подготовки Node.js 20 всегда обращался к внешнему репозиторию системных пакетов, даже если все базовые пакеты уже были установлены. При недоступном репозитории шаг долго оставался без обновлений, а затем завершался ошибкой.

**Стало**

Готовый образ с базовыми пакетами не обращается к репозиторию. Если пакет всё же требуется, сетевое ожидание ограничено; потоковый ответ во время долгой подготовки периодически передаёт прошедшее время. Формат итогового ответа и статус успеха не изменились.

### BC-0903-17: сортировка валют отвергает поле, по которому Битрикс24 не сортирует

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

**Было**

[GET /v1/currencies](/docs/entities/currencies/list) и [POST /v1/currencies/search](/docs/entities/currencies/search) принимали в `sort` и `order` любое имя поля. Метод Битрикс24 `crm.currency.list` молча подменяет неизвестный ключ сортировкой по умолчанию, поэтому ответ приходил `200` со списком в произвольном для клиента порядке и без признака ошибки. То же касалось ключей `sort` и `order` у подвызова `entity=currencies` в [POST /v1/batch](/docs/batch).

**Стало**

Принимаются три поля: `sort`, `id` и `fullName`. Любое другое имя — как несуществующее `bogus`, так и объявленное `amount` — возвращает `400 UNKNOWN_SORT_FIELD` до вызова Битрикс24, и сообщение перечисляет допустимые имена. Документированный `?order[sort]=asc` не меняется.

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

Три класса изменений, каждый требует своей проверки.

Первое: запрос с неизвестным именем поля вместо `200` получает `400`. Если код полагался на то, что такой запрос «просто работает», он теперь увидит ошибку — это и есть исправление, но обработать её нужно.

Второе: поля `amount`, `amountCnt`, `base`, `formatString`, `decimals`, `decPoint`, `thousandsSep`, `lid`, `dateUpdate` и `lang` тоже отвечают `400`. Сортировки по ним никогда не было: ядро подменяло её порядком по умолчанию, то есть успешный ответ был неправдой.

Третье, самое тихое: `?sort=id` и `?sort=fullName` теперь **действительно** меняют порядок строк, оставаясь `200`. Раньше оба молча сортировались по умолчанию. Постраничный обход по этим полям через `offset` вернёт другие страницы, чем до обновления, и признака в статусе ответа нет — перепроверьте такие обходы.

Затронутые эндпоинты: [GET /v1/currencies](/docs/entities/currencies/list), [POST /v1/currencies/search](/docs/entities/currencies/search) и подвызов `entity=currencies` в [POST /v1/batch](/docs/batch) — оба ключа, `sort` и `order`. Для остальных сущностей ключ `order` в батче по-прежнему уходит в Битрикс24 как есть.

### BC-0903-18: include принимает только разрешаемые связи

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

**Было**

Связи `site` в [GET /v1/pages/:id](/docs/entities/pages/get), `requisite` в [GET /v1/companies/:id](/docs/entities/companies/get) и [GET /v1/contacts/:id](/docs/entities/contacts/get), а также `quote` в [GET /v1/deals/:id](/docs/entities/deals/get) объявлялись доступными. Запрос с таким `include` возвращал HTTP 200, но не добавлял связь в `_included`. То же происходило со связями `deal`, `contact` и `company` у [GET /v1/quotes/:id](/docs/entities/quotes/get), `contact` и `company` у [GET /v1/invoices/:id](/docs/entities/invoices/get), а также `section` у [GET /v1/products/:id](/docs/entities/products/get).

**Стало**

Связи предложений, счетов и товаров возвращаются в `_included` как объект или `null`, если поле-ссылка пустое. `site` у страниц, `requisite` у компаний и контактов, а также `quote` у сделок больше не объявляются. Запрос этих имён возвращает `400 INVALID_INCLUDE`.

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

Для страницы прочитайте `siteId` и запросите [GET /v1/sites/:id](/docs/entities/sites/get). Для компании используйте [GET /v1/requisites](/docs/entities/requisites/list) с фильтрами `entityTypeId=4` и `entityId=<companyId>`, для контакта — с `entityTypeId=3` и `entityId=<contactId>`. Для сделки прочитайте `quoteId` и запросите [GET /v1/quotes/:id](/docs/entities/quotes/get).

### BC-0903-19: массив input в POST /v1/embeddings ограничен 64 строками

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

**Было**

[POST /v1/embeddings](/docs/ai/embeddings) принимал массив `input` любой длины — ограничения на число строк в одном запросе не было.

**Стало**

Массив `input` принимает не более 64 строк. Более длинный массив отклоняется с `400 invalid_request` до списания средств и до обращения к модели. Разбейте больший запрос на части по 64 строки.

### NEW-0903-20: новая модель распознавания речи BitrixGPT 5.6 Transcribe

`POST /v1/audio/transcriptions` принимает вторую платформенную модель — `bitrix/bitrixgpt-5.6-transcribe` (BitrixGPT 5.6 Transcribe): 25 европейских языков, включая русский и украинский. Whisper Large v3 Turbo остаётся моделью по умолчанию — вызовы без поля `model` не меняются. У новой модели поля `language`, `prompt`, `hotwords`, `temperature` и `vad_filter` принимаются, но на распознавание не влияют; их имена возвращаются в новом информационном заголовке ответа `X-Ignored-Params`. Форматы `text`, `srt` и `vtt` для новой модели строит платформа Вайбкод из сегментов, и они тарифицируются по длительности аудио, как `json`. В `capabilities` модели появился ключ `transcription_openai_only`. Английские тексты ошибок `ai_provider_timeout` и `ai_provider_unavailable` теперь не называют движок распознавания; коды и статусы прежние.

### FIX-0903-21: демо линейки Vibe+ открывает доступ на .com

**Было**

Портал, которому выдали демо Vibe+, продолжал получать отказ
`INT_VIBE_PLUS_REQUIRED`: выдача демо не меняет код тарифа портала, а вердикт
доступа читал только его. Слот `capabilities.servers.create` в `/v1/me`
оставался `available: false`, и повторное действие упиралось в тот же отказ.

**Стало**

Активное демо открывает доступ в режиме пробного периода — с теми же
ограничениями, что у демо Маркетплейса. Купленный тариф Vibe+ поверх активного
демо по-прежнему даёт полный доступ, а истёкшее демо доступа не даёт.

### NEW-0903-22: два новых кода отказа у промокода: ограничение по тарифу Битрикс24

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

Когда список задан, оба публичных метода промокода отвечают новыми кодами: `POST /v1/cowork/coupon/preview` возвращает их в поле причины при `valid=false`, `POST /v1/cowork/coupon/redeem` — статусом `409`. Кодов два, и путать их нельзя.

`COUPON_TARIFF_NOT_ELIGIBLE` — тариф портала прочитан и в список не входит. Отказ окончательный: на этом портале код не начнёт работать сам, повторять запрос бессмысленно.

`COUPON_TARIFF_UNKNOWN` — ограничение действует, но тариф портала платформа ещё не определила (так бывает на только что подключённом портале). Промокод цел, попытка не расходует лимит попыток погашения, и повтор позже — верное действие.

В обоих случаях промокод остаётся непогашенным, а прежние коды отказа не изменились.

⚠️ У `preview` статус ответа прежний — `200` с `valid=false`, — но в поле `reason` теперь приходят и эти два значения. Клиент, который разбирает `reason` по известному ему набору, обязан завести им ветки: `COUPON_TARIFF_UNKNOWN` в ветке по умолчанию «промокод недействителен» покажет окончательный отказ там, где верное действие — повторить позже. Расход лимита попыток у проверки такой же, как у погашения: `COUPON_TARIFF_UNKNOWN` его не тратит, `COUPON_TARIFF_NOT_ELIGIBLE` тратит.
