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

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

### BC-1019-1: Добавление доступа к хранилищу требует личного ключа

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

**Было**

Правка `scopes` могла добавить `vibe:storage` ключу приложения или ключу неизвестного происхождения, открывая доступ к файлам владельца.

**Стало**

Ручное добавление через `PATCH /v1/keys/:id`, управляющий ключ или MCP отклоняется с `403 KEY_STORAGE_SCOPE_REQUIRES_PERSONAL_KEY`. То же ограничение действует при изменении прав парного ключа через `PATCH /v1/apps/:id`. Уже выданное право можно сохранить без изменения или снять; переименование и другие правки разрешены. Конкурентная операция может вернуть `409 KEY_OPERATION_IN_PROGRESS`.

При `POST /v1/keys` и `POST /v1/apps` ключ приложения или ключ неизвестного происхождения не получает хранилище по умолчанию; явный запрос этого права возвращает тот же 403 до создания ключа или приложения. Выдача через OAuth для партнёрских приложений сохраняет отказ `400 CONNECT_STORAGE_SCOPE_UNAVAILABLE`. Системная выдача Коворка и замена его ключей сохраняют доступ к хранилищу; ранее снятое право не возвращается. Ключи партнёрских приложений не получают хранилище при замене.

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

Создайте новый личный ключ с правом хранилища. При `409 KEY_OPERATION_IN_PROGRESS` перечитайте ключ или приложение и повторите операцию с текущим набором прав.

### FIX-1019-2: Connect отзывает ключ предъявленного устройства Коворка

**Было**

`POST /v1/connect/revoke` с `client_id=cowork-desktop` и ключом этого клиента отвечал HTTP 200, но оставлял ключ активным.

**Стало**

Ответ `POST /v1/connect/revoke` остаётся HTTP 200. Предъявленный ключ устройства отзывается, дальнейшие запросы с ним отклоняются. Ключи других устройств остаются активными. Неизвестные, чужие и уже отозванные токены по-прежнему дают HTTP 200 без раскрытия состояния ключа. `DELETE /v1/cowork/key` также остаётся доступен для отзыва собственного ключа устройства.

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

Существующий запрос отзыва теперь отключает предъявленное устройство; для дальнейшей работы на нём потребуется войти снова. Формат запроса и ответа не меняется.

### FIX-1019-3: ссылки на собственное хранилище распознаются при деплое

При создании приложения и деплое через `source.url` ссылки на бакет платформы распознаются как в форме отдельного хоста бакета, так и с именем бакета в пути. Версия исходников связывается с деплоем в обеих формах. Если для вашего аккаунта доступна выкладка на общем сервере по ссылке, ссылки на другие бакеты не допускаются: сначала сохраните архив как версию исходников и используйте `source.versionId`.

### NEW-1019-4: Явный ранний отказ при повторении JSON

В [POST /v1/chat/completions](/docs/ai/chat/completions) доступна опция `repetition_guard: "off" | "abort"`. Отсутствие опции или `"off"` сохраняет прежнее поведение. Явный `"abort"` останавливает запрос при эвристически обнаруженном повторе JSON до завершения генерации. Нужны `response_format` с типом `json_object` или `json_schema`, отсутствие объявленных инструментов и модель с поддержкой потока даже для синхронного ответа. Несовместимый запрос получает `400 invalid_request` до обращения к модели. При обнаружении повтора синхронный клиент получает `422 reasoning_repetition`, а потоковый — одно событие `error` и один `data: [DONE]` при HTTP `200`. Частичный ответ нужно отбросить. Законные повторяющиеся массивы могут вызвать ложный отказ, поэтому для них оставляйте опцию выключенной. Условия и пример SDK — в [документации JSON-ответа](/docs/ai/chat/json).

### FIX-1019-5: запуск сервера из ошибки, не дождавшийся готовности, возвращает его в ошибку

**Было**

[POST /v1/infra/servers/{id}/start](/docs/infra/lifecycle/start) для сервера в статусе `error` переводил его в `provisioning`. Если машина так и не поднималась, по истечении ожидания сервер получал статус `sleeping`, причина ошибки пропадала из ответа, а списания за спящий сервер возобновлялись.

**Стало**

Несостоявшийся запуск из `error` возвращает сервер в `error` с прежней причиной, списания не возобновляются. Запуск из `sleeping` по истечении ожидания по-прежнему возвращает сервер в `sleeping`.

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

Действий не требуется. После неудачного запуска сервера в статусе `error` опрос [GET /v1/infra/servers/{id}](/docs/infra/servers/get) покажет `error`, а не `sleeping`.

### NEW-1019-6: выпуск приложения галактики на отдельный сервер сохраняет свой домен

Создание отдельного сервера взамен приложения галактики — [POST /v1/infra/servers](/docs/infra/servers/create) с `placement: "dedicated"` и `graduateFrom` — сохраняет свой домен приложения: имя переезжает на созданный сервер вместе с подтверждением, записи DNS и TXT-токен остаются прежними, привязывать домен заново не нужно.

Ответ `201` этого вызова получил необязательное поле верхнего уровня `warningCodes` — машинные коды к строкам `warnings`, чтобы ветвиться без разбора текста. Поле приходит только тогда, когда есть что сообщить, и набор кодов открытый: незнакомый код нужно пропускать, а не считать ошибкой.

Первый такой код — `GRADUATION_DOMAIN_REGISTRY_PENDING`: домен уже закреплён за новым сервером, но пока не открывается. Соседняя строка `warnings` называет имя и единственный вызов, который это доигрывает — `POST /v1/infra/servers/{id}/domain/verify` на новом сервере. Записи DNS при этом менять не нужно.

Свой домен приложения пока доступен только порталам пилотной программы, поэтому всё описанное выше действует только на них. На остальных порталах у приложения галактики своего домена нет, и ответ этого вызова не меняется.

### NEW-1019-7: Восстановление регистрации бота после ответа без ID

Для регистрации бота через `POST /v1/bots` с режимом `webhook` API Вайбкод теперь подтверждает сохранённую запись URL по ответу портала и возвращает `data.botId`, когда остальные свойства бота проверены. Если прежняя регистрация осталась в ожидании подтверждения, вызовите `POST /v1/bots/registrations/:code/recover` с тем же ключом и кодом. Успех возвращает `data.botId`; действие проверяет уже созданного бота и не регистрирует нового. При `409` повторите действие после `Retry-After` или обратитесь в поддержку, если подтверждение не завершается.

### NEW-1019-8: ссылки на новые страницы открытых линий в `GET /v1/guide`

Объект `openLines.docs` в ответе `GET /v1/guide` получил семь новых ссылок: `crmMembersCreate`, `crmMembersDelete`, `crmMessages`, `crmLead`, `sessionsSearch`, `sessionsIntercept` и `sessionsJoin`. Они ведут на отдельные страницы методов: добавить и удалить сотрудника CRM-чата, отправить сообщение клиенту, создать лид из обращения, найти сессии, перехватить диалог и войти в диалог. Прежние ключи `openLines.docs` остались на месте, ответ по-прежнему HTTP 200.

### FIX-1019-9: Подсказка при повторном использовании сервера объясняет создание второго приложения

**Было**

При повторном использовании сервера ответ [POST /v1/infra/servers](/docs/infra/servers/create) сообщал об уже привязанном сервере, но не объяснял, как создать второе приложение.

**Стало**

Поле `hint` объясняет: для второго приложения создайте отдельную карточку приложения с собственным API-ключом и используйте этот ключ для нового приложения.

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

Существующие запросы менять не нужно. Правило повторного использования сервера и поля ответа сохранены.

### NEW-1019-10: адреса переходов из списка коннекторов Коворка

`GET /v1/connectors` для Коворка возвращает `manageUrl` для управления подключениями, `addUrl` для каталога и `addOwnUrl: null`; при `null` используется `addUrl`. Адрес карточки `items[].webUrl` изменен на `/extensions/connectors/<slug>`. Адреса абсолютные и открываются в системном браузере. Ответ для ключей приложения не меняется.

### FIX-1019-11: первая выкладка Node.js 20 на новом сервере не ждёт системных обновлений

**Было**

[POST /v1/infra/servers/:id/deploy](/docs/infra/deploy/deploy) с `runtime` из семейства `node20` устанавливал на сервер пакет `unzip`. На только что созданном сервере в это время шли фоновые обновления операционной системы, и выкладка заканчивалась ошибкой `RUNTIME_PREREQUISITES_LOCK_TIMEOUT` или `RUNTIME_PREREQUISITES_TIMEOUT`. То же ожидание случалось перед распаковкой `.zip` в выкладке и в [POST /v1/infra/servers/:id/upload](/docs/infra/deploy/upload).

**Стало**

Рантайм `node20` больше не требует `unzip`: архивы `.zip` распаковывает агент сервера. На сервере с актуальным агентом выкладка и загрузка `.zip` не устанавливают `unzip` и не ждут фоновых обновлений. Коды `UNZIP_PREFLIGHT_FAILED` и связанный с этим шагом `EXEC_BUSY` остаются только для серверов со старым агентом.

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

Повторять выкладку на новом сервере больше не нужно. Менять запросы не требуется.
