For AI agents: markdown of this page — /docs-content-en/infra/galaxy.md documentation index — /llms.txt

Galaxy app

A Galaxy app is a separate Black Hole application that lives in a container on a shared host — a galaxy — together with other such apps. Each app gets its own HTTPS subdomain and isolation, like a separate virtual machine, but they all share one galaxy — which is many times cheaper than keeping a separate server per app. If the Bitrix24 account administrator enabled placement in galaxies, the same POST /v1/infra/servers call creates a Galaxy app instead of a virtual machine.

Scope: vibe:infra · Base URL: https://vibecode.bitrix24.com/v1 · Authorization: X-Api-Key header

Who chooses the placement model

The placement mode is chosen by the Bitrix24 account administrator in the dashboard, on the Galaxies page, in the Placement section. A regular Bitrix24 account member sees the mode as read-only, and the API caller does not set it. The same POST /v1/infra/servers request creates either a separate virtual machine or a Galaxy app, depending on the placement mode. There is no "create a Galaxy app specifically" parameter in the request.

The placement mode is one of three:

  • Galaxy First (galaxies-only) — new apps are placed densely inside galaxies. If an app outgrows its container, it is moved to a separate Black Hole server.
  • Hybrid (both) — an app lands in a galaxy when there is room, otherwise it is deployed on a separate virtual machine.
  • Standalone only (standalone-only) — galaxies are not used, each app gets its own virtual machine.

What the caller should do about it:

  • Detect the model from the response, do not set it. A Galaxy app is identified by the createdVia field equal to galaxy in the create response. The full list of signs is in the "How to tell a Galaxy app in the response" section below.
  • Need a separate virtual machine — request it explicitly. If your Bitrix24 account places apps in galaxies but a particular app needs a dedicated server, pass the placement field equal to dedicated in the body of POST /v1/infra/servers — the platform will create a separate virtual machine instead of a Galaxy app. By default placement equals auto, and the placement mode applies.

Readiness differs between the models:

  • Separate virtual machine — by status: "running" and blackholeStatus: "CONNECTED".
  • Galaxy app — only through a code upload, waiting for CONNECTED does not work here (see "Lifecycle" below).

How to tell a Galaxy app in the response

Field Where Value
createdVia response of POST /v1/infra/servers galaxy for a Galaxy app
kind response of POST /v1/infra/servers and GET /v1/infra/servers/:id GALAXY_APP — a Galaxy app (container), GALAXY — a galaxy (the carrier host), STANDALONE — a separate virtual machine
galaxyId response of POST /v1/infra/servers and GET /v1/infra/servers/:id ID of the galaxy the app runs in. null for other types
appCount response of GET /v1/infra/servers/:id For a galaxy (GALAXY) — the number of non-deleted apps in it. null for other types

A Galaxy app has no SSH access of its own (ssh equals null), no public IP address and no external virtual-machine identifier — a container has none of these. The region and plan fields in the response are the region and plan of the carrier galaxy: the values passed at creation have no effect, the platform chooses placement itself.

Lifecycle — build on code upload

A Galaxy app never reaches blackholeStatus: "CONNECTED" on its own. Its container and tunnel agent are created by the code upload itself — there is no separate provisioning step like a virtual machine has.

This leads to the main rule: upload the code right after creation, without waiting for CONNECTED. If you create a Galaxy app and just poll the status, it stays in provisioning, and after about 20 minutes the platform marks it as error and records in the provisionError field that the code was never uploaded.

Creating and uploading code

Creation goes through the same POST /v1/infra/servers call. The code is uploaded in one of two scenarios.

  • Scenario 1 — single request. Pass the code in the source field together with runtime and start right in POST /v1/infra/servers. The build runs in the background, no separate upload call is needed.
  • Scenario 2 — two steps. Create the app without source, get next: "deploy" in the response, then upload the code via POST /v1/infra/servers/:id/deploy. Creating an app without source requires provider/plan/region (informational for a galaxy — see the example in create.md).

Full request bodies, fields and examples for both scenarios are on the Create a server page.

Creating a Galaxy app via scenario 1 — source passed, build running in the background. The model is identified by createdVia equal to galaxy:

JSON
{
  "success": true,
  "data": {
    "id": "7c2b1f08-3a4d-4e91-9b6c-2f5e8a1d0c33",
    "status": "provisioning",
    "name": "my-crm-app",
    "kind": "GALAXY_APP",
    "galaxyId": "<galaxy-host-id>",
    "ssh": null,
    "ip": null,
    "plan": "bc-medium",
    "region": "bc-eu-central",
    "mode": "BLACKHOLE",
    "createdVia": "galaxy",
    "subdomain": "app-7c2b1f08",
    "blackholeStatus": "NONE",
    "appUrl": "https://app-7c2b1f08.vibecode.bitrix24.com",
    "createdAt": "2026-04-22T10:50:11.477Z"
  }
}

Deploy

Deploying a Galaxy app differs from deploying a virtual machine. The full contract is on the Deploy application page.

  • The code source is only the inline source.content (a base64 archive). The source.url and source.versionId variants are rejected with 400 GALAXY_DEPLOY_CONTENT_ONLY.
  • The runtime and start fields are required. Without runtime the request returns 400 GALAXY_DEPLOY_RUNTIME_REQUIRED. The runtime list is at GET /v1/infra/runtimes.
  • You do not need to add a Dockerfile — the platform generates it from the runtime, port and start fields.
  • The env variables are injected into the container at start, not baked into the image, so secrets do not end up in the image layers.
  • The container working directory is /opt/app, and the /app path is also a link to it. Store persistent data in the /data volume.

Cost

Cost is counted per galaxy, not per app. Several Galaxy apps in one galaxy share its cost — five apps on a bc-small plan cost roughly the same as one galaxy, not as five servers. Galaxy apps do not count toward the per-API-key server limit (GET /v1/meinfra.limits.used) — it counts only separate virtual machines.

Logs

For a Galaxy app, GET /v1/infra/servers/:id/logs returns the output stream of the container itself (stdout and stderr), not the galaxy system journal. Reading logs does not wake a sleeping galaxy. If the galaxy is asleep or unreachable, the response is an empty data.logs array plus a diagnostic data.hint field. The since parameter for a Galaxy app accepts only a duration (10m, 2h, 24h) or a timestamp in RFC 3339 format (for example, 2026-04-22T10:50:11Z).

Deletion

A Galaxy app is removed with the same DELETE /v1/infra/servers/:id call — the platform tears down its container in the galaxy and marks the record deleted. The platform wakes a sleeping galaxy itself before deletion. A galaxy with non-deleted apps is not deleted by this call — remove its apps first.

Error codes

HTTP Code Description
400 SOURCE_AT_CREATE_GALAXY_ONLY The source field was passed at creation in a portal without galaxy mode. Upload the code via POST /:id/deploy after creation
400 GALAXY_DEPLOY_CONTENT_ONLY Deploying a Galaxy app with source.url or source.versionId. The source is only the inline source.content
400 GALAXY_DEPLOY_RUNTIME_REQUIRED Deploying a Galaxy app without runtime. Specify a runtime, for example node20
502 GALAXY_APP_BUILD_FAILED The container build failed. The tail of the build log arrives in the buildLog field, and the breakdown of the cause in error.category and error.buildHint — see Upload code
502 GALAXY_APP_START_FAILED The container built but crashed or went into a restart loop due to lack of memory right after start. The log tail arrives in the buildLog field, and the breakdown of the cause in error.category and error.buildHint — see Upload code
409 GALAXY_HAS_APPS The server being deleted is a galaxy that still has non-deleted apps. The body contains appCount
502 GALAXY_DEPLOY_INTERRUPTED The galaxy host is reachable, but a connection drop during the build interrupted the deploy and its successful completion was not confirmed. Your app slot and the /data volume are preserved — retry the same request. If the error repeats, the app is likely failing to start — check the start command, port, dependencies, environment variables, and memory limit
502 GALAXY_HOST_UNREACHABLE The galaxy is unreachable — its tunnel is not in CONNECTED status. The response carries error.hint with a recovery plan, see below

The full reference of common API errors is on the Errors page.

The `error.hint` field of `GALAXY_HOST_UNREACHABLE`

A 502 GALAXY_HOST_UNREACHABLE response carries an error.hint object of four strings:

Field What it holds
reason Why the galaxy is unreachable right now — its virtual machine is waking up, or the agent is reconnecting the tunnel
recovery What to do. The wording depends on where the error came from — see the three branches below
recoveryAction The concrete action to retry. Also depends on the source of the error
note A caveat: the galaxy status in the listing can lag behind the real tunnel state. If the condition holds beyond 15 minutes, the galaxy is genuinely down

The reason and note fields are always the same, while recovery and recoveryAction differ by the source of the error:

Source What the hint advises
Code upload (POST /v1/infra/servers/:id/deploy) Wait 1–2 minutes and re-send the same deploy to the same server ID. A sleeping galaxy is woken by the deploy itself
Command run (POST /v1/infra/servers/:id/exec) ⚠️ If the galaxy is asleep, retries will not wake it — wake it first with a deploy or from the cabinet, and only then retry. If the galaxy was running, wait 1–2 minutes for the tunnel to re-establish
Deletion (DELETE /v1/infra/servers/:id) Wait 1–2 minutes and retry the deletion. The server record is preserved until the teardown actually runs on the galaxy

In all three cases there is no need to delete and recreate the application: the slot, its container and its /data volume are intact, and a fresh slot lands on the same galaxy and meets the same condition.

See also