# Изменения API: 6 июля 2026

[← Журнал изменений](/docs/changelog) · [Июль 2026](/docs/changelog/2026-07)

### NEW-0706-1: Поля pricing.perCall и pricing.perMinute в каталоге моделей

Ответы [GET /v1/models](/docs/ai/models/list) и [GET /v1/models/{model}](/docs/ai/models/get) дополнены необязательными полями в объекте `pricing`: `perCall` — стоимость одного вызова в Вайбах, `perMinute` — стоимость одной минуты аудио в Вайбах (для моделей распознавания речи). Поля появляются только у моделей, для которых соответствующая базовая цена больше нуля; у остальных моделей объект `pricing` не меняется — существующие запросы работают без изменений.

### NEW-0706-2: Новый код ошибки 402 ai_quota_exhausted на AI-эндпоинтах

При включённом контроле месячной AI-квоты портала запросы [POST /v1/chat/completions](/docs/ai/chat/completions), [POST /v1/embeddings](/docs/ai/embeddings) и [POST /v1/audio/transcriptions](/docs/ai/audio/transcriptions) могут вернуть 402 с телом `{ success: false, error: { code: "ai_quota_exhausted", type: "insufficient_quota", reason, resetAt? } }`. Поле `reason` различает три случая: `breaker` — сработал часовой предохранитель расходов сверх квоты, `wallet_empty` — квота исчерпана и на балансе портала нет средств, `wallet_off` — расход сверх квоты для портала недоступен. `resetAt` — момент, когда запросы снова начнут проходить (для `wallet_off` при полном отключении может отсутствовать). Пока квота портала не исчерпана, поведение эндпоинтов не меняется.

### FIX-0706-3: Расход сверх AI-квоты списывается по базовой цене модели из каталога

**Было**

При активном контроле месячной AI-квоты портала запросы сверх квоты на [POST /v1/chat/completions](/docs/ai/chat/completions), [POST /v1/embeddings](/docs/ai/embeddings) и [POST /v1/audio/transcriptions](/docs/ai/audio/transcriptions) списывались с баланса портала по внутренним ставкам программы квот — со скидками непикового времени; итоговую цену нельзя было увидеть в каталоге моделей.

**Стало**

Расход сверх квоты списывается по базовой цене модели из публичного каталога — той же, что возвращается в поле `pricing` ответа [GET /v1/models](/docs/ai/models/list), включая новые `perCall` и `perMinute` для не-токенных моделей. Скидки непикового времени применяются только к списанию квоты, а не к денежному балансу. Расход в рамках квоты по-прежнему не списывается с баланса портала.

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

Менять ничего не требуется. Стоимость работы сверх квоты теперь можно рассчитать заранее по каталожной цене модели.

### NEW-0706-4: Модель эмбеддингов bitrix/embeddings доступна в API

Эндпоинт [POST /v1/embeddings](/docs/ai/embeddings) теперь обслуживается моделью `bitrix/embeddings` — преобразование текста в векторные представления для семантического поиска, кластеризации и retrieval (RAG). Модель бесплатная, тарификация только по входным токенам. Список моделей с поддержкой эмбеддингов — [GET /v1/models](/docs/ai/models/list).

### FIX-0706-5: Деплой честно сообщает об ошибке, если новый билд не занял порт

Развёртывание через [POST /v1/infra/servers/:id/deploy](/docs/infra/deploy) теперь проверяет, что порт держит именно новый сервис. Если предыдущий процесс продолжает слушать порт, а новый билд крэш-луп'ит с EADDRINUSE, деплой честно завершается ошибкой вместо ложного успеха; порт, занятый оставшимся процессом того же приложения, при возможности освобождается автоматически.

**Было**

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

**Стало**

Шаг `healthcheck` возвращает ошибку с указанием EADDRINUSE и порта, а шаг `stop_existing` освобождает порт от оставшегося процесса приложения (или предупреждает и продолжает, если освободить нельзя).

### NEW-0706-6: фильтр: оператор $nin (NOT IN) для исключения набора значений

**Было**

Отобрать записи, у которых поле НЕ входит в набор значений, было нельзя: оператор `$in` (IN) поддерживался, а обратного не было. Родные префиксы Битрикс24 `@` (IN) и `!@` (NOT IN) в имени поля (`{ "!@categoryId": [1, 3] }`) не транслировались — такой фильтр по сделкам возвращал `400 UNKNOWN_FILTER_FIELD`.

**Стало**

Добавлен оператор `$nin`: `{ "filter": { "categoryId": { "$nin": [1, 3] } } }` вернёт записи со всеми значениями, кроме перечисленных (NOT IN). Симметричен `$in`. Родные префиксы Битрикс24 `@` / `!@` в имени поля по-прежнему не поддерживаются, но теперь дают понятный `400 INVALID_FILTER_FIELD` с подсказкой перейти на `$in` / `$nin` — вместо невнятной ошибки или молча проигнорированного (и потому возвращавшего весь набор) фильтра.

### BC-0706-7: отдельный код ошибки для слишком длинной команды exec

> Поддержка старого формата до: 06.01.2027

**Было**

Команда длиннее 10 000 символов у [POST /v1/infra/servers/:id/exec](/docs/infra/deploy/exec) отклонялась общим кодом `VALIDATION_ERROR` без указания причины и выхода.

**Стало**

Такой запрос возвращает 400 с отдельным кодом `COMMAND_TOO_LONG` и структурированным `hint`: большие данные и скрипты передаются через [POST /v1/infra/servers/:id/upload](/docs/infra/deploy/upload), затем выполняются `bash /путь/скрипт.sh`. Остальные нарушения схемы по-прежнему возвращают `VALIDATION_ERROR`.

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

Если ваш клиент обрабатывает `VALIDATION_ERROR` этого эндпоинта как общий случай ошибки валидации — добавьте обработку кода `COMMAND_TOO_LONG` (или обрабатывайте любой 400 единообразно).

### NEW-0706-8: подсказка в ошибке таймаута exec

Ошибка `EXEC_TIMEOUT` у [POST /v1/infra/servers/:id/exec](/docs/infra/deploy/exec) теперь несёт структурированное поле `hint` (`reason` / `recovery` / `recoveryAction`): почему процесс был остановлен (по истечении `timeout` процесс-группа завершается принудительно, без grace-паузы) и что делать — запустить длинную операцию фоновой задачей и следить за ней через [GET /v1/infra/servers/:id/logs](/docs/infra/deploy/logs), поднять `timeout` до 600 секунд или использовать режим `?stream=true`. Поле аддитивное: прежний формат `code` / `message` не изменился, подсказка приходит и в JSON-режиме, и в SSE-событии `error`.
