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

Создать сервер

POST /v1/infra/servers

Создаёт приложение у облачного провайдера. Всегда в режиме Black Hole — iptables блокирует все входящие порты, приложение невидимо из интернета. На части серверов в правилах остаётся одна служебная запись: вход по SSH с единственного адреса платформы, он нужен для переустановки агента.

На портале есть две модели размещения, и от модели зависит, чего ждать после создания:

  • Отдельная виртуальная машина (модель по умолчанию). Если под выбранный тариф есть заранее подготовленная машина, платформа настраивает её и только потом отвечает — уже со статусом running и с IP-адресом. Иначе платформа отвечает сразу со статусом provisioning и создаёт машину с нуля — на это уходит 1–3 минуты. В обоих случаях опрашивайте GET /v1/infra/servers/:id до status: "running" и blackholeStatus: "CONNECTED". Ответ единственный раз содержит SSH-данные ssh.password и ssh.privateKey — они будут нужны при переключении в режим OPEN, сохраните их сразу. Эта страница описывает данную модель в полях запроса, полях ответа и таблице ошибок ниже.
  • Galaxy-приложение — контейнер на общем хосте. Если портал размещает приложения в галактиках, тот же POST /v1/infra/servers создаёт galaxy-приложение, а не виртуальную машину. Признак модели в ответе — поле createdVia равно galaxy. Раздел «Galaxy-приложение» ниже описывает два сценария запуска, полная модель — на странице Galaxy-приложение.

Galaxy-приложение

Если портал размещает приложения в галактиках, POST /v1/infra/servers создаёт galaxy-приложение — контейнер на общем хосте, а не отдельную виртуальную машину. Запрос и порядок вызовов те же, отличается жизненный цикл. Признак модели в ответе — поле createdVia равно galaxy. Полная модель, стоимость и отличия деплоя — на странице Galaxy-приложение.

Не ждите CONNECTED перед загрузкой кода. Galaxy-приложение никогда само не доходит до blackholeStatus: "CONNECTED" — его контейнер собирается при загрузке кода. Если просто опрашивать статус, приложение останется в provisioning, а примерно через 20 минут платформа пометит его как error и запишет в поле provisionError, что код так и не был загружен. Поэтому код загружают сразу — одним из двух сценариев ниже.

Сценарий 1 — прозрачный, рекомендуется

Один запрос. Передайте в POST /v1/infra/servers код приложения в поле source вместе с runtime и start (и при необходимости install, env, port). Сборка пойдёт в фоновом режиме. После ответа опрашивайте GET /v1/infra/servers/:id до status: "running". Отдельный вызов загрузки кода не нужен.

Terminal
curl -X POST https://vibecode.bitrix24.tech/v1/infra/servers \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-crm-app",
    "displayName": "Мой CRM-бот",
    "source": { "content": "<base64-архив>" },
    "runtime": "node20",
    "start": "node index.js",
    "install": "npm ci",
    "port": 3000
  }'

Поля source, runtime, start, install, env, port, healthPath совпадают по смыслу с телом POST /:id/deploy:

Поле Тип Обяз. Описание
source object да (для этого сценария) Источник кода. source.content — архив приложения в base64, до 96 МБ на тело запроса, то есть около 72 МБ самого архива: base64 тяжелее исходных байт примерно на треть. Тело сверх потолка отклоняется кодом 413 INLINE_SOURCE_TOO_LARGE. Архив крупнее разворачивайте в два шага — сценарий 2 ниже
runtime string да (если передан source) ID рантайма: node20, python311, php83, static и другие. Список — GET /v1/infra/runtimes
start string да (если передан source) Команда запуска приложения, одной строкой. Перенос строки вернёт 400
install string нет Команда установки зависимостей, одной строкой
env object нет Переменные окружения { "KEY": "value" }. Подставляются в контейнер при запуске, см. ниже
port number нет Порт, на котором приложение слушает
healthPath string нет Путь, по которому платформа проверяет готовность приложения внутри контейнера. До 500 символов, начинается со /. По умолчанию /. На создании отдельной виртуальной машины игнорируется

Других полей деплоя одношаговое создание не принимает: preStart, systemd, serviceName, cleanDeploy, extractTo, hardening, preserveEnv, dataDirs, dataDirsRecursive вернут 400 UNKNOWN_PARAM, а полный список допустимых полей придёт в details.validParams. Эти поля относятся к деплою отдельной виртуальной машины и к galaxy-приложению не применяются — команды, которые нужно выполнить до старта приложения, задавайте в install.

Без полей runtime и start поле source вернёт 400 — оба поля обязательны. На портале без режима галактик новый запрос с source запрещён и вернёт 400 SOURCE_AT_CREATE_GALAXY_ONLY. Повтор, который безопасно сходится на уже создаваемом keyless GALAXY_APP, выполняет это схождение раньше fresh-only отказа: возвращает прежний id с sourceIgnored: true и не запускает вторую сборку.

На пробном периоде сначала прочитайте блоки deployment и capabilities.servers.create из GET /v1/me. Если galaxyApp присутствует, одношаговое создание стоит попробовать, но этот блок отражает сохранённое состояние и не гарантирует успех: текущую вместимость проверяет только POST. Если режима галактик нет, placementNote отсутствует, а запрос с source возвращает 400 SOURCE_AT_CREATE_GALAXY_ONLY. При отсутствии хоста и в режиме отдельной машины двухшаговый путь разрешён, только когда capabilities.servers.create.available равен true; допустимый идентификатор тарифа выберите из capabilities.servers.create.limits.allowedPlans. Если существующий хост непригоден, для нового one-shot запроса дождитесь его восстановления, попросите администратора починить его либо повысьте тариф. Пока available равен false, не переходите на отдельную машину: при включённом контроле trial-ограничений занятый слот даёт 402 TRIAL_PORTAL_LIMIT. После удаления хоста заново прочитайте GET /v1/me и используйте объявленный там двухшаговый путь.

Сценарий 2 — в два шага

Создайте приложение без source — ответ придёт со статусом provisioning и подсказкой next: "deploy". Сразу вызовите POST /v1/infra/servers/:id/deploy с кодом в source, рантаймом и командой запуска. Загружайте код сразу, не дожидаясь CONNECTED.

Terminal
# Шаг 1 — создать приложение без кода
curl -X POST https://vibecode.bitrix24.tech/v1/infra/servers \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "provider": "bitrix-cloud", "name": "my-crm-app", "plan": "bc-medium", "region": "ru-central1-a" }'

# Ответ содержит data.id, data.next = "deploy" и data.hint.
# Шаг 2 — сразу загрузить код, не дожидаясь CONNECTED
curl -X POST https://vibecode.bitrix24.tech/v1/infra/servers/SERVER_ID/deploy \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "source": { "content": "<base64-архив>" },
    "runtime": "node20",
    "start": "node index.js",
    "port": 3000
  }'

provider и plan обязательны по схеме для создания без source. region необязателен: без него платформа сама подставит регион по умолчанию для выбранного провайдера. Для galaxy-приложения значения информационны — приложение наследует провайдера, план и регион своего хоста.

Если присланное значение расходится с тем, что приложение реально получило, ответ несёт запись в warnings[] рядом с data: она называет разошедшиеся поля, показывает и присланное, и действующее значение и предупреждает, что повторная отправка ничего не изменит. Совпавшие поля не упоминаются, так что корректный вызов остаётся без предупреждения. Нужна машина, у которой провайдера, план и регион выбираете вы, — создавайте её с placement равным dedicated.

Отдельная виртуальная машина вместо galaxy-приложения

Если портал размещает приложения в галактиках, а конкретному приложению нужен свой сервер — передайте поле placement равным dedicated. Пара provider, plan при этом обязательна, region по-прежнему необязателен. Поле source в таком запросе вернёт 400 SOURCE_AT_CREATE_GALAXY_ONLY: отдельная виртуальная машина разворачивается в два шага, код загружают через POST /:id/deploy.

Terminal
curl -X POST https://vibecode.bitrix24.tech/v1/infra/servers \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "bitrix-cloud",
    "name": "my-crm-app",
    "plan": "bc-small",
    "region": "ru-central1-b",
    "placement": "dedicated"
  }'

В ответе kind равен STANDALONE. Дальше действует порядок для отдельной виртуальной машины: дождаться status: "running" и blackholeStatus: "CONNECTED", затем деплой.

Диагностика и переменные окружения

  • Поле provisionError. Если сборка или запуск упали, GET /v1/infra/servers/:id вернёт в data.provisionError причину сбоя, а при ошибке сборки образа — ещё и хвост лога сборки Docker. Читайте это поле, чтобы понять причину.
  • Переменные env подставляются при запуске. Значения из env передаются в контейнер во время запуска через docker run --env, а не вшиваются в образ. Вместе с ними платформа передаёт PORT (равен полю port, по умолчанию 3000): ключ PORT зарезервирован, присланный свой перекрывается, и ответ несёт строку в warnings[] — см. POST /v1/infra/servers/:id/deploy. Поэтому ключи API и секреты из env не попадают в слои образа.

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

Поле Тип Обяз. Описание
provider string да ID провайдера из GET /v1/infra/providers, например bitrix-cloud. 1–50 символов
name string да Системное имя сервера — технический идентификатор. 2–63 символа, только строчные латинские буквы, цифры и -, первым символом — буква. Паттерн: ^[a-z][a-z0-9-]*$. Используется в URL поддомена (app-<hex> генерируется отдельно), логах, audit-журнале. Неизменяемый после создания. Для отображаемого имени используйте displayName
displayName string нет Отображаемое имя на любом языке (русский, китайский, эмодзи — что угодно). 2–100 символов, без управляющих байтов. Отображается в UI, уведомлениях о падении сервера, security-алертах, биллинг-строках, B24-каталоге. Если не передан — подставится name. Само name остаётся техническим идентификатором, неизменяемым, оно используется в URL поддомена и логах
description string нет Описание приложения для карточки каталога Битрикс24, до 500 символов. Переносы строк и табуляции разрешены, прочие управляющие байты запрещены. Значение обрезается по краям. Если не передать — описание останется пустым, задать его позже можно через PATCH /v1/infra/servers/:id
plan string да ID тарифа из GET /v1/infra/providers/:providerId/plans, например bc-small
region string нет ID региона из GET /v1/infra/providers/:providerId/regions, например ru-central1-b. Без него платформа подставит регион по умолчанию для провайдера
image string нет Публичный идентификатор образа ОС из GET /v1/infra/providers/:providerId/images. Можно передать стабильное семейство, например ubuntu-2404-lts: платформа сама разрешит его в актуальный конкретный образ провайдера. Если поле не передано, разрешается образ провайдера по умолчанию
sshPublicKey string нет Ваш SSH-публичный ключ (ssh-rsa …, ssh-ed25519 …, ecdsa-sha2-nistp256/384/521 …, security-keys). До 8192 символов. Платформа ставит его рядом со своим ключом: на заранее подготовленную машину — до ответа о создании, на создаваемую с нуля — во время подготовки
placement string нет Модель размещения: auto (по умолчанию) или dedicated. На портале с режимом «Сначала галактика» (galaxies-only) значение dedicated создаёт отдельную виртуальную машину, а не galaxy-приложение — перенос приложения на собственный сервер. Проходит те же проверки, что и обычное создание сервера: политику serverCreation и квоту серверов на пользователя. При auto поведение прежнее (в режиме «Сначала галактика» создаётся galaxy-приложение)
graduateFrom string нет ID вашего galaxy-приложения (kind=GALAXY_APP), которое платформа удалит сразу после того, как создаст для него выделенный сервер — чтобы старое приложение не осталось висеть в галактике. Ограничен владельцем: тот же ключ, тот же портал, kind=GALAXY_APP. Чужой идентификатор или идентификатор не galaxy-приложения вернёт 404, ничего не удаляя. Имеет смысл только вместе с placement: dedicated. Заголовок Idempotency-Key с graduateFrom для выделенного сервера несовместим — см. Идемпотентность
runMode object нет Режим работы, в котором сервер рождается. Та же форма, что у PATCH /:id/run-mode: {"mode": "ALWAYS"}, {"mode": "IDLE", "idleMinutes": 15|30|60|240} или {"mode": "SCHEDULE", "scheduleId": "…"}. Разбор идёт по полю mode, поэтому лишнее поле рядом с режимом отвергается, а не выбрасывается молча. Отказ приходит ДО создания машины, поэтому неудачный запрос не оставляет сервер. Без блока сервер рождается на расписании, которое администратор портала отметил для новых машин, — Отметить расписание по умолчанию. Без такой отметки действует таймаут авто-сна по умолчанию из «Известных особенностей»

Примечание: для модели отдельной виртуальной машины параметр runtime в POST /v1/infra/servers не принимается — передача вернёт 400 RUNTIME_PARAM_REMOVED. Рантайм устанавливается на этапе деплоя. См. POST /:id/deploy. Исключение — режим галактик: при передаче поля source параметр runtime обязателен (см. раздел «Galaxy-приложение»), и 400 RUNTIME_PARAM_REMOVED в этом случае не возвращается.

Примеры

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

Terminal
# name — только строчные латинские буквы, цифры и дефис, первый символ буква (^[a-z][a-z0-9-]*$)
curl -X POST https://vibecode.bitrix24.tech/v1/infra/servers \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "bitrix-cloud",
    "name": "my-crm-app",
    "displayName": "Мой CRM-бот",
    "plan": "bc-small",
    "region": "ru-central1-b",
    "image": "fd83esfomhq25p2ono90"
  }'

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

Terminal
# name — только строчные латинские буквы, цифры и дефис, первый символ буква (^[a-z][a-z0-9-]*$)
curl -X POST https://vibecode.bitrix24.tech/v1/infra/servers \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "bitrix-cloud",
    "name": "my-crm-app",
    "displayName": "Мой CRM-бот",
    "plan": "bc-small",
    "region": "ru-central1-b",
    "image": "fd83esfomhq25p2ono90"
  }'

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

javascript
// name — только строчные латинские буквы, цифры и дефис, первый символ буква (^[a-z][a-z0-9-]*$)
const res = await fetch('https://vibecode.bitrix24.tech/v1/infra/servers', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    provider: 'bitrix-cloud',
    name: 'my-crm-app',
    displayName: 'Мой CRM-бот',
    plan: 'bc-small',
    region: 'ru-central1-b',
    image: 'fd83esfomhq25p2ono90',
  }),
})
const { data } = await res.json()
console.log('Server ID:', data.id, 'Subdomain:', data.subdomain)

// Сохраняем SSH-креды на всякий случай — они возвращаются только один раз
if (data.ssh?.privateKey) {
  await saveLocally(`${data.id}.key`, data.ssh.privateKey)
}

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

javascript
// name — только строчные латинские буквы, цифры и дефис, первый символ буква (^[a-z][a-z0-9-]*$)
const res = await fetch('https://vibecode.bitrix24.tech/v1/infra/servers', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    provider: 'bitrix-cloud',
    name: 'my-crm-app',
    displayName: 'Мой CRM-бот',
    plan: 'bc-small',
    region: 'ru-central1-b',
    image: 'fd83esfomhq25p2ono90',
  }),
})

Поля ответа

Поле Тип Описание
success boolean Всегда true при успехе
data.id string (UUID) Уникальный идентификатор сервера
data.status string "running", если платформа взяла заранее подготовленную машину. Иначе "provisioning" — ждите "running" через 1–3 минуты. При повторе с тем же Idempotency-Key — статус сервера на момент повтора. В reuse-ответе (reused: true) это статус существующего сервера и он может быть любым, в том числе сразу "running" — тогда ожидание "running" ничего не проверяет
data.provider string Эхо переданного provider. Исключение — galaxy-приложение (createdVia: "galaxy"): возвращается провайдер хоста-носителя, а не запрошенный
data.name string Системное имя сервера. Эхо переданного name при создании нового. В reuse-ответе — имя существующего сервера, а запрошенное вами лежит в data.requestedName
data.kind string Тип сервера, всегда: STANDALONE или GALAXY_APP
data.galaxyId string Только для galaxy-ветки — ID хоста-галактики. В standalone-ответе ключ отсутствует
data.displayName string | null Отображаемое имя. Если при создании не передавали displayName — будет равно name
data.description string | null Эхо переданного description. Ключ есть только в ответе для отдельной виртуальной машины. Для galaxy-приложения, где createdVia равно galaxy, ключа в ответе нет, хотя описание сохраняется — прочитайте его через GET /v1/infra/servers/:id
data.ip string | null Публичный IP. У заранее подготовленной машины приходит сразу. У машины, созданной с нуля, — null. Адрес появится после её запуска
data.ssh.user string Пользователь для SSH: root для новых серверов
data.ssh.port number Порт SSH: 22
data.ssh.password string | null Одноразово! Пароль root. Сохраняйте сразу — позже не вернётся. Нужен при переключении в OPEN-режим
data.ssh.privateKey string | null Одноразово! Приватный ключ платформы в формате OpenSSH. Приходит и тогда, когда вы передали свой sshPublicKey. null — при повторе с тем же Idempotency-Key, см. Идемпотентность. В ответе переиспользования и у galaxy-приложения null весь блок ssh. Сохраняйте сразу
data.plan string Эхо переданного plan. Исключение — galaxy-приложение (createdVia: "galaxy"): возвращается тариф хоста-носителя, а не запрошенный
data.region string Регион, в который сервер реально попал. Может отличаться от запрошенного при переключении на запасную зону (см. «Известные особенности»). Для galaxy-приложения — регион хоста-носителя
data.image string Разрешённый публичный идентификатор образа. Если image не передавали, это может быть образ провайдера по умолчанию. Конкретный образ провайдера может быть нормализован обратно в стабильное семейство
data.mode string Всегда "BLACKHOLE" сразу после создания
data.createdVia string "api" для вызовов через v1 API, "ui" для вызовов из личного кабинета. В reuse-ответе — значение существующего сервера, поэтому на ответ v1-создания может прийти "ui"
data.subdomain string Субдомен для приложения, например app-92fb1c34. Используется в appUrl
data.blackholeStatus string Состояние туннеля агента. У машины, созданной с нуля, — "NONE", пока агент не подключится, затем "CONNECTED". У заранее подготовленной машины ответ несёт "NONE" или уже "CONNECTED"
data.accessPolicy string Политика доступа к приложению. По умолчанию "OWNER_ONLY" — только владелец ключа
data.sleepAfterMinutes number | null Сохранённый таймаут авто-сна в минутах. Поле есть в каждом успешном 201-ответе — для новой отдельной машины и galaxy-приложения, а также при reuse и idempotency replay. null — сохранённый выбор «Никогда»: без действующего расписания авто-сон отключён, а с ним применяется платформенный таймаут после окна
data.runtimeId string | null Всегда null при создании. Заполняется при деплое с runtime
data.runtimeStatus string | null Устаревшее поле, оставлено для совместимости. Для серверов, созданных после 2026-04-25, всегда null. Готовность рантайма после деплоя определяет успех шага runtime в ответе POST /:id/deploy, а не это поле
data.appUrl string | null HTTPS-адрес приложения: https://{subdomain}.vibecode.bitrix24.tech
data.createdAt string (ISO 8601) Момент создания
warnings array<string> Рядом с data, не внутри. Приходит, только если есть что сказать: например, displayName или description потеряли не-ASCII символы по дороге (типичный случай — Windows PowerShell без явной сериализации в UTF-8). Сервер при этом создаётся, а обе строки уезжают в карточку каталога Битрикс24 как есть

data.sleepAfterMinutes — поле ответа, а не параметр создания. Чтобы изменить сохранённую политику после создания отдельной машины, вызовите PATCH /v1/infra/servers/:id/sleep. Не подставляйте в это поле ожидаемый дефолт: при reuse или idempotency replay ответ возвращает значение уже существующей записи, в том числе null или историческое числовое значение. Поле не является вычисленным фактическим таймаутом: при null и действующем расписании пробуждения применяется платформенный запас после окна, по умолчанию 15 минут.

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

Отдельная виртуальная машина, созданная с нуля:

JSON
{
  "success": true,
  "data": {
    "id": "db008c84-91a5-4e15-b9d5-6c6aa2838448",
    "status": "provisioning",
    "provider": "bitrix-cloud",
    "name": "docs-test-temp",
    "kind": "STANDALONE",
    "ip": null,
    "ssh": {
      "user": "root",
      "port": 22,
      "password": "0FPIIR9EfO2OAeSSMK6bKA",
      "privateKey": "-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmU…\n-----END OPENSSH PRIVATE KEY-----\n"
    },
    "plan": "bc-agent",
    "region": "ru-central1-b",
    "image": "fd83esfomhq25p2ono90",
    "mode": "BLACKHOLE",
    "createdVia": "api",
    "subdomain": "app-92fb1c34",
    "blackholeStatus": "NONE",
    "accessPolicy": "OWNER_ONLY",
    "sleepAfterMinutes": 60,
    "runtimeId": null,
    "runtimeStatus": null,
    "appUrl": "https://app-92fb1c34.vibecode.bitrix24.tech",
    "createdAt": "2026-04-22T10:50:11.477Z"
  }
}

У заранее подготовленной машины в этом ответе status равен running, а ip заполнен.

Galaxy-приложение по сценарию 1 — source передан, сборка идёт в фоне. Поле ssh равно null. Поля next нет:

JSON
{
  "success": true,
  "data": {
    "id": "7c2b1f08-3a4d-4e91-9b6c-2f5e8a1d0c33",
    "status": "provisioning",
    "provider": "bitrix-cloud",
    "name": "my-crm-app",
    "kind": "GALAXY_APP",
    "galaxyId": "<galaxy-host-id>",
    "displayName": "Мой CRM-бот",
    "ip": null,
    "ssh": null,
    "plan": "bc-medium",
    "region": "ru-central1-a",
    "image": "ubuntu-2404-lts",
    "mode": "BLACKHOLE",
    "createdVia": "galaxy",
    "subdomain": "app-7c2b1f08",
    "blackholeStatus": "NONE",
    "accessPolicy": "OWNER_ONLY",
    "sleepAfterMinutes": 60,
    "runtimeId": null,
    "runtimeStatus": null,
    "appUrl": "https://app-7c2b1f08.vibecode.bitrix24.tech",
    "createdAt": "2026-04-22T10:50:11.477Z"
  }
}

Galaxy-приложение по сценарию 2 — source не передан, появляются next и hint:

JSON
{
  "success": true,
  "data": {
    "id": "7c2b1f08-3a4d-4e91-9b6c-2f5e8a1d0c33",
    "status": "provisioning",
    "provider": "bitrix-cloud",
    "name": "my-crm-app",
    "kind": "GALAXY_APP",
    "galaxyId": "<galaxy-host-id>",
    "displayName": "Мой CRM-бот",
    "ip": null,
    "ssh": null,
    "plan": "bc-medium",
    "region": "ru-central1-a",
    "image": "ubuntu-2404-lts",
    "mode": "BLACKHOLE",
    "createdVia": "galaxy",
    "subdomain": "app-7c2b1f08",
    "blackholeStatus": "NONE",
    "accessPolicy": "OWNER_ONLY",
    "sleepAfterMinutes": 60,
    "runtimeId": null,
    "runtimeStatus": null,
    "appUrl": "https://app-7c2b1f08.vibecode.bitrix24.tech",
    "createdAt": "2026-04-22T10:50:11.477Z",
    "next": "deploy",
    "hint": "This is a galaxy app — POST /v1/infra/servers/:id/deploy with source.content now; it will not reach \"running\" on its own."
  }
}

Если сборка galaxy-приложения упала, GET /v1/infra/servers/:id вернёт причину в data.provisionError:

JSON
{
  "success": true,
  "data": {
    "id": "7c2b1f08-3a4d-4e91-9b6c-2f5e8a1d0c33",
    "status": "error",
    "createdVia": "galaxy",
    "provisionError": "Docker build failed: npm ci exited with code 1"
  }
}

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

400 — нарушена валидация (имя начинается с заглавной):

JSON
{
  "success": false,
  "error": {
    "code": "INVALID_REQUEST",
    "message": "name: Name must start with a letter and contain only lowercase letters, digits, and hyphens"
  }
}

Ошибки

HTTP Код Описание
400 INVALID_REQUEST Нарушена валидация полей (неверный формат имени, отсутствует обязательное поле, неверный SSH-ключ и т. д.). Поле message содержит конкретную причину. Если на портале с размещением в галактике не передано ни source, ни пара обязательных полей provider + plan — добавляется объект error.hint (см. ниже)
400 SOURCE_AT_CREATE_GALAXY_ONLY Запрос с source не удалось разместить в галактике. Это происходит при выключенном режиме галактик, вместе с placement: "dedicated" или когда фактическая проверка не нашла пригодный хост. Следуйте error.hint и capabilities.servers.create: без хоста галактики двухшаговый путь доступен только при available: true; при существующем хосте и available: false подсказка запрещает его, потому что при включённом контроле trial-ограничений создание отдельной машины вернёт 402 TRIAL_PORTAL_LIMIT
400 GALAXY_SOURCE_URL_NOT_ALLOWED Ссылка в source.url не прошла проверку до отправки на хост галактики. Причины: адрес ведёт не в хранилище исходников платформы, значение не является абсолютным URL, схема не http и не https, адрес ведёт не в публичную сеть — на локальный, внутренний или служебный узел. Текст ответа называет сработавшее правило, а для стороннего адреса подсказывает замену — сохранить архив версией и выложить её вторым шагом через выкладку кода. Та же проверка стоит и на самой выкладке
400 RUNTIME_PARAM_REMOVED Параметр runtime передан без source. Указывайте рантайм в POST /:id/deploy либо передайте runtime, start и source вместе в этом же запросе. На портале с размещением в галактике добавляется объект error.hint (см. ниже)
400 UNKNOWN_PARAM В теле есть неизвестное поле (например deployMode вместо placement). details.unknownFields перечисляет лишние поля, details.suggestions подсказывает правильное имя, details.validParams — полный список допустимых полей
400 WORK_SCHEDULE_NOT_FOUND В блоке runMode назван идентификатор расписания, которого в вашем аккаунте нет. Машина при этом не создаётся
400 WORK_SCHEDULE_EMPTY У названного расписания нет ни одного окна — на таком сервер не работал бы никогда. Машина не создаётся
400 RUN_MODE_UNAVAILABLE Режимы работы для вашего аккаунта ещё не включены. Машина не создаётся
400 INVALID_PLAN Тариф из поля plan отсутствует в каталоге провайдера. Список — GET /v1/infra/providers/:providerId/plans
400 INVALID_REGION Присланный region отсутствует в каталоге провайдера. Список — GET /v1/infra/providers/:providerId/regions. Второй случай: region не передан, а у провайдера нет ни одного региона — тогда message называет провайдера, и подставлять значение по умолчанию платформе не из чего
401 MISSING_API_KEY Не передан заголовок X-Api-Key
401 INVALID_API_KEY Ключ не опознан: такой строки на платформе нет
401 UNAUTHENTICATED Ключ авторизации (vibe_app_) прислан без заголовка Authorization: Bearer — создание сервера проходит тарифную проверку, которой нужно знать, кто именно создаёт сервер. Поле error.hint называет следующий шаг: пройти OAuth-авторизацию или взять личный API-ключ (vibe_api_), которому сессия не нужна. Порядок — Ключи и авторизация
402 MARKETPLACE_REQUIRED На портале нет активной подписки, а доступ к платформе здесь открывает именно она. Если у российского облачного портала прочитан бесплатный тариф Битрикс24, userMessage и подсказка называют оба условия: платный тариф Битрикс24 и подписку BitrixGPT + Маркетплейс; касса портала соберёт их в одну корзину. Для демо-тарифа и непрочитанного тарифа эта пара не применяется. Пути решения — в error.alternatives, требуемые тарифы и ссылка на оформление — в error.details. Какой путь доступа действует в регионе портала — Тариф и доступ
402 BY_PAID_ONLY Доступ открывает платный или демо-тариф Битрикс24. Открывает его и платная подписка Битрикс24 Маркет Плюс — в Беларуси она продаётся
402 KZ_PAID_ONLY Регион портала открывает доступ по тарифу: платный или демо-тариф Битрикс24, подписка в регионе не продаётся
402 UZ_PAID_ONLY То же для региона UZ: платный или демо-тариф Битрикс24, подписка в регионе не продаётся
402 COMMERCIAL_PLAN_REQUIRED Платформа не нашла запись портала, к которому привязан ключ, поэтому не может проверить доступ
402 TRIAL_PORTAL_LIMIT Превышена квота серверов портала на trial error.retryable: false; не повторяйте создание с другими именами, ключами, провайдерами или планами. Проверьте deployment.standalone.reuseTarget в GET /v1/me, иначе следуйте userMessage и alternatives.
402 PLAN_NOT_ALLOWED_ON_TRIAL Запрошенный тариф недоступен на пробном периоде. Набор разрешённых тарифов читайте из error.details.allowedPlans — он различается, поэтому не зашивайте его в код. Поле error.details.requestedPlan, когда оно есть, повторяет отклонённый тариф
402 GALAXY_NOT_ON_TRIAL Хост Galaxy нельзя создать на пробном доступе. Получите полный доступ по модели региона; для пробного развёртывания используйте отдельный сервер с планом из capabilities.servers.create.limits.allowedPlans ответа GET /v1/me в пределах оставшейся квоты. Контейнер GALAXY_APP на существующем подходящем хосте этим отказом не запрещён
402 ACCOUNT_FROZEN Баланс Вайбкод заморожен, нужно пополнить
403 PORTAL_SUBSCRIPTION_UNREADABLE Состояние подписки аккаунта прочитать не удалось: ключу разработчика не хватает прав на чтение лицензии. Покупка такой отказ не снимает, поэтому поле error.details.requiredTariffs пустое. Переподключите приложение под главным администратором аккаунта, чтобы ключ получил нужные права. Код 402 MARKETPLACE_REQUIRED означает другое: подписка прочитана, и её нет
403 PORTAL_TARIFF_UNREADABLE Тариф аккаунта прочитать не удалось, поэтому какого тарифа не хватает, ответ не называет: поле error.details.requiredTariffs пустое, а кнопка ведёт в поддержку. Покупка тарифа отказ не снимает
403 INFRA_NOT_PERMITTED Инфраструктура отключена на платформе или на портале
403 SERVER_CREATION_DISABLED Создание серверов запрещено политикой портала
403 MAX_SERVERS_REACHED Превышен лимит серверов на API-ключ. Удалите ненужные через DELETE или создавайте новый API-ключ
403 WRITE_BLOCKED_READONLY_KEY У ключа режим «только чтение», а создание сервера — операция записи. Переключите ключ на чтение и запись, порядок — Режим доступа
403 INFRA_SCOPE_REQUIRED У ключа нет скоупа vibe:infra — управление инфраструктурой недоступно. Добавьте скоуп или используйте ключ с правами на инфраструктуру
403 INFRA_FORBIDDEN_FOR_COWORK_KEY Вызов сделан ключом Cowork/Code — такой ключ работает только с данными, изменяющие операции ему закрыты. Что делать — Проектный ключ для деплоя
404 NO_CREDENTIALS Провайдер provider не сконфигурирован на платформе
409 GALAXY_FULL Портал размещает приложения в галактиках, и места под ещё одно приложение нет. Прежде чем отказать, платформа пробует разместить приложение на другой галактике, поэтому этот ответ означает, что места действительно нет. Удалите ненужное galaxy-приложение либо запросите отдельную машину — поле placement со значением dedicated
409 REISSUE_IN_PROGRESS Ключ приложения или его привязка к серверу заняты перевыпуском ключа, доставкой секретов или удалением либо изменились во время запроса. Новая машина не создана; повторите запрос чуть позже
409 APPLICATION_KEY_RECOVERY_REQUIRED Замена API-ключа, которым сделан запрос, не завершена: его перевыпуск закончился ответом 500 или ещё не закончился. Сервер не создан: он оказался бы на ключе с незавершённой заменой. Порядок действий — Менеджмент-ключи, раздел о перевыпуске ключа
409 APPLICATION_REUSE_CONFLICT Пока платформа подбирала существующий сервер для повторного использования, привязку сервера к приложению изменил параллельный запрос. error.retryable: true, повторите запрос
413 INLINE_SOURCE_TOO_LARGE Тело со встроенным source.content больше 96 МБ, то есть около 72 МБ самого архива. Решение принимается по заголовку Content-Length до чтения тела, поэтому отказ детерминированный — то же тело повторной отправкой не пройдёт. Трафик это не экономит: платформа принимает тело целиком, и отказ приходит после того, как загрузка закончилась. В error.hint приходят четыре строки — reason, recovery, recoveryAction и note: рецепт здесь — создать сервер без source, сохранить архив версией на полученном идентификаторе и развернуть её по {"source": {"versionId": "vN"}}, потому что все адреса версионного пути строятся по идентификатору сервера, которого до создания ещё нет
429 RATE_LIMITED Превышен общий лимит запросов платформы
429 DEPLOY_BACKEND_BUSY Запрос нёс архив в source.content, а на бэкенде уже идёт предельное число таких же тяжёлых запросов (общий счётчик с POST /:id/deploy и POST /:id/upload). В ответе заголовок Retry-After: 30 — повторите через полминуты. Чтобы не зависеть от очереди, создайте сервер без source, а код загрузите отдельным запросом со ссылкой {source: {url: ...}} — у этого пути ограничения на одновременность нет
502 PROVIDER_ERROR Облачный провайдер вернул ошибку при создании виртуальной машины. Без заголовка Idempotency-Key запись сервера помечается удалённой, квота не расходуется — можно сразу повторить попытку. Если запрос шёл с этим заголовком, найдите сервер по имени из запроса в списке серверов. Запись со статусом error значит, что облако могло создать машину, хотя ответ потерялся: повтор с тем же Idempotency-Key вернёт эту запись, а не создаст вторую машину — см. Идемпотентность. Записи нет — повторите запрос. Поле message содержит локализованное описание сбоя и код инцидента — сырой ответ провайдера в тело не попадает, он остаётся в логах платформы. Назовите код инцидента поддержке
503 POOL_EXHAUSTED Исход создания неизвестен: ошибка базы могла возникнуть после начала операции. Выдержите Retry-After, проверьте список серверов и повторяйте создание только если убедились, что сервер не появился

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

Подсказка `error.hint`

На портале с размещением в галактике ошибки INVALID_REQUEST и RUNTIME_PARAM_REMOVED дополняются объектом error.hint. Он называет причину отказа и даёт готовое тело запроса. Условие у двух кодов разное. У INVALID_REQUEST подсказка приходит, когда в теле нет ни source, ни обязательной пары provider + plan. Поле region можно опустить, платформа подставит регион провайдера по умолчанию. У RUNTIME_PARAM_REMOVED подсказка приходит, когда передан runtime без source, причём provider и plan при этом могут быть заполнены. На портале с отдельными виртуальными машинами подсказки нет ни в одном из случаев.

На пробном доступе эти ранние подсказки используют ту же предварительную оценку, что и GET /v1/me. Подходящий по сохранённому состоянию хост даёт рекомендацию попробовать одношаговый запрос. При отсутствии хоста двухшаговый путь разрешён, только когда capabilities.servers.create.available равен true. Если существующий хост непригоден, для нового one-shot запроса нужно дождаться восстановления, починить хост либо повысить тариф; после удаления хоста следует заново прочитать GET /v1/me и перейти на объявленный там двухшаговый путь. Подсказка носит рекомендательный характер: окончательное решение принимает POST.

Если запрос с source уже дошёл до фактической проверки и вернул SOURCE_AT_CREATE_GALAXY_ONLY, его error.hint учитывает результат этой проверки. При существующем хосте на пробном доступе подсказка запрещает двухшаговый путь, когда capabilities.servers.create.available равен false: при включённом контроле trial-ограничений он вернёт 402 TRIAL_PORTAL_LIMIT. При отсутствии хоста она разрешает создать отдельную машину без source, а затем выполнить деплой только после положительной проверки этого слота.

Не путайте с data.hint из успешного ответа: там строка про следующий шаг после создания приложения по сценарию 2, здесь — объект внутри error.

Поле Тип Описание
error.hint.reason string Почему запрос отклонён
error.hint.recovery string Что изменить в запросе, чтобы он прошёл
error.hint.example object Готовое тело запроса, которое можно взять за основу
JSON
{
  "success": false,
  "error": {
    "code": "INVALID_REQUEST",
    "message": "provider: Required; plan: Required",
    "hint": {
      "reason": "This portal places new apps on shared galaxy hosts, and the request lacked `source` and the required provider/plan pair. `region` is optional and defaults to the provider's region.",
      "recovery": "RECOMMENDED: create-and-deploy in ONE call — POST /v1/infra/servers { name, source: { content }, runtime, start }; OMIT provider/plan/region. Two-step also works: pass provider and plan (region is optional and defaults to the provider's region) to create an empty slot, then POST /v1/infra/servers/:id/deploy with the source. See GET /v1/me -> deployment.galaxyApp.checklist. For a deliberate dedicated standalone VM pass placement: \"dedicated\" with provider and plan; region is optional.",
      "example": {
        "name": "<slug>",
        "source": { "content": "<base64 gzip-tar of the app>" },
        "runtime": "node20",
        "start": "node server.js",
        "port": 3000
      }
    }
  }
}

Если в теле передан placement: "dedicated", подсказка другая: она предлагает добавить обязательные provider и plan, сохранив выделенный сервер, а region оставить пустым для выбора региона по умолчанию, а не переводить приложение в контейнер галактики.

Переиспользование сервера

POST /v1/infra/servers не создаёт второй сервер и возвращает существующий в двух случаях. Первый — ключ вызова принадлежит карточке из раздела «Приложения», к которой уже привязан живой сервер. Второй — тот же API-ключ уже создаёт GALAXY_APP в статусе provisioning, у сервера есть живая keyless-карточка, раздел «Приложения» виден порталу, а родительский Galaxy-host по-прежнему жив: не удалён, имеет тип GALAXY и не находится в error/deleted. Второй случай действует при любом размещении, кроме placement: "dedicated", даже если после первого запроса настройки размещения переключились на отдельные машины, и проверяется до fresh-only отказа для тела с source. После выхода такого приложения из provisioning следующий create снова может создать новый сервер.

Имя, которое вы передали в name, в этом решении не участвует — повтор платформа определяет по вызывающему ключу и состоянию сервера, а не по имени.

В reuse-ответе (reused: true) все поля data описывают существующий сервер, а не ваш запрос — status, provider, plan, region, image, createdVia, createdAt относятся к нему. Статус может быть любым, поэтому «дождаться running» не является проверкой того, что сервер ваш. Проверка — это reused и пара name ⊕ requestedName.

Ответ на такой запрос всегда несёт data.reused: true и рядом с data — массив warnings минимум с одной записью. Сравните data.name с data.requestedName: они различаются, если сервер приложения был создан раньше и под другим именем.

Поле Тип Когда
data.reused boolean Всегда на таком ответе. Новый сервер не создан
data.reusedReason string APPLICATION_ALREADY_HAS_SERVER
data.requestedName string Эхо вашего name — всегда, даже если совпадает с именем существующего сервера
data.sourceIgnored boolean Переданный source не развёрнут этим запросом
data.deploying boolean Переданный source собирается на контейнер приложения прямо сейчас
data.metaIgnored boolean Переданные displayName/description не применены
warnings array Рядом с data, не внутри. Минимум одна запись

Что делать перед деплоем. Запросите GET /v1/infra/servers/:id и посмотрите, что на сервере уже развёрнуто. Деплой заменяет работающий код, он не добавляет к нему. Если это не тот сервер, который вы имели в виду, остановитесь и спросите пользователя, с каким приложением должен работать этот ключ.

Про переданный source. Обычное переиспользование разворачивает исходники в galaxy-приложение только тогда, когда контейнера ещё нет или прошлая сборка упала — в ответе будет deploying: true, опрашивайте GET /v1/infra/servers/:id до running. При схождении на keyless-приложении в provisioning этот запрос никогда не запускает вторую сборку и отвечает sourceIgnored: true. Если ранняя сборка уже идёт, data.next отсутствует: не вызывайте deploy параллельно, дождитесь выхода сервера из provisioning и только потом разворачивайте проигнорированный source через POST /v1/infra/servers/:id/deploy, если замена всё ещё нужна. Для припаркованного приложения без активной сборки ответ сохраняет next: "deploy".

Про переданные displayName и description. Переиспользование никогда не переименовывает сервер, который отдаёт: у него остаются собственные имя и описание, а переданные вами значения отбрасываются — в ответе это видно по data.metaIgnored: true и отдельному предупреждению. Переименуйте осознанно через PATCH /v1/infra/servers/:id, убедившись, что сервер тот.

Про data.next. В reuse-ответе поле приходит только для припаркованного galaxy-приложения без контейнера и без активной сборки, которое прикреплено к galaxy-хосту. Во время уже идущей сборки next намеренно отсутствует: опрашивайте сервер, не запускайте конкурирующий deploy. Если приложение откреплено от хоста или сервер уже может выполнять код, next тоже не приходит. Не трактуйте отсутствие next как ошибку или разрешение перезаписать код.

Как получить для приложения другой сервер. Отдельного вызова, меняющего привязку, нет. Если нужна отдельная виртуальная машина и привязку трогать не надо — создайте её с placement: "dedicated": переиспользование не сработает, но и к приложению новый сервер привязан не будет. Если нужно именно сменить привязанный сервер — удалите текущий через DELETE /v1/infra/servers/:id, и следующий POST /v1/infra/servers тем же ключом снимет устаревшую привязку и привяжет вновь созданный сервер. Удаление необратимо и уничтожает всё, что развёрнуто на сервере, — сначала убедитесь по GET /v1/infra/servers/:id, что это не чужая работа.

Создание с placement: "dedicated" переиспользование не затрагивает.

Идемпотентность

Передайте необязательный заголовок Idempotency-Key, чтобы безопасно повторять зарегистрированное создание standalone-сервера или Galaxy-приложения. Если ответ на первый запрос потерялся (обрыв сети, таймаут балансировщика), повтор с тем же ключом не создаст второй ресурс — вернётся тот же сервер: HTTP-код 201 и заголовок ответа Idempotent-Replayed: true, а поля описывают его состояние на момент повтора.

Повтор возможен в течение 15 минут с момента резервирования ключа (для прежних standalone-записей — создания сервера). После этого окна тот же ключ сервер уже не вернёт: запрос пройдёт как новое создание со всеми проверками прав — и либо получит обычный отказ по правам (402 / 403), либо 409 IDEMPOTENCY_KEY_ALREADY_USED. Если сервер не удаляли, он никуда не делся — текст ответа это скажет.

Важно: повторяйте ТЕМ ЖЕ ключом, а не новым. Для standalone-создания тот же Idempotency-Key вторую машину не создаст: он вернёт либо сам сервер, либо 409 с ответом о его судьбе. Новый Idempotency-Key сам по себе не является повтором прежнего запроса, но обычные правила переиспользования всё равно действуют. В частности, запрос тем же API-ключом при живом keyless GALAXY_APP в provisioning вернёт его с reused: true при любом недедицированном размещении. Поэтому новый ключ не означает, что обязательно будет создан новый сервер: проверяйте data.id, data.reused и GET /v1/infra/servers.

  • Ключ — строка 1–255 символов из набора [A-Za-z0-9_.:-]. Область действия — ваш API-ключ.
  • При повторе standalone одноразовые SSH-данные не выдаются повторно. В теле ответа ssh.privateKey и ssh.password будут null, а поле note пояснит это. Сохраняйте данные из ответа первого создания. У GALAXY_APP своих SSH-данных нет: ssh равен null, поле note не требуется.
  • Galaxy-создание и переиспользование защищены после включения новой защиты. Ключ резервируется независимо от строки ресурса: несколько разных ключей могут вернуть один переиспользованный слот. Новые fresh, revived и reused результаты запоминают точный applicationId; если фоновая привязка fresh/revived-сервера находит уже созданную для этого ключа карточку, запись атомарно переключается с предварительно зарезервированного id на id именно этой карточки, после чего он фиксирован. Повтор того же ключа в течение 15 минут принимает только эту точную карточку, а не любую более позднюю карточку того же владельца на том же сервере. Платформа также заново проверяет владельца и портал обеих строк и живой Galaxy-host. Если записанная карточка была удалена, отвязана или заменена, владение изменилось либо host удалён/перешёл в error/deleted, ключ остаётся израсходованным, но ответ — 409 IDEMPOTENCY_KEY_ALREADY_USED без data и прежнего id; в новое создание запрос не проваливается. UUID-only записи до включения защиты остаются legacy. После окна действуют обычные проверки и отказ занятого ключа. До активации первое galaxy-создание по-прежнему не резервирует ключ; уже записанные ключи читаются и после выключения защиты. Старые galaxy-создания без записи ключа восстановить нельзя.
  • Заголовок несовместим с graduateFrom для выделенного сервера — вернётся 400 IDEMPOTENCY_UNSUPPORTED_WITH_GRADUATION.
  • Повтор записанного ключа не запускает сборку повторно. После ошибки сборки используйте явный deploy. Fresh/revived Galaxy-результат повторяется обычным create-ответом; semantic reuse снова содержит reused, reusedReason, requestedName, sourceIgnored/metaIgnored, warnings, hint и применимый next. Эти поля учитывают текущее валидированное тело повтора, но новая запись reuse отдельно помнит, принял ли исходный запрос свой source: пока начатая им сборка активна, повтор отвечает deploying: true без sourceIgnored и без next; после её завершения source также не объявляется проигнорированным и автоматически повторно не разворачивается. У прежней записи формата v1 этого признака нет, поэтому повтор не выдумывает исход: не отдаёт sourceIgnored или next, а просит сначала проверить сервер и логи и не запускать deploy автоматически. Запрос с новым ключом проходит обычные правила reuse: пустой или ошибочный слот может начать сборку, а схождение на keyless-приложении с уже активной сборкой не запускает вторую и может вернуть sourceIgnored: true.
Код code Когда
400 INVALID_IDEMPOTENCY_KEY Ключ не проходит валидацию (длина или недопустимые символы)
400 IDEMPOTENCY_UNSUPPORTED_WITH_GRADUATION Ключ вместе с graduateFrom для выделенного сервера
409 IDEMPOTENCY_KEY_ALREADY_USED Ключ израсходован. Текст ответа различает удалённый сервер, повтор позже 15-минутного окна и недоступный прежний результат — в том числе удаление, отвязку или замену точной записанной Galaxy-карточки. В последнем случае ответ не содержит data и прежнего идентификатора и не начинает новое создание. Тот же код приходит и на galaxy-пути, если ключ уже израсходован
409 IDEMPOTENCY_CONCURRENT_RETRY Параллельный запрос с тем же ключом ещё выполняется — повторите чуть позже

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

  • Примеры корректных и некорректных имён по паттерну ^[a-z][a-z0-9-]*$:
    • Правильно: my-app, bot-1, crm-dashboard.
    • Неправильно: My-App (заглавная), bot_1 (подчёркивание), my.app (точка), кириллица.
  • Свой sshPublicKey на заранее подготовленной машине. Если первый ответ создания пришёл со статусом running и без reused: true, платформа выдала заранее подготовленную машину. Если вы передали sshPublicKey, платформа установила его до ответа: для входа по SSH используйте свой ключ или ключ из ssh.privateKey. Смотрите именно первый ответ: повтор с тем же Idempotency-Key показывает статус сервера на момент повтора.
  • Когда region в ответе отличается от запрошенного. В запрошенной зоне могли кончиться IP-адреса (Address space exhausted) — тогда платформа автоматически пробует следующие зоны в порядке из GET /v1/infra/providers/:providerId/regions, и фиксирует это в аудит-логе событием SERVER_ZONE_FALLBACK.
  • Таймаут провижининга — 15 минут. Если status держится в provisioning дольше, платформа переводит сервер в error и заполняет provisionError и provisionErrorCode. Дальше остаётся вызвать DELETE и создать новый.
  • Новая обычная машина получает таймаут авто-сна 60 минут. Фактическое сохранённое значение приходит уже в data.sleepAfterMinutes ответа создания и затем в GET /v1/infra/servers/:id. При reuse и idempotency replay это значение существующей записи, поэтому оно может быть null или отличаться от 60. Сервер, родившийся на расписании, отмеченном для новых машин, это значение хранит, но оно не действует, пока расписание назначено, — режим виден в полях runMode и workSchedule того же GET. Входящие HTTP-запросы и активность по SSH сбрасывают таймер, а cron, фоновые процессы и собственные исходящие запросы приложения — нет. Допустимые значения и осознанное отключение авто-сна через PATCH с null — Настроить авто-сон.
  • Рантайм устанавливается на этапе деплоя. Параметр runtime без source в POST /v1/infra/servers не принимается (вернёт 400 RUNTIME_PARAM_REMOVED). Указывайте runtime в теле POST /:id/deploy — для отдельной виртуальной машины начало конвейера идёт в порядке runtime → stop_existing → clean → download → install. Вместе с source рантайм принимается и обязателен: это одношаговое создание galaxy-приложения, где runtime и start идут в том же запросе.
  • Кириллица в displayName и description из Windows PowerShell. Отправленная без явной сериализации в UTF-8, она сохраняется знаками вопроса (?): байты теряются на стороне клиента, до отправки запроса. Готовый вызов с UTF8.GetBytes — Windows / PowerShell и UTF-8.

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