For AI agents: markdown of this page — /docs-content-en/infra.md documentation index — /llms.txt
Infrastructure
Create and manage virtual servers for deploying Bitrix24 applications. Each server is invisible from the internet by default (Black Hole mode) — the application is reachable only through the HTTPS subdomain app-{id}.vibecode.bitrix24.com. Server management and deployment go through the REST API without SSH.
Scope: vibe:infra (added automatically to every API key) · Base URL: https://vibecode.bitrix24.com/v1 · Authorization: X-Api-Key header
Documentation sections
- Providers and catalogs — list of providers, plans, regions, and OS images (4 endpoints).
- Servers — create, list, details, update name and description, delete (5 endpoints).
- Lifecycle — start, stop, sleep, wake, tunnel repair, provisioning status (9 endpoints).
- Scheduled wake — recurring wake windows for a sleeping server on a cron schedule (4 endpoints).
- Access and modes — access policy, user/department list, SSH credentials, BLACKHOLE↔OPEN mode (7 endpoints).
- Deploy API — run commands, upload files, deploy the application, logs, port, metrics, lock, runtimes (8 endpoints).
- Access tokens — short-lived tokens for e2e checks and shareable links (3 endpoints).
- What arrives at the application — Gateway injection of
X-Vibe-Authorization: Bearer, reading identity via/v1/me, handler skeletons in Node/Python/Go. - Portal event subscriptions — delivery of Bitrix24 events (
ONTASKADDand similar) to the app through the tunnel, without polling (3 endpoints). - Galaxy app — the "container in a shared galaxy" placement model: how to tell it from a regular server (
kind), the build-on-upload lifecycle, per-galaxy pricing. - Server access recovery — the server is running but a new key cannot see it: an empty list,
404 NOT_FOUND, changing the managing key.
What to know up front
- The application port is always 3000. The Black Hole tunnel proxies exactly this port; you don't need to change it. The server is an isolated environment:
:3000inside the virtual machine has no relation to the ports on your local machine. - Deploy API is BLACKHOLE-only. All of
/deploy,/exec,/upload,/logsrequire servers inBLACKHOLEmode with the tunnel agent in statusCONNECTED. For OPEN servers they return an error. /deployand/execreturn JSON by default. This is safe for AI agents and MCP clients — no extra query parameters are needed. If you genuinely need a streaming response (live deploy-step output in the UI), pass?stream=true— then you get SSE (Server-Sent Events). The documentation used to claim the opposite (SSE by default,?stream=falsefor JSON) — that is outdated and no longer matches the API behavior.accessPolicyis security. Changing the policy fromOWNER_ONLYtoPORTAL/AUTHENTICATED/PUBLICopens the application to other users. Never changeaccessPolicywithout explicit user confirmation.- The server is a clean Ubuntu 24.04 with root access enabled. The virtual machine is created from a stock Ubuntu image with no preinstalled software (except the tunnel agent). The agent runs as the
rootuser — nosudois needed inpreStart,install, or/execcommands. Outbound internet is unrestricted:apt-get,curl,wget,pipwork directly. Inbound traffic is blocked except the tunnel connection. The app itself, however, does not run asroot— it runs under a dedicated unprivileged account. This applies to the app process only. Deploy commands and/execstill run with administrator privileges. Details and how to opt out — Deploying an app. - The Bitrix24 plan plays a dual role. First, the Bitrix24 REST API itself is available only on commercial Bitrix24 account plans — without one, neither applications, nor the
/v1/dealsproxy, nor bots, nor any other call proxied into Bitrix24 work. Second, on top of that — creating servers, deploying, and waking require a qualifying Bitrix24 plan: a commercial plan grants full access, a demo plan grants a limited trial, and a free plan is declined withINT_TARIFF_REQUIRED. This is an AI Beta; terms may change at any time. AI Router works independently of the Bitrix24 plan — it does not proxy into REST and is available even on free plans (BYOK free; platform models are billed against the Vibecode balance). Details are in the "Plan and access" section below. - User authorization inside the application. On every request the Gateway injects six headers prefixed with
X-Vibe-:Request-Idalways, plusUser-Id,User-Name,User-Role,Portal-Id,Authorization(Bearer vibe_session_<…>) for an authenticated request. The browser never sees or stores theAuthorizationtoken — it lives only between the Gateway and the app server. For a quick user identifier theX-Vibe-User-Idheader is enough; the full context (scopes,capabilities, plan, application info) comes from a singleGET /v1/mecall with server-side caching. The user ID in the/v1/meresponse isdata.currentUser.bitrixUserId; the Bitrix24 account domain isdata.portal. The full header table, the BFF pattern, and handler skeletons in Node/Python/Go — What arrives at the application. - Creating servers requires a user session for
vibe_app_keys.POST /v1/infra/serversis gated by a plan check that needs to know exactly who is creating the server. Forvibe_api_the user context already lives in the key itself; forvibe_app_anAuthorization: Bearer <session>is required — without it the response is401 UNAUTHENTICATEDwith anerror.hintpointing at the OAuth flow. Reads and the Deploy API on already-existing servers don't require a session — the "Endpoint authorization" table below collects all the rules in one place.
Quick start
Three calls — create a server and run the application.
curl — personal key
export VIBE_KEY="YOUR_API_KEY"
# 1. Create a server (automatically in Black Hole mode)
curl -X POST https://vibecode.bitrix24.com/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": "bc-eu-central",
"image": "ubuntu-2404-lts"
}'
# 2. Wait until ready: status=running AND blackholeStatus=CONNECTED
curl -H "X-Api-Key: $VIBE_KEY" \
https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID
# 3. Deploy the application (?stream=false — JSON instead of SSE).
# X-Skip-Source-Snapshot: deploy from an external URL while source
# storage is enabled, otherwise 409 SNAPSHOT_REQUIRED (see below).
curl -X POST "https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/deploy?stream=false" \
-H "X-Api-Key: $VIBE_KEY" \
-H "Content-Type: application/json" \
-H "X-Skip-Source-Snapshot: deploy from external URL" \
-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
}'
The application is reachable at https://app-{id}.vibecode.bitrix24.com — the appUrl field in the /deploy response.
Deploying from an external URL and source storage. When source storage is enabled for your Bitrix24 account, a deploy from an external address — not from Vibecode storage — returns 409 SNAPSHOT_REQUIRED so that the application's version history is not lost. The X-Skip-Source-Snapshot: <reason> header continues the deploy without saving a snapshot. To keep a snapshot, first upload the archive via POST /v1/apps/:id/sources, then deploy it via { "source": { "versionId": "vN" } }. More details — Source storage.
curl — OAuth application
# Same thing, just add the Authorization: Bearer header with the session token
curl -X POST https://vibecode.bitrix24.com/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": "bc-eu-central", "image": "ubuntu-2404-lts" }'
Full example
A realistic JavaScript scenario — create a server, wait until ready, deploy, get the application URL.
const VIBE_KEY = process.env.VIBE_KEY
const BASE = 'https://vibecode.bitrix24.com/v1'
async function api(method, path, body = null, extraHeaders = {}) {
const opts = { method, headers: { 'X-Api-Key': VIBE_KEY, ...extraHeaders } }
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. Pick provider, plan, region, image
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 === 'bc-eu-central')
const image = images[0]
// 2. Create a server (always in 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 created: ${server.id}, subdomain: ${server.subdomain}`)
// 3. Wait until status becomes running AND blackholeStatus becomes CONNECTED
let info = server
while (info.status !== 'running' || info.blackholeStatus !== 'CONNECTED') {
await new Promise(r => setTimeout(r, 10000)) // 10 seconds between polls
const res = await api('GET', `/infra/servers/${server.id}`)
info = res.data
console.log(`status=${info.status}, blackhole=${info.blackholeStatus}`)
}
// 4. Deploy the application (?stream=false is required for a JSON response).
// The X-Skip-Source-Snapshot header is needed when deploying from an
// external URL while source storage is enabled — otherwise 409 SNAPSHOT_REQUIRED.
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' },
}, { 'X-Skip-Source-Snapshot': 'deploy from external URL' })
console.log(`Application is live: ${deploy.data.appUrl}`)
// 5. (Optional) Configure auto-sleep after 60 minutes of inactivity
await api('PATCH', `/infra/servers/${server.id}/sleep`, { sleepAfterMinutes: 60 })
Galaxy app — a different contract. If your Bitrix24 account places apps in galaxies, the same
POST /v1/infra/serverscreates a Galaxy app — a container on a shared host. Upload the code right after creation, without waiting forblackholeStatus: "CONNECTED". The full model, lifecycle, cost, and deploy differences — Galaxy app.
Endpoint reference
Endpoint reference for the section. Links lead to pages with parameters, examples, and error codes.
Providers and catalogs:
| Method | Path | Description |
|---|---|---|
| GET | /v1/infra/providers |
List of cloud providers |
| GET | /v1/infra/providers/:providerId/plans |
Provider plans |
| GET | /v1/infra/providers/:providerId/regions |
Provider regions |
| GET | /v1/infra/providers/:providerId/images |
OS images |
Servers:
| Method | Path | Description |
|---|---|---|
| POST | /v1/infra/servers |
Create a server (always Black Hole) |
| GET | /v1/infra/servers |
List of your servers |
| GET | /v1/infra/servers/:id |
Server details |
| PATCH | /v1/infra/servers/:id |
Update the name and description |
| DELETE | /v1/infra/servers/:id |
Delete a server |
Lifecycle:
| Method | Path | Description |
|---|---|---|
| POST | /v1/infra/servers/:id/start |
Start a stopped/sleeping server |
| POST | /v1/infra/servers/:id/stop |
Stop a running server |
| POST | /v1/infra/servers/:id/reboot |
Reboot the server |
| POST | /v1/infra/servers/:id/wake |
Wake a sleeping server (async or blocking) |
| POST | /v1/infra/servers/:id/sleep-now |
Immediately put a BLACKHOLE server to sleep |
| PATCH | /v1/infra/servers/:id/sleep |
Configure auto-sleep |
| POST | /v1/infra/servers/:id/refresh |
Request status and IP from the provider |
| POST | /v1/infra/servers/:id/repair |
Restore the tunnel via serial console |
| GET | /v1/infra/servers/:id/repair-status |
Tunnel restore progress |
Scheduled wake:
| Method | Path | Description |
|---|---|---|
| GET | /v1/infra/servers/:id/wake-schedules |
List wake windows and their firing history |
| POST | /v1/infra/servers/:id/wake-schedules |
Create a wake window |
| PATCH | /v1/infra/servers/:id/wake-schedules/:scheduleId |
Update a wake window |
| DELETE | /v1/infra/servers/:id/wake-schedules/:scheduleId |
Delete a wake window |
Access and modes:
| Method | Path | Description |
|---|---|---|
| GET | /v1/infra/servers/:id/ssh |
SSH credentials (OPEN only) |
| PATCH | /v1/infra/servers/:id/mode |
Switch BLACKHOLE↔OPEN |
| PATCH | /v1/infra/servers/:id/access-policy |
Application access policy |
| GET | /v1/infra/servers/:id/access |
List of users and departments with access |
| POST | /v1/infra/servers/:id/access |
Add a user or department |
| DELETE | /v1/infra/servers/:id/access/:accessId |
Remove an access entry |
| GET | /v1/infra/servers/:id/b24-users |
Search Bitrix24 account users |
Deploy API:
| Method | Path | Description |
|---|---|---|
| POST | /v1/infra/servers/:id/exec |
Run a command (SSE or JSON) |
| POST | /v1/infra/servers/:id/upload |
Upload a file (base64 or by URL) |
| GET | /v1/infra/servers/:id/logs |
Service logs (journalctl utility) |
| POST | /v1/infra/servers/:id/deploy |
Full application deploy |
| PATCH | /v1/infra/servers/:id/port |
Set the application port |
| GET | /v1/infra/servers/:id/metrics |
Tunnel activity metrics |
| DELETE | /v1/infra/servers/:id/lock |
Release a stuck operation lock |
| GET | /v1/infra/runtimes |
List of available runtimes |
Access tokens:
| Method | Path | Description |
|---|---|---|
| POST | /v1/infra/servers/:id/access-tokens |
Issue an access token (api-bearer or share-url) |
| GET | /v1/infra/servers/:id/access-tokens |
List of server tokens |
| DELETE | /v1/infra/servers/:id/access-tokens/:tokenId |
Revoke a token |
Portal event subscriptions:
| Method | Path | Description |
|---|---|---|
| POST | /v1/infra/servers/:id/event-subscriptions |
Subscribe the server to a portal event (event.bind under the OAuth app) |
| GET | /v1/infra/servers/:id/event-subscriptions |
List subscriptions + recent deliveries |
| DELETE | /v1/infra/servers/:id/event-subscriptions/:subId |
Remove a subscription |
Endpoint authorization
All infra endpoints require the X-Api-Key header. For vibe_app_ keys (bound to an OAuth application) some POST operations additionally require Authorization: Bearer <session> — without it the response is 401 UNAUTHENTICATED with an error.hint. For vibe_api_ keys the user context already lives in the key itself, so a separate session is not needed.
| Endpoint | X-Api-Key |
Authorization: Bearer for vibe_app_ |
When Bearer is required |
|---|---|---|---|
GET /v1/infra/providers/* |
yes | no | — |
GET /v1/infra/servers, GET /v1/infra/servers/:id |
yes | no | — |
GET /v1/infra/servers/:id/logs, /metrics, /access, /access-tokens, /b24-users, /ssh |
yes | no | — |
GET /v1/infra/runtimes |
yes | no | — |
POST /v1/infra/servers (create a server) |
yes | yes | Plan gate: the platform needs to know exactly who is creating the server. |
POST /v1/infra/servers/:id/deploy, /exec, /upload |
yes | no | The vibe:infra scope on the key is enough. |
POST /v1/infra/servers/:id/start, /stop, /reboot, /wake, /sleep-now, /refresh, /repair, PATCH /sleep |
yes | no | — |
GET /v1/infra/servers/:id/wake-schedules |
yes | no | — |
POST /v1/infra/servers/:id/wake-schedules, PATCH/DELETE .../wake-schedules/:scheduleId |
yes | no | Requires scheduled wake to be enabled for the Bitrix24 account; otherwise 403 WAKE_SCHEDULE_DISABLED. |
PATCH /v1/infra/servers/:id/mode, /access-policy, /port |
yes | no | — |
POST /v1/infra/servers/:id/access, DELETE /v1/infra/servers/:id/access/:accessId |
yes | no | — |
POST /v1/infra/servers/:id/access-tokens, DELETE .../:tokenId |
yes | no | The platform flag accessTokensEnabled must be enabled; otherwise 503 FEATURE_DISABLED. |
POST/GET/DELETE /v1/infra/servers/:id/event-subscriptions |
yes | no | The server must be backed by an OAuth app with an application_token; otherwise 400 NOT_OAUTH_APP. |
PATCH /v1/infra/servers/:id (name and description) |
yes | no | — |
DELETE /v1/infra/servers/:id |
yes | no | — |
DELETE /v1/infra/servers/:id/lock |
yes | no | — |
Quick check before calling: GET /v1/me → data.capabilities.servers.create.available. For vibe_app_ without a session it returns false with reason: "SESSION_REQUIRED" and a hint in userMessage — the model immediately sees that it needs to go through the OAuth flow rather than hitting a 401 on the POST /v1/infra/servers itself.
Limits
| Limit | Value |
|---|---|
| Servers per API key | Set by the platform |
| Deploy API operations per minute per server | 10 |
Concurrent exec/deploy per server |
1 |
exec timeout |
1–600 seconds (default 300) |
base64 body size (upload inline, source.content) |
500 MB |
File size via source.url / upload url |
500 MB |
multipart archive size in deploy |
500 MB |
/ssh request rate |
up to 10 per minute |
The platform rate limit is shared across all V1 endpoints, see the "Limits and optimization" section.
Server statuses
| Status | Description |
|---|---|
provisioning |
The virtual machine is being created at the provider (1–3 minutes) |
running |
The virtual machine is running, IP assigned. For the tunnel you also need blackholeStatus: CONNECTED |
sleeping |
Stopped by the sleep timer or manually. Wakes automatically on a request to the HTTPS subdomain or a /deploy//start//wake call |
error |
The server is not in a working state: the virtual machine was deleted at the provider, the agent hasn't connected for a long time, the externalId is missing |
deleted |
The server is deleted (soft-delete). Cannot be restored |
The blackholeStatus field describes the agent tunnel state independently of status:
| Value | Description |
|---|---|
NONE |
Right after server creation, before the agent's first connection attempt |
WAITING |
The agent is preparing to connect |
CONNECTED |
The tunnel is active, the Deploy API is available |
DISCONNECTED |
The agent was connected, but the connection is now lost — try /repair |
The kind field distinguishes the placement model: STANDALONE — a separate virtual machine, GALAXY_APP — a Galaxy app (a container in a galaxy), GALAXY — the galaxy itself (the host carrier; created by the platform, not the user). A Galaxy app's blackholeStatus stays NONE until the code is uploaded — it does not connect on its own. More details — Galaxy app.
The runtimeStatus field is deprecated, kept for compatibility. For servers created after 2026-04-25 (when the runtime parameter was removed from POST /v1/infra/servers) it always returns null. The runtime is now installed at the POST /:id/deploy stage, and the readiness signal is the success of the runtime step itself in the deploy response.
Plan and access
Vibecode infrastructure has two levels of access conditions.
Level 1 — Bitrix24 REST API. Bitrix24 itself opens the REST API only on commercial Bitrix24 account plans. This is not about Vibecode: on free Bitrix24 plans it simply does not return REST responses. So without a commercial Bitrix24 plan the following do not work:
- Creating and publishing applications (
POST /api/apps) — registered in the Bitrix24 account via REST. - REST proxy:
/v1/deals,/v1/contacts,/v1/batch,/v1/bots,/v1/tasksand all other entities. - Bots, chats, tasks — everything proxied into Bitrix24.
Level 2 — Vibecode infrastructure. On top of the first condition, creating servers, deploying, and waking require a qualifying Bitrix24 plan — a commercial plan grants full access, a demo plan a limited trial, and a free plan is declined with INT_TARIFF_REQUIRED (this is an AI Beta; terms may change at any time):
POST /v1/infra/servers— creating a server.POST /v1/infra/servers/:id/deploy— deploying the application.POST /v1/infra/servers/:id/wakeand automatic waking whenpreventWake=true.- Creating agents and managed bots (they provision servers under the hood).
What works on any Bitrix24 plan, including free:
- AI Router —
POST /v1/chat/completions,POST /v1/audio/transcriptions,GET /v1/models. Does not proxy into Bitrix24, goes directly to LLM providers. With BYOK keys — free; with platform models — billed against the Vibecode balance. - Basic platform endpoints:
GET /v1/me,GET /v1/feedback,GET /v1/guide— for AI-agent self-orientation.
Check before calling: GET /v1/me → the capabilities.servers.create.available field. If false — the capabilities.servers.create.userMessage field contains a translated explanation for the user.
Force refresh after a plan upgrade: GET /v1/me?refresh=tariff — skips the cache (1 hour by default) and makes a fresh app.info request.
Access to servers: the single signal is capabilities.servers.create in the GET /v1/me response (see above). If access is closed, POST /v1/infra/servers returns 402 (or 403 for REGION_NOT_SUPPORTED) with the access-gate code (see "Error codes" below). Access is governed by your Bitrix24 plan: a commercial plan grants full access, a demo plan a limited trial, and a free plan is declined with INT_TARIFF_REQUIRED.
Response headers of the infra endpoints:
| Header | Value |
|---|---|
X-Tariff-Checked-At |
ISO timestamp of the last reconciliation via app.info (max 1 hour of cache) |
X-Tariff-Is-Commercial |
"true" or "false" |
The access-gate error codes are listed in the "Error codes" section below.
Error codes
Infrastructure errors
| Code | HTTP | Description |
|---|---|---|
NOT_FOUND |
404 | Server not found or belongs to a different API key |
INVALID_REQUEST |
400 | Validation error (invalid name, plan, region, image) |
INFRA_NOT_PERMITTED |
403 | Infrastructure disabled on the platform or on the portal |
SERVER_CREATION_DISABLED |
403 | Server creation forbidden by portal policy |
MAX_SERVERS_REACHED |
403 | The per-API-key server limit is exceeded |
NO_CREDENTIALS |
404 | The provider is not configured on the platform |
SERVER_NOT_READY |
409 | The server is still being created, the operation is not available yet |
CONFLICT |
409 | The server is in a status from which the action cannot be performed (e.g. start on a running one) |
PROVIDER_ERROR |
502 | The cloud provider returned an error |
VM_MISSING |
422 | The record has no externalId — the virtual machine was not created at the provider or was deleted externally. Delete the server via DELETE and create a new one |
PORT_RESTRICTED |
400 | Port 1–1023 (system ports forbidden). Allowed: 0 (auto-detect) and 1024–65535 |
BLACKHOLE_ONLY |
400 | The endpoint works only for BLACKHOLE servers (applies to /sleep-now, /sleep, /metrics) |
OPEN_MODE_NOT_ALLOWED |
403 | Switching to OPEN is forbidden by the portal policy allowOpenMode |
SAME_MODE |
400 | The server is already in the requested mode |
NOT_IMPLEMENTED |
501 | The action is not supported by the provider (e.g. /reboot on some plugins) |
REPAIR_BLOCKED |
409 | Repair is blocked (preventWake=true or the server is deleted) |
Deploy API errors
| Code | HTTP | Description |
|---|---|---|
SERVER_NOT_READY |
409 | The server is not ready for the operation: it is not running, the tunnel is not connected, or the server is listed as connected but the Gateway has no live tunnel. The response carries a hint field with the reason and the next step. The platform attempts to restore the tunnel itself. If that does not succeed — wake the server or call /repair and repeat the request |
EXEC_BUSY |
409 | Another operation is already running on the server. Use /lock to release a stuck lock |
COMMAND_TOO_LONG |
400 | The /exec command is longer than 10,000 characters. Ship large payloads and scripts via /upload |
EXEC_TIMEOUT |
200 | Execution timeout exceeded. The failure arrives in the response body |
EXEC_FAILED |
200 | Command execution error on the agent. The failure arrives in the response body |
UPLOAD_PATH_DENIED |
403 | Forbidden upload path |
DEPLOY_FAILED |
200 | One of the deploy steps failed — error.step names which one. The failure arrives in the response body |
DEPLOY_TIMEOUT |
200 | A deploy step did not finish within its time limit |
DEPLOY_CONNECTION_TERMINATED |
200 | The connection to the server dropped mid-deploy. The deploy may be partially applied — check the failing step and retry |
DEPLOY_TUNNEL_STALE |
200 | The Gateway has no live tunnel for the server. Call /repair and retry the deploy |
VALIDATION_ERROR |
400 | Malformed Deploy API request body |
For /exec and /deploy on a separate virtual machine (kind: "STANDALONE"), the connection is held open for the whole run, so the 200 status is sent before the work starts. A failure during execution arrives in the response body — the marker is success: false, not the HTTP status. Check success, otherwise a failed command will be mistaken for a successful one. For a Galaxy app (kind: "GALAXY_APP") the same error arrives with the status 502 — the 200 HTTP statuses in the table above apply to a separate virtual machine.
In streaming mode (?stream=true) a failure arrives as an SSE error event with code and message — this is how /exec and a deploy report a failure on an exception or a transport drop. For a deploy, a failure of an individual step arrives differently — as a step event with status: "error" and the step name. There is no success field in the stream.
Access-gate and billing errors
| Code | HTTP | Description |
|---|---|---|
INT_TARIFF_REQUIRED |
402 | The portal is on a free Bitrix24 plan — creating servers, deploying, and waking require a commercial plan (a demo plan grants a limited trial) |
REGION_NOT_SUPPORTED |
403 | Infrastructure access is not yet available in the portal's region |
COMMERCIAL_PLAN_REQUIRED |
402 | The Bitrix24 plan is free and does not grant access — a commercial plan is required |
TRIAL_PORTAL_LIMIT |
402 | The per-portal server limit for the trial period is exceeded (1 server per portal) |
PLAN_NOT_ALLOWED_ON_TRIAL |
402 | The requested plan is not available during the trial period. error.details.allowedPlans lists the plans the trial gate is configured for; error.details.requestedPlan, when present, echoes the rejected plan |
ACCOUNT_FROZEN |
402 | The Vibecode balance is frozen. A top-up is required |
BILLING_EXHAUSTED |
402 | The Vibecode balance is exhausted. Waking and deployment are blocked |
SERVER_WAKE_BLOCKED |
403 | Waking is blocked (not due to billing: administrative block, security) |
System errors
| Code | HTTP | Description |
|---|---|---|
MISSING_API_KEY |
401 | The X-Api-Key header was not provided |
INVALID_API_KEY |
401 | Invalid or expired API key |
SCOPE_DENIED |
403 | The key does not have the vibe:infra scope |
RATE_LIMITED |
429 | The request rate limit was exceeded. The response carries the Retry-After header |
INTERNAL_ERROR |
500 | Internal server error |
The full reference of common errors — Errors.
App icon
The app icon (SVG) appears in the Bitrix24 catalog and as the browser-tab favicon. The format, requirements and order (favicon <link> before deploy, POST /v1/infra/servers/:id/icon upload after) live on a dedicated page — App icon.
Recipes
- Load a database dump onto a server — upload a dump and restore the database in the background via
exec. - A fast release cycle — shorten the edit cycle without running every step.
See also
- API overview — overall platform architecture.
- Limits and optimization — rate limits, auto-pagination, batch requests.
- Keys and authorization (
/v1/me) — plan and capability check. - What arrives at the application — Gateway injection of
X-Vibe-Authorization, BFF pattern, handler skeletons.