#Инфраструктура

Создание и управление виртуальными серверами для деплоя приложений Битрикс24. Каждый сервер невидим из интернета по умолчанию (режим Black Hole) — доступ к приложению только через HTTPS-субдомен app-{id}.vibecode.bitrix24.tech. Управление сервером и деплой — через REST API без SSH.

Скоуп: vibe:infra (добавляется автоматически в каждый API-ключ) · Базовый URL: https://vibecode.bitrix24.tech/v1 · Авторизация: заголовок X-Api-Key

#Разделы документации

  • Провайдеры и каталоги — список провайдеров, тарифов, регионов и образов ОС (4 эндпоинта).
  • Серверы — создание, список, детали, удаление (4 эндпоинта).
  • Жизненный цикл — старт, стоп, сон, пробуждение, ремонт туннеля, статус провижининга (9 эндпоинтов).
  • Доступ и режимы — политика доступа, список пользователей/отделов, SSH-данные, режим BLACKHOLE↔OPEN (7 эндпоинтов).
  • Deploy API — выполнение команд, загрузка файлов, деплой приложения, логи, порт, метрики, лок, рантаймы (8 эндпоинтов).
  • Токены доступа — краткосрочные токены для e2e-проверки и распространяемых ссылок (3 эндпоинта).
  • Что приходит в приложение — Gateway-инжекция X-Vibe-Authorization: Bearer, чтение identity через /v1/me, скелеты обработчика на Node/Python/Go.

#Что важно знать сразу

  1. Порт приложения — всегда 3000. Black Hole туннель проксирует ровно этот порт; менять его не нужно. Сервер — изолированное окружение: :3000 внутри виртуальной машины никак не связан с портами вашей локальной машины.
  2. Deploy API — только для BLACKHOLE. Все /deploy, /exec, /upload, /logs требуют серверов в режиме BLACKHOLE со статусом CONNECTED для агента туннеля. Для OPEN-серверов они вернут ошибку.
  3. /deploy и /exec отдают JSON по умолчанию. Это безопасно для AI-агентов и MCP-клиентов — никаких дополнительных query-параметров не нужно. Если вам действительно нужен потоковый ответ (live-вывод шагов деплоя в UI), передайте ?stream=true — тогда вернётся SSE (Server-Sent Events). Раньше документация утверждала обратное (default SSE, ?stream=false для JSON) — это устарело и больше не соответствует поведению API.
  4. accessPolicy — это безопасность. Смена политики с OWNER_ONLY на PORTAL/AUTHENTICATED/PUBLIC открывает приложение другим пользователям. Никогда не меняйте accessPolicy без явного подтверждения пользователя.
  5. Сервер — это чистая Ubuntu 24.04, рут-доступ включён. Виртуальная машина создаётся из стокового образа Ubuntu без предустановленного ПО (кроме агента туннеля). Агент работает от имени пользователя root — в preStart, install и командах /exec sudo не нужен. Исходящий интернет доступен без ограничений: apt-get, curl, wget, pip работают напрямую. Входящий трафик заблокирован кроме туннельного соединения.
  6. Тариф Битрикс24 играет двойную роль. Во-первых, REST API самого Битрикс24 доступен только на коммерческих тарифах портала — без этого не работают ни приложения, ни прокси /v1/deals, ни боты, ни любой другой вызов, который проксируется в Битрикс24. Во-вторых, поверх этого — создание серверов, деплой и пробуждение требуют коммерческого тарифа Битрикс24 или активного 14-дневного trial Вайбкод. AI Router работает независимо от тарифа Битрикс24 — он не проксирует в REST и доступен даже на бесплатных тарифах (BYOK бесплатно; платформенные модели тарифицируются с баланса Вайбкод). Подробности — в разделе «Тариф и trial» ниже.
  7. Авторизация пользователя в приложении. На каждом запросе Gateway инжектирует шесть заголовков с префиксом X-Vibe-: Request-Id всегда плюс User-Id, User-Name, User-Role, Portal-Id, Authorization (Bearer vibe_session_<…>) для аутентифицированного запроса. Браузер Authorization-токен не видит и не хранит — он живёт только между Gateway и app-сервером. Для быстрого идентификатора пользователя достаточно заголовка X-Vibe-User-Id; полный контекст (скоупы, capabilities, тариф, информация о приложении) — одним вызовом GET /v1/me со server-side кэшированием. ID пользователя в ответе /v1/medata.currentUser.bitrixUserId, домен портала — data.portal. Полная таблица заголовков, BFF-паттерн и скелеты обработчика на Node/Python/Go — Что приходит в приложение.
  8. Создание серверов требует пользовательской сессии для ключей vibe_app_. POST /v1/infra/servers гейтится тарифной проверкой, которой нужно знать, кто именно создаёт сервер. Для vibe_api_ пользовательский контекст уже есть в самом ключе; для vibe_app_ обязателен Authorization: Bearer <session> — без него ответ 401 UNAUTHENTICATED с error.hint, указывающим на OAuth-флоу. Чтение и Deploy API на уже существующих серверах сессии не требуют — таблица «Авторизация эндпоинтов» ниже сводит все правила в одном месте.

#Быстрый старт

Три вызова — создание сервера и запуск приложения.

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

Terminal
export VIBE_KEY="YOUR_API_KEY"

# 1. Создать сервер (автоматически в режиме Black Hole)
curl -X POST https://vibecode.bitrix24.tech/v1/infra/servers \
  -H "X-Api-Key: $VIBE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "bitrix-cloud",
    "name": "my-app",
    "plan": "bc-small",
    "region": "ru-central1-b",
    "image": "fd83esfomhq25p2ono90"
  }'

# 2. Дождаться готовности: status=running И blackholeStatus=CONNECTED
curl -H "X-Api-Key: $VIBE_KEY" \
  https://vibecode.bitrix24.tech/v1/infra/servers/SERVER_ID

# 3. Задеплоить приложение (?stream=false — JSON вместо SSE)
curl -X POST "https://vibecode.bitrix24.tech/v1/infra/servers/SERVER_ID/deploy?stream=false" \
  -H "X-Api-Key: $VIBE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "source": { "url": "https://github.com/user/app/archive/main.tar.gz" },
    "runtime": "node20",
    "install": "cd /opt/app && npm install --production",
    "start": "cd /opt/app && node server.js",
    "port": 3000
  }'

Приложение доступно по адресу https://app-{id}.vibecode.bitrix24.tech — поле appUrl в ответе /deploy.

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

Terminal
# То же самое, только добавляется заголовок Authorization: Bearer с токеном сессии
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-app", "plan": "bc-small", "region": "ru-central1-b", "image": "fd83esfomhq25p2ono90" }'

#Полный пример

Реалистичный сценарий на JavaScript — создание сервера, ожидание готовности, деплой, получение URL приложения.

javascript
const VIBE_KEY = process.env.VIBE_KEY
const BASE = 'https://vibecode.bitrix24.tech/v1'

async function api(method, path, body = null) {
  const opts = { method, headers: { 'X-Api-Key': VIBE_KEY } }
  if (body) {
    opts.headers['Content-Type'] = 'application/json'
    opts.body = JSON.stringify(body)
  }
  const res = await fetch(`${BASE}${path}`, opts)
  if (!res.ok) throw new Error(`${method} ${path} → ${res.status}`)
  return res.json()
}

// 1. Выбрать провайдера, тариф, регион, образ
const { data: plans } = await api('GET', '/infra/providers/bitrix-cloud/plans')
const { data: regions } = await api('GET', '/infra/providers/bitrix-cloud/regions')
const { data: images } = await api('GET', '/infra/providers/bitrix-cloud/images')

const plan = plans.find(p => p.id === 'bc-small')
const region = regions.find(r => r.id === 'ru-central1-b')
const image = images[0]

// 2. Создать сервер (всегда в Black Hole)
const { data: server } = await api('POST', '/infra/servers', {
  provider: 'bitrix-cloud',
  name: 'my-crm-bot',
  plan: plan.id,
  region: region.id,
  image: image.id,
})
console.log(`Сервер создан: ${server.id}, субдомен: ${server.subdomain}`)

// 3. Ждать пока статус не станет running И blackholeStatus не станет CONNECTED
let info = server
while (info.status !== 'running' || info.blackholeStatus !== 'CONNECTED') {
  await new Promise(r => setTimeout(r, 10000)) // 10 секунд между опросами
  const res = await api('GET', `/infra/servers/${server.id}`)
  info = res.data
  console.log(`status=${info.status}, blackhole=${info.blackholeStatus}`)
}

// 4. Задеплоить приложение (обязательно ?stream=false для JSON-ответа)
const deploy = await api('POST', `/infra/servers/${server.id}/deploy?stream=false`, {
  source: { url: 'https://github.com/user/app/archive/main.tar.gz' },
  runtime: 'node20',
  install: 'cd /opt/app && npm install --production',
  preStart: 'cd /opt/app && npx prisma migrate deploy',
  start: 'cd /opt/app && node server.js',
  port: 3000,
  env: { NODE_ENV: 'production' },
})

console.log(`Приложение живёт: ${deploy.data.appUrl}`)

// 5. (Опционально) Настроить авто-сон через 60 минут простоя
await api('PATCH', `/infra/servers/${server.id}/sleep`, { sleepAfterMinutes: 60 })

#Справочник эндпоинтов

Все 35 эндпоинтов. Ссылки ведут на страницы с параметрами, примерами и кодами ошибок.

Провайдеры и каталоги:

Метод Путь Описание
GET `/v1/infra/providers` Список облачных провайдеров
GET `/v1/infra/providers/:providerId/plans` Тарифы провайдера
GET `/v1/infra/providers/:providerId/regions` Регионы провайдера
GET `/v1/infra/providers/:providerId/images` Образы ОС

Серверы:

Метод Путь Описание
POST `/v1/infra/servers` Создать сервер (всегда Black Hole)
GET `/v1/infra/servers` Список ваших серверов
GET `/v1/infra/servers/:id` Детали сервера
DELETE `/v1/infra/servers/:id` Удалить сервер

Жизненный цикл:

Метод Путь Описание
POST `/v1/infra/servers/:id/start` Запустить остановленный/спящий сервер
POST `/v1/infra/servers/:id/stop` Остановить работающий сервер
POST `/v1/infra/servers/:id/reboot` Перезагрузить сервер
POST `/v1/infra/servers/:id/wake` Разбудить спящий сервер (асинхронно или блокирующе)
POST `/v1/infra/servers/:id/sleep-now` Немедленно усыпить BLACKHOLE-сервер
PATCH `/v1/infra/servers/:id/sleep` Настроить авто-засыпание
POST `/v1/infra/servers/:id/refresh` Запросить статус и IP у провайдера
POST `/v1/infra/servers/:id/repair` Восстановить туннель через serial console
GET `/v1/infra/servers/:id/repair-status` Прогресс восстановления туннеля

Доступ и режимы:

Метод Путь Описание
GET `/v1/infra/servers/:id/ssh` SSH-данные (только для OPEN)
PATCH `/v1/infra/servers/:id/mode` Переключить BLACKHOLE↔OPEN
PATCH `/v1/infra/servers/:id/access-policy` Политика доступа к приложению
GET `/v1/infra/servers/:id/access` Список пользователей и отделов доступа
POST `/v1/infra/servers/:id/access` Добавить пользователя или отдел
DELETE `/v1/infra/servers/:id/access/:accessId` Удалить запись доступа
GET `/v1/infra/servers/:id/b24-users` Поиск пользователей портала Битрикс24

Deploy API:

Метод Путь Описание
POST `/v1/infra/servers/:id/exec` Выполнить команду (SSE или JSON)
POST `/v1/infra/servers/:id/upload` Загрузить файл (base64 или по URL)
GET `/v1/infra/servers/:id/logs` Логи сервиса (утилита journalctl)
POST `/v1/infra/servers/:id/deploy` Полный деплой приложения
PATCH `/v1/infra/servers/:id/port` Задать порт приложения
GET `/v1/infra/servers/:id/metrics` Метрики активности туннеля
DELETE `/v1/infra/servers/:id/lock` Снять зависший лок операции
GET `/v1/infra/runtimes` Список доступных рантаймов

Токены доступа:

Метод Путь Описание
POST `/v1/infra/servers/:id/access-tokens` Выпустить токен доступа (api-bearer или share-url)
GET `/v1/infra/servers/:id/access-tokens` Список токенов сервера
DELETE `/v1/infra/servers/:id/access-tokens/:tokenId` Отозвать токен

#Авторизация эндпоинтов

Все инфра-эндпоинты требуют заголовок X-Api-Key. Для ключей vibe_app_ (привязка к OAuth-приложению) часть POST-операций дополнительно требует Authorization: Bearer <session> — без него ответ 401 UNAUTHENTICATED с error.hint. Для ключей vibe_api_ пользовательский контекст уже есть в самом ключе, отдельная сессия не нужна.

Эндпоинт X-Api-Key Authorization: Bearer для vibe_app_ Когда требует Bearer
GET /v1/infra/providers/* да нет
GET /v1/infra/servers, GET /v1/infra/servers/:id да нет
GET /v1/infra/servers/:id/logs, /metrics, /access, /access-tokens, /b24-users, /ssh да нет
GET /v1/infra/runtimes да нет
POST /v1/infra/servers (создать сервер) да да Тарифный гейт: платформе нужно знать, кто именно создаёт сервер.
POST /v1/infra/servers/:id/deploy, /exec, /upload да нет Достаточно скоупа vibe:infra на ключе.
POST /v1/infra/servers/:id/start, /stop, /reboot, /wake, /sleep-now, /refresh, /repair, PATCH /sleep да нет
PATCH /v1/infra/servers/:id/mode, /access-policy, /port да нет
POST /v1/infra/servers/:id/access, DELETE /v1/infra/servers/:id/access/:accessId да нет
POST /v1/infra/servers/:id/access-tokens, DELETE .../:tokenId да нет Платформенный флаг accessTokensEnabled должен быть включён; иначе 503 FEATURE_DISABLED.
DELETE /v1/infra/servers/:id да нет
DELETE /v1/infra/servers/:id/lock да нет

Быстрая проверка до вызова: GET /v1/medata.capabilities.servers.create.available. Для vibe_app_ без сессии возвращается false с reason: "SESSION_REQUIRED" и подсказкой в userMessage — модель сразу видит, что нужно пройти OAuth-флоу, а не ловить 401 на самом POST /v1/infra/servers.

#Лимиты

Лимит Значение
Серверов на API-ключ 3
Операций Deploy API в минуту на сервер 10
Одновременных exec/deploy на сервер 1
Таймаут exec 1–600 секунд (по умолчанию 300)
Размер base64-тела (upload inline, source.content) 500 МБ
Размер файла через source.url / upload url 500 МБ
Размер multipart-архива в deploy 500 МБ
Частота запросов /ssh до 10 в минуту

Rate-limit платформы — общий для всех V1-эндпоинтов, см. раздел «Лимиты и оптимизация».

#Статусы сервера

Статус Описание
provisioning Виртуальная машина создаётся у провайдера (1–3 минуты)
running Виртуальная машина запущена, IP назначен. Для туннеля нужен ещё blackholeStatus: CONNECTED
sleeping Остановлен по таймеру сна или вручную. Автоматически просыпается при обращении к HTTPS-субдомену или вызове /deploy//start//wake
error Сервер не в рабочем состоянии: виртуальная машина удалена у провайдера, агент долго не подключается, внешний externalId отсутствует
deleted Сервер удалён (soft-delete). Нельзя восстановить

Поле blackholeStatus описывает состояние туннеля агента независимо от status:

Значение Описание
NONE Сразу после создания сервера, до первой попытки подключения агента
WAITING Агент готовится к подключению
CONNECTED Туннель активен, Deploy API доступен
DISCONNECTED Агент был подключён, сейчас нет связи — попробуйте `/repair`

Поле runtimeStatus — устаревшее, оставлено для совместимости. Для серверов, созданных после 2026-04-25 (когда параметр runtime был убран из `POST /v1/infra/servers`), всегда возвращается null. Рантайм теперь ставится на этапе `POST /:id/deploy`, а сигналом готовности служит сам успех шага runtime в ответе деплоя.

#Тариф и trial

У инфраструктуры Вайбкод два уровня условий по тарифу Битрикс24.

Уровень 1 — REST API Битрикс24. Сам Битрикс24 открывает REST API только на коммерческих тарифах портала. Это не про Вайбкод: на бесплатных тарифах Битрикс24 попросту не отдаёт REST-ответы. Значит, без коммерческого тарифа Битрикс24 не работают:

  • Создание и публикация приложений (POST /api/apps) — регистрируется на портале через REST.
  • REST-прокси: /v1/deals, /v1/contacts, /v1/batch, /v1/bots, /v1/tasks и все остальные сущности.
  • Боты, чаты, задачи — всё, что проксирует в Битрикс24.

Уровень 2 — Вайбкод-инфраструктура. Сверх первого условия, создание серверов, деплой и пробуждение требуют либо коммерческого тарифа Битрикс24, либо активного 14-дневного trial Вайбкод:

  • POST /v1/infra/servers — создание сервера.
  • POST /v1/infra/servers/:id/deploy — деплой приложения.
  • POST /v1/infra/servers/:id/wake и автоматическое пробуждение при preventWake=true.
  • Создание агентов и managed-ботов (они провижинят серверы под капотом).

Что работает на любом тарифе Битрикс24, включая бесплатный:

  • AI Router — POST /v1/chat/completions, POST /v1/audio/transcriptions, GET /v1/models. Не проксирует в Битрикс24, напрямую ходит к провайдерам LLM. С BYOK-ключами — бесплатно; с платформенными моделями — тарифицируется с баланса Вайбкод.
  • Базовые эндпоинты платформы: GET /v1/me, GET /v1/feedback, GET /v1/guide — для самоориентации AI-агента.

Проверка до вызова: GET /v1/me → поле capabilities.servers.create.available. Если false — поле capabilities.servers.create.userMessage содержит переведённое объяснение для пользователя.

Принудительное обновление после апгрейда: GET /v1/me?refresh=tariff — пропускает кэш (по умолчанию 1 час) и делает свежий запрос к app.info.

Trial-информация: GET /v1/me → блок trial:

  • trial.active — булевый флаг активного trial.
  • trial.daysRemaining — сколько дней осталось.
  • trial.warning"expires_in_7d" | "expires_in_3d" | "expires_in_1d" | null.
  • trial.justStartedtrue при первом вызове сразу после старта trial. После приветствия подтвердите вызовом POST /api/portals/:id/trial/acknowledge (session-API), чтобы флаг сбросился.

Заголовки ответа инфра-эндпоинтов:

Заголовок Значение
X-Tariff-Checked-At ISO-timestamp последней сверки через app.info (максимум 1 час кэша)
X-Tariff-Is-Commercial "true" или "false"
X-Trial-Days-Remaining Целое число (отсутствует, если trial неактивен)
X-Trial-Expiring-In "1d" / "3d" / "7d" (только когда близко к концу)

Коды ошибок тарифного гейта перечислены в разделе «Коды ошибок» ниже.

#Коды ошибок

#Ошибки инфраструктуры

Код HTTP Описание
NOT_FOUND 404 Сервер не найден или принадлежит другому API-ключу
INVALID_REQUEST 400 Ошибка валидации (неверное имя, тариф, регион, образ)
INFRA_NOT_PERMITTED 403 Инфраструктура отключена на платформе или на портале
SERVER_CREATION_DISABLED 403 Создание серверов запрещено политикой портала
MAX_SERVERS_REACHED 403 Превышен лимит 3 серверов на API-ключ
NO_CREDENTIALS 404 Провайдер не сконфигурирован на платформе
SERVER_NOT_READY 409 Сервер ещё создаётся, операция пока недоступна
CONFLICT 409 Сервер в статусе, из которого нельзя выполнить действие (например start работающего)
PROVIDER_ERROR 502 Облачный провайдер вернул ошибку
VM_MISSING 422 У записи нет externalId — виртуальная машина не создана у провайдера или удалена извне. Удалите сервер через DELETE и создайте новый
PORT_RESTRICTED 400 Порт 1–1023 (системные порты запрещены). Допустимы 0 (автоопределение) и 1024–65535
BLACKHOLE_ONLY 400 Эндпоинт работает только для BLACKHOLE-серверов (актуально для /sleep-now, /sleep, /metrics)
OPEN_MODE_NOT_ALLOWED 403 Переключение в OPEN запрещено политикой портала allowOpenMode
SAME_MODE 400 Сервер уже в запрошенном режиме
NOT_IMPLEMENTED 501 Действие не поддерживается провайдером (например /reboot на некоторых плагинах)
REPAIR_BLOCKED 409 Репэр заблокирован (preventWake=true или сервер удалён)

#Ошибки Deploy API

Код HTTP Описание
AGENT_NOT_CONNECTED 409 Агент туннеля не в статусе CONNECTED
EXEC_BUSY 409 На сервере уже выполняется другая операция. Используйте `/lock` для снятия зависшего лока
EXEC_TIMEOUT 504 Превышен таймаут выполнения
EXEC_FAILED 500 Ошибка выполнения команды на агенте
UPLOAD_PATH_DENIED 403 Запрещённый путь для загрузки
DEPLOY_FAILED 500 Ошибка в процессе деплоя (см. поле step в ответе)
VALIDATION_ERROR 400 Некорректное тело запроса Deploy API

#Ошибки тарифного гейта и биллинга

Код HTTP Описание
COMMERCIAL_PLAN_REQUIRED 402 Бесплатный тариф и trial недоступен (уже использован)
TRIAL_EXPIRED 402 Trial использован и завершился
TRIAL_PORTAL_LIMIT 402 Превышена квота серверов портала на trial
TRIAL_USER_LIMIT 402 Превышена квота серверов на пользователя на trial
PLAN_NOT_ALLOWED_ON_TRIAL 402 Запрошенный тариф не в белом списке для trial (разрешён только bc-micro)
ACCOUNT_FROZEN 402 Баланс Вайбкод заморожен. Нужно пополнить
BILLING_EXHAUSTED 402 Баланс Вайбкод исчерпан. Пробуждение и деплой заблокированы
SERVER_WAKE_BLOCKED 403 Пробуждение заблокировано (не из-за биллинга: завершённый trial, административный блок, безопасность)

#Системные ошибки

Код HTTP Описание
MISSING_API_KEY 401 Не передан заголовок X-Api-Key
INVALID_API_KEY 401 Неверный или просроченный API-ключ
SCOPE_DENIED 403 У ключа нет скоупа vibe:infra
RATE_LIMIT_EXCEEDED 429 Превышен rate-limit
INTERNAL_ERROR 500 Внутренняя ошибка сервера

Полный справочник общих ошибок — Ошибки.

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