Для AI-агентов: markdown этой страницы — /docs-content/cowork/applications-key.md индекс документации — /llms.txt

Выдать или заменить ключ приложения

POST /v1/cowork/applications/:id/key

Выдаёт ключ приложению с пустым слотом или заменяет уже выданный и возвращает новый ключ ровно один раз. Так публикуют приложение, добавленное из каталога: сырой ключ не восстанавливается, а перевыпуск через управляющий ключ настольному клиенту недоступен.

Скоуп: vibe:cowork (ключ Cowork/Code) | Базовый URL: https://vibecode.bitrix24.tech/v1 | Авторизация: X-Api-Key

Какая ветка сработала, называет поле issued: minted — слот был пуст и ключ выдан, rotated — ключ в слоте заменён. Заранее ветку не угадать, поэтому решает платформа. Вызывают эндпоинт двое. Владелец приложения получает ключ в слоте приложения. Участник команды разработки сервера приложения получает собственный ключ этого сервера — ключ владельца при этом не меняется и не показывается.

Параметры

Параметр Тип Обяз. Описание
Параметрid (path) Типstring Обяз.да ОписаниеИдентификатор приложения. Список: GET /v1/applications
ПараметрIdempotency-Key (header) Типstring Обяз.да ОписаниеСтрока от 1 до 255 символов из набора [A-Za-z0-9_.:-]. Область действия — вызывающий ключ. Как отвечает повтор — в «Известных особенностях»

Поля запроса (body)

Поле Тип Обяз. Описание
ПолеsyncServerEnv Типboolean Обяз.нет ОписаниеЗаменить ключ в окружении сервера приложения и перезапустить приложение. По умолчанию false. Действует только на ветке rotated: при minted прежнего ключа в окружении нет. Итог приходит в поле envSync ответа

Тело необязательно: запрос без тела и запрос с пустым объектом {} равнозначны. Схема строгая: лишнее поле отвечает 400 VALIDATION_ERROR. Размер тела ограничен 8 КиБ.

Примеры

Эндпоинт принимает только ключ Cowork/Code, поэтому примеров два. У личного ключа и ключа OAuth-приложения нет скоупа vibe:cowork, отказ по скоупу — 403 INSUFFICIENT_SCOPE.

curl — ключ Cowork/Code

Terminal
curl -X POST https://vibecode.bitrix24.tech/v1/cowork/applications/APPLICATION_ID/key \
  -H "X-Api-Key: YOUR_COWORK_KEY" \
  -H "Idempotency-Key: app-key-2026-09-22-01" \
  -H "Content-Type: application/json" \
  -d '{}'

JavaScript — ключ Cowork/Code

javascript
const res = await fetch('https://vibecode.bitrix24.tech/v1/cowork/applications/APPLICATION_ID/key', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_COWORK_KEY',
    'Idempotency-Key': 'app-key-2026-09-22-01',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
})

if (!res.ok) {
  const { error } = await res.json()
  throw new Error(`${res.status} ${error.code}`)
}

const { data } = await res.json()

// Сырой ключ приходит один раз — сохраните его сразу
if (data.rawApiKey === null) {
  // Это повтор запроса: ключ уже выдан, заново он не показывается
} else {
  saveKey(data.applicationId, data.rawApiKey)
}

// Прежний ключ работает до previousKey.graceUntil — доставьте новый ключ серверу раньше
if (data.previousKey?.graceUntil) {
  console.log('Прежний ключ перестанет работать:', data.previousKey.graceUntil)
}

Поля ответа

Поле Тип Описание
Полеsuccess Типboolean ОписаниеВсегда true при успехе
Полеdata.application Типobject | null ОписаниеКарточка приложения — та же форма, что отдаёт GET /v1/applications/:id. Её блок key уже показывает новый ключ. null только в одном случае: ключ выдан, а карточку после этого прочитать не удалось — тогда в warningCodes приходит APPLICATION_CARD_UNAVAILABLE
Полеdata.applicationId Типstring ОписаниеПовторяет application.id, чтобы связать локальную запись с карточкой, не разбирая её
Полеdata.issued Типstring | null Описаниеminted — слот был пуст и ключ выдан, rotated — ключ в слоте заменён. При повторе запроса — то, что сделал исходный запрос. null у замены, сделанной до того, как платформа начала записывать ветку
Полеdata.rawApiKey Типstring | null ОписаниеСырой ключ. Возвращается ОДИН раз, восстановить нельзя. Формат — vibe_api_, затем 32 символа латиницы и цифр, затем _ и 6 шестнадцатеричных символов. null при повторе запроса
Полеdata.key Типobject | null ОписаниеНовый ключ без секрета — id, prefix, suffix, scopes, status, expiresAt, createdAt. null при повторе запроса
Полеdata.key.scopes Типarray ОписаниеПрава нового ключа. Ключ владельца, выданный в пустой слот, несёт только vibe:infra и vibe:storage. Замена переносит права прежнего ключа
Полеdata.key.expiresAt Типstring | null ОписаниеСрок действия нового ключа, ISO 8601. null — ключ бессрочный. При замене срок наследуется от прежнего ключа, см. «Известные особенности»
Полеdata.previousKey Типobject | null ОписаниеЗаменённый ключ — id, graceUntil, status. Приходит только владельцу на ветке rotated, в остальных случаях null
Полеdata.previousKey.graceUntil Типstring | null ОписаниеМомент, когда прежний ключ перестанет работать: через 24 часа после замены или раньше, если раньше наступает его собственный срок. null, когда прежний ключ был заблокирован, — отсрочки у него нет
Полеdata.envSync Типobject | null ОписаниеИтог замены ключа в окружении сервера: статус в поле status, значения — в таблице ниже. null, когда syncServerEnv не передан, на ветке minted и в ответе участнику команды разработки
Полеdata.warnings Типarray ОписаниеПредупреждения текстом. Пустой, когда предупреждений нет
Полеdata.warningCodes Типarray ОписаниеКоды предупреждений. APPLICATION_HAS_AUTH_KEY — у приложения есть и ключ авторизации: карточка продолжает показывать его, а вызов затронул личный ключ. ENV_SYNC_NOT_APPLICABLE_FOR_COLLABORATOR — ответ участнику команды разработки. KEY_NOT_REPLAYABLE — повтор запроса. APPLICATION_CARD_UNAVAILABLE — карточку прочитать не удалось

Значения envSync.status. Поле variable называет затронутую переменную окружения, поле reason уточняет skipped и recreate_failed.

Статус Что произошло
Статусupdated Что произошлоКлюч заменён в окружении приложения, приложение перезапущено
Статусrestart_failed Что произошлоКлюч в окружении заменён, перезапуск не удался — перезапустите приложение сами
Статусowner_restore_failed Что произошлоКлюч в окружении заменён, но файл окружения остался недоступен приложению. Перезапуск не поможет, пока приложению не вернут доступ к файлу
Статусnot_found Что произошлоПрежний ключ в окружении не найден, окружение не тронуто. Впишите новый ключ сами
Статусskipped Что произошлоЗамена не выполнялась: reason: "no_server" — у приложения нет сервера, reason: "galaxy" — доставка ключа в контейнеры для аккаунта выключена
Статусunreachable Что произошлоСервер или контейнер спит либо недоступен, окружение не тронуто
Статусfailed Что произошлоПлатформа не смогла определить, куда доставить ключ, или доставка оборвалась
Статусrecreated Что произошлоКонтейнер пересоздан с новым ключом в окружении. На время перезапуска приложение обрывает открытые соединения — это плановый простой
Статусnot_required Что произошлоВ окружении контейнера нет ключа платформы, менять нечего
Статусbaked_in_image Что произошлоКлюч зашит в образ контейнера, пересоздание его не обновит. Переопределите переменную при запуске или пересоберите образ из исходников
Статусrecreate_failed Что произошлоЗамена началась и не завершилась. Причина — в reason: rolled_back, app_down, busy, read_failed или timeout
Статусsuperseded Что произошлоБолее поздняя замена ключа уже применилась к этому контейнеру

Пример ответа

Замена ключа в занятом слоте, issued: "rotated":

JSON
{
  "success": true,
  "data": {
    "application": {
      "id": "cmud90k3b0009cicg8yxl2rf8",
      "name": "Отчёт по сделкам",
      "description": null,
      "type": "PERSONAL",
      "iconUrl": null,
      "createdAt": "2026-09-22T22:31:23.063Z",
      "updatedAt": "2026-09-22T22:31:23.092Z",
      "viewerState": "owner",
      "pinned": false,
      "author": { "name": "Автор приложений" },
      "isEmbedded": false,
      "openUrl": null,
      "openTarget": null,
      "server": null,
      "sources": { "hasVersions": false, "latestVersionId": null, "latestSavedAt": null },
      "activeOperation": null,
      "key": {
        "slot": "api",
        "present": true,
        "prefix": "vibe_api_…",
        "suffix": "9529",
        "status": "ACTIVE",
        "expiresAt": null,
        "lastUsedAt": null,
        "rotatable": true,
        "rotateBlockedReason": null,
        "affectsShownKey": true
      }
    },
    "applicationId": "cmud90k3b0009cicg8yxl2rf8",
    "issued": "rotated",
    "rawApiKey": "vibe_api_…",
    "key": {
      "id": "b3d37d59-5b50-4e72-aa12-8a2b40a012f8",
      "prefix": "vibe_api_…",
      "suffix": "9529",
      "scopes": ["crm", "vibe:infra", "vibe:storage"],
      "status": "ACTIVE",
      "expiresAt": null,
      "createdAt": "2026-09-22T22:31:23.086Z"
    },
    "previousKey": {
      "id": "5d192322-3ced-438e-bc4f-0cbba01b9937",
      "graceUntil": "2026-09-23T22:31:23.087Z",
      "status": "ACTIVE"
    },
    "envSync": null,
    "warnings": [],
    "warningCodes": []
  }
}

Выдача ключа в пустой слот, issued: "minted":

JSON
{
  "success": true,
  "data": {
    "application": {
      "id": "cmud90jwg0001cicg4qgipzws",
      "name": "Дашборд продаж",
      "description": null,
      "type": "PERSONAL",
      "iconUrl": null,
      "createdAt": "2026-09-22T22:31:22.816Z",
      "updatedAt": "2026-09-22T22:31:22.889Z",
      "viewerState": "owner",
      "pinned": false,
      "author": { "name": "Автор приложений" },
      "isEmbedded": false,
      "openUrl": null,
      "openTarget": null,
      "server": null,
      "sources": { "hasVersions": false, "latestVersionId": null, "latestSavedAt": null },
      "activeOperation": null,
      "key": {
        "slot": "api",
        "present": true,
        "prefix": "vibe_api_…",
        "suffix": "f08a",
        "status": "ACTIVE",
        "expiresAt": null,
        "lastUsedAt": null,
        "rotatable": true,
        "rotateBlockedReason": null,
        "affectsShownKey": true
      }
    },
    "applicationId": "cmud90jwg0001cicg4qgipzws",
    "issued": "minted",
    "rawApiKey": "vibe_api_…",
    "key": {
      "id": "61a91657-2e88-4aeb-848f-1951327efd71",
      "prefix": "vibe_api_…",
      "suffix": "f08a",
      "scopes": ["vibe:infra", "vibe:storage"],
      "status": "ACTIVE",
      "expiresAt": null,
      "createdAt": "2026-09-22T22:31:22.879Z"
    },
    "previousKey": null,
    "envSync": null,
    "warnings": [],
    "warningCodes": []
  }
}

Пример ответа при ошибке

403 — ключ в слоте приложения шире вызывающего ключа:

JSON
{
  "success": false,
  "error": {
    "code": "KEY_ROTATE_WIDER_THAN_CALLER",
    "message": "The key in this application slot is wider than your key. Re-issue it from the web cabinet, where the owner sees what the new key will be allowed to do."
  }
}

Ошибки

Выписка ключа идёт тем же каналом Битрикс24, что у создания приложения, и его отказы переподнимаются дословно. У коробочного аккаунта выписка идёт своим каналом и приносит собственные коды, разобранные в Ключах и авторизации. Форма ответа та же, ветвитесь по error.code.

HTTP Код Описание
HTTP400 КодIDEMPOTENCY_KEY_REQUIRED ОписаниеЗаголовок Idempotency-Key не передан
HTTP400 КодINVALID_IDEMPOTENCY_KEY ОписаниеЗаголовок передан, но не подходит по длине или набору символов
HTTP400 КодVALIDATION_ERROR ОписаниеЛишнее поле в теле или syncServerEnv не булево значение
HTTP400 КодPORTAL_NOT_LINKED ОписаниеАккаунт Битрикс24 не связан с Битрикс24 Нетворк, и выписать ключ нечем
HTTP400 КодBOX_NO_DEVELOPER_KEY ОписаниеКоробочный аккаунт: у владельца приложения нет ключа разработчика, и выписать ключ нечем
HTTP401 КодMISSING_API_KEY ОписаниеНе передан заголовок X-Api-Key
HTTP401 КодINVALID_API_KEY ОписаниеКлюч не опознан: такой строки на платформе нет
HTTP401 КодKEY_INACTIVE ОписаниеКлюч выключен
HTTP401 КодKEY_EXPIRED ОписаниеСрок действия вызывающего ключа истёк
HTTP402 КодACCOUNT_FROZEN ОписаниеБаланс аккаунта исчерпан — пополните счёт
HTTP402 КодMARKETPLACE_REQUIRED ОписаниеТолько выдача, а не замена: у аккаунта нет действующей подписки BitrixGPT + Маркетплейс. В странах, где доступ даёт тариф Битрикс24, приходит код своей страны — KZ_PAID_ONLY, UZ_PAID_ONLY или BY_PAID_ONLY. Замена эту проверку не проходит: она переносит права прежнего ключа и новых не выдаёт
HTTP402 КодINT_TARIFF_REQUIRED ОписаниеТолько выдача, а не замена: аккаунт получает доступ по тарифу Битрикс24, а тариф бесплатный
HTTP403 КодINSUFFICIENT_SCOPE ОписаниеУ ключа нет скоупа vibe:cowork
HTTP403 КодCOWORK_HARNESS_KEY_FORBIDDEN ОписаниеВызов сделан ключом стороннего агента, выписанным на подписку. Такому ключу эндпоинт недоступен — см. Свой агент на подписке
HTTP403 КодCOWORK_NOT_ACTIVATED ОписаниеНет активной подписки Cowork/Code для пары сотрудник и аккаунт
HTTP403 КодWRITE_BLOCKED_READONLY_KEY ОписаниеВызывающий ключ в режиме «только чтение», а выдача и замена ключа — запись. error.details называет ключ и его режим
HTTP403 КодNOT_APPLICATION_OWNER ОписаниеВызывающий не владеет приложением и не входит в команду разработки его сервера
HTTP403 КодKEY_ROTATE_WIDER_THAN_CALLER ОписаниеКлюч в слоте приложения шире вызывающего ключа. Замена здесь молча сузила бы приложение, которым могут пользоваться другие, поэтому такой ключ перевыпускают в кабинете
HTTP403 КодKEY_POLICY_READONLY_REQUIRED ОписаниеТолько ключ участника команды разработки: выдаваемый ключ шире режима, который аккаунт назначает новым ключам. Владельцу ключ в пустой слот выдаётся в режиме политики, и этот отказ ему не приходит
HTTP403 КодINFRA_DISABLED_FOR_PORTAL ОписаниеТолько выдача, а не замена: администратор портала выключил работу с серверами, а новый ключ несёт vibe:infra
HTTP403 КодPORTAL_TARIFF_UNREADABLE ОписаниеТолько выдача, а не замена: тариф аккаунта прочитать не удалось, поэтому какой тариф нужен, ответ не называет. Покупка тарифа отказ не снимает
HTTP403 КодPORTAL_SUBSCRIPTION_UNREADABLE ОписаниеТолько выдача, а не замена: состояние подписки аккаунта прочитать не удалось. Покупка отказ не снимает — приложение нужно переподключить под главным администратором аккаунта
HTTP404 КодAPPLICATION_NOT_FOUND ОписаниеПриложения с таким id на аккаунте нет или оно удалено
HTTP409 КодKEY_ROTATE_OAUTH_APP_KEY ОписаниеВ личном слоте лежит ключ авторизации. Его перевыпуск пересоздаёт OAuth-приложение на аккаунте и меняет client_id, поэтому делается в кабинете
HTTP409 КодKEY_ROTATE_SYSTEM_KEY ОписаниеВ слоте лежит ключ, который платформа выдаёт своим эндпоинтом. Кнопки перевыпуска в кабинете у такого ключа нет — обратитесь в поддержку
HTTP409 КодKEY_ROTATE_LIVE_OAUTH_GRANT ОписаниеУ ключа есть живое разрешение авторизации, и замена оставила бы его на отзываемом ключе. Сначала отзовите разрешение в кабинете
HTTP409 КодKEY_ROTATE_NOT_ACTIVE ОписаниеКлюч в слоте отозван или его срок истёк. Верните ключ в работу или продлите срок в кабинете и повторите
HTTP409 КодKEY_ROTATE_KEY_VANISHED ОписаниеКлюч удалили, пока шёл запрос. Повторите
HTTP409 КодAPPLICATION_KEY_RECOVERY_REQUIRED ОписаниеКлюч в слоте — незавершённая замена. Новый ключ идемпотентности запрет не снимает: нужно восстановление через поддержку
HTTP409 КодAPPLICATION_KEY_REPLACE_IN_PROGRESS ОписаниеНа приложении уже идёт другая замена ключа либо она завершилась, пока этот запрос ждал очереди. Одна замена на приложение за раз, с любым ключом идемпотентности. Дождитесь её, перечитайте карточку и только потом просите снова. Замена, брошенная упавшим запросом, перестаёт мешать через две минуты
HTTP409 КодKEY_LIMIT_REACHED ОписаниеТолько выдача, а не замена: квота ключей исчерпана. error.details содержит used, limit и requested, а scope: "portal" означает портальный потолок платформы
HTTP409 КодCOLLABORATOR_KEY_REQUIRES_SERVER ОписаниеУчастник команды разработки: у приложения нет живого сервера, а ключ участника привязан к серверу
HTTP409 КодCOLLABORATOR_MEMBERSHIP_BIND_CONFLICT ОписаниеУчастник команды разработки: членство не удалось надёжно привязать к аккаунту, и ключ не выдан. Попросите владельца сервера добавить вас заново
HTTP409 КодIDEMPOTENCY_KEY_BODY_MISMATCH ОписаниеТот же Idempotency-Key пришёл с другим телом
HTTP409 КодIDEMPOTENCY_KEY_ALREADY_USED ОписаниеКлюч идемпотентности израсходован, и повторить нечего: он отправлен для другого приложения, карточку удалили либо ключ под ним уже выдан, а запрос потом упал. Прочитайте карточку и повторите с НОВЫМ ключом идемпотентности
HTTP409 КодIDEMPOTENCY_CONCURRENT_RETRY ОписаниеПараллельный запрос с тем же ключом идемпотентности ещё выполняется. Единственный из трёх отказов идемпотентности, где повтор осмыслен
HTTP413 КодPAYLOAD_TOO_LARGE ОписаниеТело больше 8 КиБ. Проверяется до разбора тела, поэтому ничего не резервируется и ключ не выписывается
HTTP415 КодFST_ERR_CTP_INVALID_MEDIA_TYPE ОписаниеТело прислано с типом содержимого, который маршрут не разбирает. Отправляйте Content-Type: application/json или запрос без тела
HTTP429 КодRATE_LIMITED ОписаниеПревышен предел частоты на связку аккаунт и владелец ключа. Суммарный лимит платформы — 6 запросов в минуту. Действующее для вашего ключа значение приходит в заголовке x-ratelimit-limit — оно ниже суммарного, поскольку лимит делится между репликами
HTTP429 КодQUOTA_EXCEEDED ОписаниеИсчерпана суточная бесплатная квота вызовов при нулевом балансе на предоплате
HTTP500 КодAPPLICATION_KEY_ATTACH_FAILED ОписаниеКлюч выдан в пустой слот, но привязать его к приложению не удалось. error.details.orphanKeyId называет этот ключ: отзовите его и повторите с НОВЫМ ключом идемпотентности
HTTP500 КодAPPLICATION_KEY_REPOINT_FAILED ОписаниеНовый ключ выписан, но карточка не дошла до проверенного конечного состояния. Ключ error.details.orphanKeyId остаётся под защитой восстановления, и повтор с другим ключом идемпотентности запрещён. Если на этот ключ ничего не указывает, удалите его штатным удалением ключа. Непустой error.details.strandedSlots перечисляет то, что ещё указывает на ключ, — тогда обратитесь в поддержку
HTTP500 КодKEY_ROTATE_REVOKE_FAILED ОписаниеЗамена заблокированного ключа: отзыв его живых токенов доступа не подтвердился. Сырого ключа в ответе нет, выписанный ключ остаётся под защитой восстановления, и повтор не разрешён, пока восстановление не завершено
HTTP502 КодBITRIX_UNAVAILABLE ОписаниеБитрикс24 отказал или был недоступен во время выписки ключа. Прежний ключ остаётся как был: действующий продолжает работать, заблокированный — нет
HTTP503 КодCOWORK_FEATURE_DISABLED ОписаниеCowork/Code отключён на уровне платформы

Полный список общих ошибок API — Ошибки.

Известные особенности

Режим выданного ключа не шире вашего ключа. На ключ, который получает владелец приложения, режим места Cowork/Code не влияет. В пустой слот ключ выдаётся в самом узком из режима, который аккаунт назначает новым ключам, и режима вызывающего ключа: политика «только чтение» выдачу не отбивает, а сужает. Замена даёт ключ не шире текущего режима заменяемого ключа и не шире вызывающего.

Карточка заранее говорит, пройдёт ли вызов. Блок key карточки приложения несёт rotatable — пройдёт ли этот вызов для вас — и rotateBlockedReason с причиной отказа. WIDER_THAN_CALLER значит, что ключ в слоте шире вашего, WRITE_BLOCKED_READONLY_KEY — что ваш ключ не меняет данные. Незнакомую причину читайте как «заменить нельзя, причина неизвестна». Флаг отражает то, что платформа уже знает, поэтому false не тупик, а true не гарантия: отказ самого эндпоинта всё равно обрабатывайте.

Без syncServerEnv новый ключ до сервера не доходит. Приложение держит прежний ключ в своём окружении и начинает получать отказы в момент previousKey.graceUntil — это не всегда через 24 часа. Присылайте true, если у вас нет своего способа доставить ключ серверу.

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

Заблокированный ключ в слоте замене не мешает. Его живые токены доступа гасятся и на новый ключ не переезжают.

Участник команды разработки получает свой ключ. Ключ привязан к серверу приложения и открывает только маршруты разработки этого сервера. Окружение сервера владельца такой вызов не меняет. Режим ключа участника — самый узкий из режима вызывающего ключа и режима места Cowork/Code, если вызывающий ключ принадлежит месту: у места в режиме «только чтение» ключ участника выдаётся в том же режиме, даже когда сам вызывающий ключ может изменять данные.

Повтор с тем же ключом идемпотентности ключа не возвращает. Повтор с тем же телом отвечает 201 с заголовком Idempotent-Replayed: true. Секрет хранится только в виде хеша, поэтому сохраняйте rawApiKey сразу, в том же обработчике ответа.

Смотрите также