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

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

### FIX-0629-1: поиск узлов оргструктуры теперь ищет по названию

**Было**

[POST /v1/humanresources/nodes/search](/docs/humanresources/nodes/search) проксировал в `humanresources.node.list`: тип узла задавался внутри `filter`, поиска по названию не было вовсе, а тело `{ "type": ..., "name": ... }` на верхнем уровне (или запрос без тела) возвращало `400` или `500`.

**Стало**

Эндпоинт обёрнут на `humanresources.node.search`. Обязательны два поля на верхнем уровне тела — `type` (`DEPARTMENT` или `TEAM`) и `name` (подстрока названия). Необязательны `parentId` и `pagination.limit` (по умолчанию 50, максимум 200). Возвращаются узлы, чьё название содержит `name`, в плоском `data` с `meta` (`total`, `hasMore`). Поля `filter`, `order` и `select` больше не принимаются.

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

Присылайте `{ "type": "TEAM", "name": "<подстрока>" }` на верхнем уровне вместо прежнего `{ "filter": { "type": "TEAM" } }`. Чтобы перечислить все узлы типа без поиска по названию, используйте [GET /v1/humanresources/nodes](/docs/humanresources/nodes/list) с `?type=...`.

### NEW-0629-2: Расписание выгодных часов AI-квоты (off-peak)

Добавлен эндпоинт `GET /v1/off-peak` — расписание скидок «выгодных часов» (Time-of-Use) для AI-квоты. Ответ содержит множитель цены прямо сейчас (`currentMultiplier`), ближайшее окно, когда станет дешевле (`nextWindow`), сетку 24×7 по часам и дням недели (`grid`), текущую ячейку сетки (`nowCell`) и часовой пояс расписания (`timezone`). Скидка применяется только к квотируемому расходу — в эти часы квота расходуется медленнее; оплата за токены по кошельку не затрагивается. Необязательный параметр `model=<идентификатор>` возвращает расписание конкретной модели вместо общего по умолчанию. Требуется скоуп `vibe:ai`. Пока выгодные часы не включены, ответ — `{ "enabled": false }`.

### BC-0629-3: удалён слаг провайдера vibe-search

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

**Было**

Поле `provider` в [POST /v1/search](/docs/search/run) и [POST /v1/research](/docs/search/research) принимало слаг `vibe-search` — отдельный платформенный движок, добавленный 06.06.2026. Он также присутствовал в перечне слагов [GET /v1/search/providers](/docs/search/providers).

**Стало**

Слаг `vibe-search` удалён. Платформенный поисковый движок на всех инстансах называется `bitrix-search` — конкретный апстрим за ним зависит от инстанса. Запрос с `provider: "vibe-search"` теперь возвращает `400 INVALID_REQUEST` (значение не проходит валидацию). Поддержка research для `bitrix-search` тоже зависит от инстанса — читайте [GET /v1/search/providers](/docs/search/providers).

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

Если в запросе явно передавался `provider: "vibe-search"`, замените его на `bitrix-search` либо опустите поле `provider`, чтобы использовать движок по умолчанию инстанса (его показывает поле `defaultProvider` в [GET /v1/me](/docs/keys-auth)). Слаг `vibe-search` не был движком по умолчанию ни на одном проде, поэтому затронуты только интеграции, прописавшие его явно.

### FIX-0629-4: Значение null в поле через POST /v1/batch больше не пишет в поле строку «null»

**Было**

В составном `POST /v1/batch` создание или обновление со значением поля `null` (например `{"entity":"deals","action":"update","entityId":123,"params":{"comments":null}}`) записывало в поле **литеральную строку `"null"`**.

**Стало**

Поле получает пустое значение, которое Bitrix24 трактует по типу поля: текстовое — очищается, числовое — становится `0`, датовое — остаётся без изменений. Литеральная строка `"null"` больше не пишется, ошибки не возникает. Это совпадает с поведением одиночного `PATCH /v1/{entity}/:id` с `null`. Постраничный путь `/v1/{entity}/batch` по-прежнему пропускает `null`-поле целиком (оставляет значение без изменений у всех типов).

### FIX-0629-5: Поиск и список с фильтром по null теперь отдают больше 50 строк

**Было**

Запрос `POST /v1/{entity}/search` или `GET /v1/{entity}` с фильтром по пустому значению (например `{"filter": {"closedDate": null}}`) и `limit` больше 50 возвращал максимум 50 записей, хотя `meta.total` показывал реальное число совпадений и `meta.hasMore` был `true`. Автопагинация молча обрывалась после первой страницы, и типовой обход «читать, пока строк ровно `limit`» получал неполный результат без единой ошибки.

**Стало**

Такой запрос отдаёт до `limit` записей, как и с любым другим фильтром. Значение `null` в фильтре трактуется как «поле пусто» одинаково на всех страницах выборки.

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

Клиентам, которые из-за обрыва листали вручную через `offset` шагом 50, ручной обход больше не нужен — можно запросить до 5000 записей одним вызовом.

### FIX-0629-6: смена порта и автомаршрутизация деплоя работают на новых серверах-приложениях из коробки

**Было**

Обычный сервер «Опубликовать приложение» поднимался с фиксированным портом агента, поэтому `PATCH /v1/infra/servers/:id/port` и шаг автомаршрутизации деплоя отвечали `409 PORT_NOT_APPLIED` (`NO_SCANNER`), а публичный URL отдавал служебную страницу Black Hole, пока сервис слушал не порт по умолчанию.

**Стало**

Новые обычные серверы-приложения поднимаются с авто-определением порта: сервис на любом порту доступен через туннель сразу, а смена порта и автомаршрутизация деплоя проходят успешно. Серверы агентов и galaxy-хостов поведение не меняют.

### FIX-0629-7: установка приложения через /v1/apps возвращает понятный код ошибки вместо общего BOX_APP_INSTALL_FAILED

**Было**

При сбое установки OAuth-приложения [POST /v1/apps](/docs/apps/create) всегда возвращал `502 BOX_APP_INSTALL_FAILED`, а в `error.message` подставлялся сырой ответ Битрикс24 целиком.

**Стало**

Ответ при сбое классифицируется: `403 B24_INSUFFICIENT_SCOPE` (служебная интеграция потеряла права на портале), `410 STALE_DEVELOPER_KEY` (доступ изменили или удалили — восстановить автоматически нельзя), `502 RECOVERY_FAILED` (временный сбой, можно повторить) или `502 DEVKEY_MINT_FAILED` (прочее). `error.message` больше не содержит сырой ответ Битрикс24 — диагностика переехала в очищенное поле `error.details.b24Body`.

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

Обработка «ответ не 201 — установка не удалась» продолжает работать без изменений. Если код различал именно `BOX_APP_INSTALL_FAILED`, добавьте обработку новых кодов выше.

### FIX-0629-8: поиск по широкому диапазону дат больше не возвращает пусто

**Было**

`POST /v1/deals/search` (и аналогично для leads, contacts, companies, quotes, invoices, items) с фильтром по дате и нижней границей (`>=` / `>`) за период шире 14 дней возвращал `200` с пустым `data` и `meta.total: 0`, хотя записи за этот период существовали.

**Стало**

Такой запрос возвращает все совпадающие записи. Поведение `GET /v1/deals`, узких диапазонов (≤ 14 дней) и параметра `autoWindow: false` не менялось.

### NEW-0629-9: Новый код ошибки CONNECTOR_APP_INSTALL_FORBIDDEN при установке приложения

[POST /v1/apps](/docs/apps) на коробочном портале теперь возвращает `403` с кодом `CONNECTOR_APP_INSTALL_FORBIDDEN`, когда администратор портала Битрикс24 запретил пользователю устанавливать приложения. Поле `error.message` содержит понятное локализованное объяснение с подсказкой обратиться к администратору портала. Прежде такой отказ отдавался как общий `502 CONNECTOR_APP_INSTALL_FAILED` без объяснения причины; этот код по-прежнему используется для прочих сбоев установки.

### NEW-0629-10: Перенос владения ботом на другой ключ

Добавлен эндпоинт [POST /v1/bots/:botId/transfer](/docs/bots/management/transfer) — переносит владение ботом на другой API-ключ того же аккаунта Битрикс24 и того же пользователя (или администратора аккаунта). Решает ситуацию, когда бот «осиротел» после пересоздания приложения: ключ-владелец отозван, и рантайм бота переставал работать. Тело: `{ "targetApiKeyId": "<id>" }`. Целевой ключ должен быть активен, в том же аккаунте, с областью `imbot`. После переноса проверьте B24-привязку нового ключа через `POST /v1/bots/:botId/reauth`.
