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

Исход выкладки

GET /v1/infra/operations/:operationId

Возвращает исход конкретной выкладки по её идентификатору. Нужен, когда соединение с POST /deploy оборвалось и терминальный ответ до клиента не дошёл: идентификатор выдаётся до начала работы, поэтому по нему можно узнать, чем всё кончилось, вместо того чтобы запускать выкладку заново.

Ручка только на чтение, побочных действий у неё нет. Каждая выкладка адресуется отдельно, включая предыдущие попытки на том же сервере. Исход хранится 7 суток.

Идентификатор выдаётся только при выкладке на отдельную виртуальную машину (kind: "STANDALONE"). У galaxy-приложения (kind: "GALAXY_APP") его нет, и сверить исход такой выкладки этой ручкой пока нельзя.

Где взять идентификатор — три канала, все три несёт одна и та же выкладка:

  • заголовок ответа X-Vibe-Operation-Id — приходит сразу, до начала долгой работы;
  • первый кадр event: operation при ?stream=true — браузерный EventSource заголовков ответа не отдаёт, поэтому для него это единственный доступный канал;
  • поле operationId в теле — data.operationId при успехе, error.operationId при отказе.

Отсутствие идентификатора не означает, что выкладка не запускалась. Если платформа не смогла завести запись, выкладка продолжается без идентификатора, а заголовка, кадра и поля не будет. Читать это как отказ и повторять выкладку нельзя — второй запуск ляжет поверх приложения, которое уже могло подняться.

Параметры

Параметр В Тип Обяз. Описание
operationId path string да Идентификатор операции из ответа POST /deploy

Примеры

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

Terminal
curl -H "X-Api-Key: YOUR_API_KEY" \
  https://vibecode.bitrix24.tech/v1/infra/operations/OPERATION_ID

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

Terminal
curl -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  https://vibecode.bitrix24.tech/v1/infra/operations/OPERATION_ID

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

javascript
// Выкладка: забираем идентификатор из заголовка ДО того, как придёт тело
const deploy = await fetch(
  `https://vibecode.bitrix24.tech/v1/infra/servers/${serverId}/deploy`,
  {
    method: 'POST',
    headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
    body: JSON.stringify({ source: { content: archiveBase64 }, start: 'node index.js' }),
  }
)
const operationId = deploy.headers.get('X-Vibe-Operation-Id')

// Связь оборвалась — спрашиваем исход вместо повторной выкладки
const res = await fetch(
  `https://vibecode.bitrix24.tech/v1/infra/operations/${operationId}`,
  { headers: { 'X-Api-Key': 'YOUR_API_KEY' } }
)

if (res.status === 410) {
  console.log('Операция была, исход больше не хранится')
} else if (res.status === 404) {
  console.log('Такой операции нет')
} else {
  const { data } = await res.json()
  console.log(`Статус: ${data.status}, шаг: ${data.step}`)
}

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

javascript
const res = await fetch(
  `https://vibecode.bitrix24.tech/v1/infra/operations/${operationId}`,
  {
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
    },
  }
)

Поля ответа

Поле Тип Описание
success boolean Всегда true при успехе
data.operationId string Идентификатор операции
data.kind string Вид операции. Сейчас всегда deploy
data.serverId string ID сервера, на котором шла выкладка
data.status string running, succeeded, failed или unknown — см. таблицу ниже
data.step string | null Шаг конвейера, на котором операция находится или на котором остановилась
data.startedAt string Время старта, ISO 8601
data.finishedAt string | null Время завершения, ISO 8601. null, пока операция идёт
data.error object | null { code, message } при status: "failed", иначе null

Значения data.status:

Значение Что означает
running Выкладка идёт прямо сейчас
succeeded Выкладка завершилась успешно
failed Выкладка провалилась, причина — в data.error
unknown Процесс прервался между стартом и записью исхода, поэтому исход неизвестен. Не то же самое, что «выкладки не было»: операция точно запускалась. Текущее состояние сервера смотрите в GET /v1/infra/servers/:id

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

Выкладка идёт:

JSON
{
  "success": true,
  "data": {
    "operationId": "clz9k2m4x0001qw8h3f7d2n5p",
    "kind": "deploy",
    "serverId": "8f14e45f-ceea-467a-9c8d-2f1c5a6b7e30",
    "status": "running",
    "step": "install",
    "startedAt": "2026-08-11T09:14:22.117Z",
    "finishedAt": null,
    "error": null
  }
}

Выкладка завершилась успешно:

JSON
{
  "success": true,
  "data": {
    "operationId": "clz9k2m4x0001qw8h3f7d2n5p",
    "kind": "deploy",
    "serverId": "8f14e45f-ceea-467a-9c8d-2f1c5a6b7e30",
    "status": "succeeded",
    "step": null,
    "startedAt": "2026-08-11T09:14:22.117Z",
    "finishedAt": "2026-08-11T09:18:04.902Z",
    "error": null
  }
}

Выкладка провалилась:

JSON
{
  "success": true,
  "data": {
    "operationId": "clz9k2m4x0001qw8h3f7d2n5p",
    "kind": "deploy",
    "serverId": "8f14e45f-ceea-467a-9c8d-2f1c5a6b7e30",
    "status": "failed",
    "step": "healthcheck",
    "startedAt": "2026-08-11T09:14:22.117Z",
    "finishedAt": "2026-08-11T09:17:41.338Z",
    "error": {
      "code": "DEPLOY_STEP_FAILED",
      "message": "connect ECONNREFUSED 127.0.0.1:3000"
    }
  }
}

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

410 — операция была, но исход уже не хранится:

JSON
{
  "success": false,
  "error": {
    "code": "OPERATION_OUTCOME_EXPIRED",
    "message": "The outcome of this deploy is no longer stored (kept for 7 days).",
    "serverId": "8f14e45f-ceea-467a-9c8d-2f1c5a6b7e30",
    "startedAt": "2026-07-30T11:02:19.400Z"
  }
}

Ошибки

HTTP Код Описание
400 INVALID_OPERATION_ID Идентификатор не той формы, которую выдаёт платформа
401 MISSING_API_KEY Не передан заголовок X-Api-Key
401 INVALID_API_KEY Неверный или просроченный API-ключ
404 OPERATION_NOT_FOUND Операции нет, она принадлежит другому ключу либо запись уже удалена
410 OPERATION_OUTCOME_EXPIRED Операция ваша, но её исход больше не хранится
429 RATE_LIMITED Превышен лимит опроса

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

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

  • Чужая операция отвечает так же, как несуществующая — это сделано намеренно. Все три случая (идентификатора нет, идентификатор чужой, запись удалена) дают один и тот же 404. Отдельный ответ на чужую операцию подтверждал бы, что такой идентификатор существует, а идентификатор сам по себе является ключом доступа к записи: подобрав его, можно было бы прочитать чужую выкладку.
  • 410 отличается от 404 только для владельца. «Исход больше не хранится» приходит, когда операция ваша и она точно была, просто прошло больше 7 суток. На чужой или выдуманный идентификатор такой ответ не приходит никогда.
  • Запись живёт дольше, чем хранится исход. Через 7 суток исход перестаёт отдаваться, но сам факт операции сохраняется ещё некоторое время — за счёт этого и возможен различимый ответ 410. Потом запись удаляется, и тот же идентификатор начинает отвечать 404.
  • unknown — это ответ, а не ошибка. Он означает, что процесс выкладки прервался между стартом и записью исхода: операция точно была, но чем кончилась — платформа не знает. Смотрите текущее состояние сервера и, если приложение не поднялось, выкладывайте заново.
  • Лимит опроса — 60 запросов в минуту на ключ. Исход не меняется чаще, чем идёт сама выкладка, поэтому опрашивать раз в несколько секунд достаточно.

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