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

Опубликовать приложение

POST /v1/apps/:id/publish

Переводит приложение в PUBLISHED, привязывает места встраивания к порталу и делает приложение видимым всем сотрудникам.

Параметры

Параметр Тип Обяз. Описание
id (path) string да Идентификатор приложения. Список: GET /v1/apps

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

Тело необязательное. При пустом теле берутся значения из записи приложения — это основной сценарий повторной публикации без изменений. Если передаёте тело, добавьте заголовок Content-Type: application/json — без него запрос с телом вернёт 413 PAYLOAD_TOO_LARGE.

Поле Тип Обяз. Описание
catalogTitle string нет Название в каталоге портала. Если не передано — текущее значение приложения
catalogDescription string нет Описание в каталоге
catalogIcon string нет Код иконки в каталоге
appUrl string нет Адрес приложения: сервер Black Hole, контейнер в галактике или внешний https-адрес. Если не передан — текущий appUrl приложения
placements string[] нет Коды мест встраивания. Список допустимых кодов — Доступные места. Если не передан — текущий набор приложения
sourceVersionId string нет Конкретный снапшот исходников для публикации, формат v<номер>. Применимо при включённом хранилище исходников
sourceServerId string нет Сервер, исходники которого публикуются, — идентификатор из POST /v1/infra/servers/:id/deploy. Нужен, когда исходники сохранил автосейв деплоя на сервере, который не принадлежит OAuth-ключу этого приложения: такой снапшот хранится у сервера, а не у приложения. Тот же смысл у заголовка X-Source-Server. Платформа сервер не подбирает — без этого поля проверка ищет снапшот приложения. Применимо при включённом хранилище исходников

Примеры

curl — личный ключ

Terminal
curl -X POST "https://vibecode.bitrix24.tech/v1/apps/YOUR_APP_ID/publish" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "placements": ["CRM_DEAL_DETAIL_TAB"] }'

curl — OAuth-приложение

Terminal
curl -X POST "https://vibecode.bitrix24.tech/v1/apps/YOUR_APP_ID/publish" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "placements": ["CRM_DEAL_DETAIL_TAB"] }'

JavaScript — личный ключ

javascript
const res = await fetch(
  'https://vibecode.bitrix24.tech/v1/apps/YOUR_APP_ID/publish',
  {
    method: 'POST',
    headers: {
      'X-Api-Key': 'YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ placements: ['CRM_DEAL_DETAIL_TAB'] }),
  }
)
const body = await res.json()
if (!body.success) throw new Error(body.error.code)
// body.warnings — массив, если часть мест встраивания не привязалась
console.log(body.data.placements)

JavaScript — OAuth-приложение

javascript
const res = await fetch(
  'https://vibecode.bitrix24.tech/v1/apps/YOUR_APP_ID/publish',
  {
    method: 'POST',
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ placements: ['CRM_DEAL_DETAIL_TAB'] }),
  }
)

Поля ответа

Поле Тип Описание
success boolean true при успешной публикации
data object Приложение после публикации — тот же набор полей, что отдаёт данные приложения
data.placements string[] Привязанные места встраивания
data.catalogStatus string После публикации — PUBLISHED
data.publishedAt string | null Дата публикации, ISO 8601
warnings string[] Предупреждения, не отменяющие публикацию. Часть мест встраивания не удалось привязать — строка перечисляет коды. Про снятие лишних мест строка приходит по-разному в зависимости от раскатки — разбор во врезке под таблицей ошибок. Переданный sourceServerId не был использован, потому что хранилище исходников для портала отключено. Опубликованная версия сервера осталась без бессрочного хранения — тогда строка несёт готовый PATCH, которым её можно пометить. Название или описание карточки потеряли не-ASCII символы по дороге — строка называет поле. Набор строк открытый: незнакомую строку показывайте как есть, а не отбрасывайте

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

Поле data повторяет объект приложения с заполненным массивом placements:

JSON
{
  "success": true,
  "data": {
    "id": "33c4d5e6-f7a8-49b0-1234-5c6d7e8f9012",
    "title": "Дашборд продаж",
    "description": null,
    "scopes": ["crm", "user", "placement"],
    "handlerUrl": "https://vibecode.bitrix24.tech/v1/bitrix-handler",
    "appUrl": "https://app-abc12345.vibecode.bitrix24.tech",
    "redirectUris": [
      "https://vibecode.bitrix24.tech/oauth/complete",
      "http://localhost"
    ],
    "bitrixClientId": "local.7c3d4e5f6a7b80.55556666",
    "prefix": "vibe_app_local_7c3",
    "suffix": "6666",
    "authorId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "portalId": "8b1f0e2a-3c4d-5e6f-7a8b-9c0d1e2f3a4b",
    "createdAt": "2026-06-24T09:12:45.781Z",
    "updatedAt": "2026-06-24T10:03:18.204Z",
    "placements": ["CRM_DEAL_DETAIL_TAB"],
    "catalogStatus": "PUBLISHED",
    "publishedAt": "2026-06-24T10:03:18.204Z"
  }
}

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

400 — у OAuth-ключа нет скоупа placement:

JSON
{
  "success": false,
  "error": {
    "code": "MISSING_SCOPE",
    "message": "OAuth API key must have the placement scope to publish (catalog publishing binds placements on Bitrix24)."
  }
}

Ошибки

HTTP Код Описание
403 INFRA_FORBIDDEN_FOR_COWORK_KEY Вызов сделан ключом Cowork/Code — такой ключ работает только с данными, изменяющие операции ему закрыты. Что делать — Проектный ключ для деплоя
404 NOT_FOUND Приложение не найдено или принадлежит другому порталу
403 FORBIDDEN Вызов сделан ключом авторизации vibe_app_…, выписанным на другое приложение. Таким ключом публикуют только своё приложение, даже если оба приложения создал один автор
403 FORBIDDEN Запрос не от автора приложения и не от администратора портала
409 ALREADY_PUBLISHED Приложение уже в статусе PUBLISHED
400 VALIDATION_ERROR Поле тела не прошло проверку — в message перечислены поля и причины отказа
400 VALIDATION_ERROR Заголовок X-Source-Server передан больше одного раза. Передавайте его один раз с одним идентификатором сервера
400 VALIDATION_ERROR Значение заголовка X-Source-Server не является идентификатором сервера в форме UUID
400 NO_OAUTH_KEY У приложения нет связанного OAuth-ключа
400 MISSING_SCOPE У OAuth-ключа нет скоупа placement
409 SNAPSHOT_REQUIRED Включено хранилище исходников, но сохранённого снапшота нет. Возраст снапшота на исход проверки не влияет. Тело несёт hint: без sourceServerId он ведёт на POST /v1/apps/:id/sources и объясняет, как опубликовать исходники с сервера. С sourceServerId — на POST /v1/infra/servers/:id/sources. Поле hint.reason различает две причины отказа — снапшота нет у приложения или у названного сервера. Ещё два значения приходят, только когда платформа проверяет возраст снапшота. Состав полей подсказки описан в Хранилище исходников
404 SERVER_NOT_FOUND Передан sourceServerId сервера, которого нет, который принадлежит другому порталу или который удалён
403 NOT_AUTHORIZED Передан sourceServerId сервера, исходники которого запрос не вправе использовать. Права на приложение сюда не распространяются — запрос должен идти от ключа-владельца сервера, личного ключа того же пользователя или администратора портала
400 NO_USER_TOKEN Приложение не авторизовано на портале по OAuth. Пройдите авторизацию и повторите публикацию — Авторизация пользователей приложения. Тело несёт hint из трёх полей: requiredAction — что сделать, docsUrl — эта страница, oauthDocsUrl — порядок авторизации. Набор полей у этой подсказки свой, он не совпадает с подсказкой SNAPSHOT_REQUIRED
400 TITLE_TOO_LONG_FOR_CATALOG Итоговое название длиннее 100 символов. Так бывает, когда catalogTitle не передан, а title приложения длиннее предела каталога
502 PLACEMENT_UNBIND_FAILED Аккаунт не подтвердил снятие лишних мест встраивания. Приложение НЕ опубликовано, метаданные каталога из этого запроса не сохранены. Коды, которые остались на аккаунте, перечислены в error.placements. Поле placements приложения при этом уже перезаписано — перечитайте приложение. Приходит только после включения проверки — см. врезку ниже
503 NETWORK_DEVKEY_REQUIRED Аккаунт переведён на транспорт ключа разработчика, а у автора приложения такого ключа нет. Повтор не поможет — попросите автора переподключить аккаунт. Приходит только после включения проверки — см. врезку ниже

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

Проверка снятия лишних мест встраивания на стороне аккаунта сейчас раскатывается по аккаунтам, поэтому вариантов два:

  • Пока возможность не включена на аккаунте — публикация отвечает 200, даже если снять лишние места на аккаунте не удалось. Неснятый код при этом ОСТАЁТСЯ в placements приложения, а причина приходит строкой Failed to unbind <код> в warnings. Это единственный признак расхождения списка с аккаунтом, поэтому сейчас warnings надо разбирать. Кодов PLACEMENT_UNBIND_FAILED и NETWORK_DEVKEY_REQUIRED у этого эндпоинта не бывает.
  • После включения — неподтверждённое снятие отвечает 502 PLACEMENT_UNBIND_FAILED со списком кодов в error.placements, а приложение не публикуется вовсе. Ответа 200 с неснятым местом на этом пути не бывает — про снятие в warnings успешного ответа остаются пояснения о подтверждении: каким транспортом снятие подтверждено и отказало ли при этом второе плечо. Остальные строки набора включение не меняет — отказы привязки и прочие поводы из таблицы warnings выше приходят и на этом пути.

Отказ 502 здесь не означает «ничего не изменилось». Поле placements приложения записывается ДО того, как выносится отказ, и уже отражает фактическое состояние аккаунта: успешно снятые коды из него ушли, а неподтверждённые остались. Поэтому перед повтором перечитайте приложение через данные приложения. Повторный запрос без поля placements опубликует ровно тот набор, который лежит в приложении сейчас, — вместе с местом, которое вы считали снятым. Чтобы снять его, повторите запрос с явным placements без этого кода.

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

  • Публикация требует авторизации приложения на портале. Привязку мест встраивания выполняет OAuth-токен приложения, поэтому перед первой публикацией приложение проходит авторизацию на портале хотя бы один раз. Без неё публикация возвращает NO_USER_TOKEN. Порядок авторизации — Авторизация пользователей приложения. Для публикации достаточно пройти согласие на портале. Забирать токен сессии не нужно — платформа сохраняет токен приложения на возврате.
  • Вход на странице самого приложения токен приложения не создаёт. Кнопка «Войти через Bitrix24» на адресе вашего приложения выдаёт доступ к приложению — это другая поверхность, и на NO_USER_TOKEN при публикации она не влияет. Токен появляется только на согласии OAuth на стороне портала: авторизация по ссылке выше, установка приложения на портал или первое открытие встроенного места. Если после входа на странице приложения публикация всё ещё отвечает NO_USER_TOKEN — авторизации на портале не было.
  • Токен живёт долго и продлевается сам. Авторизация нужна один раз, а не перед каждой публикацией: платформа обновляет токен по refresh-токену. Повторная авторизация требуется, только если доступ отозвали на портале или OAuth-приложение пересоздали.
  • autoSaved: true у деплоя не всегда закрывает проверку публикации. Автосейв деплоя сохраняет исходники у того сервера, на который вы деплоили. Если этот сервер принадлежит не OAuth-ключу публикуемого приложения (например, вы деплоили личным ключом vibe_api_), снапшот хранится у сервера — проверка публикации по умолчанию смотрит снапшоты приложения и его не видит. Передайте sourceServerId того же сервера, и публикация возьмёт исходники оттуда — повторно сохранять их через POST /v1/apps/:id/sources не нужно. Идентификатор сервера — тот же, что в адресе деплоя. Список снапшотов сервера — GET /v1/infra/servers/:serverId/sources.
  • Заголовок места встраивания — это название приложения. Пункт левого меню и вкладки CRM подписываются итоговым catalogTitle, отдельного названия для меню нет. Переименование приложения через обновление меняет и подписи мест встраивания.
  • Снятые с публикации приложения публикуются повторно. Публикация принимается и в статусе UNPUBLISHED — приложение возвращается в PUBLISHED с теми же или новыми местами встраивания. Метаданные каталога при снятии с публикации сохранялись, поэтому при пустом теле каталог восстанавливается без повторного заполнения.
  • Часть мест встраивания может не привязаться. Привязка идёт по каждому коду отдельно. Коды, которые не удалось привязать, не прерывают публикацию — приложение становится PUBLISHED, а несработавшие коды перечисляются в warnings.

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