
# Deploy API

Deploying applications to BLACKHOLE servers without SSH. All operations go through the tunnel agent: commands run on the server, files are uploaded through the tunnel, logs are read from the system journal (the `journalctl` utility). AI agents should use this group of endpoints for the full cycle: "pull code from git → install dependencies → start the service → read logs".

**Requirements:** server in `BLACKHOLE` mode, `running` status, `blackholeStatus: CONNECTED`. In OPEN mode the Deploy API returns `NOT_BLACKHOLE`.

> **This is the contract for a Black Hole VM (`kind: "STANDALONE"`).** For a galaxy application (`kind: "GALAXY_APP"`) the `CONNECTED` requirement does not apply — the deploy builds the container itself. The full model and deploy contract for a galaxy application — [Galaxy application](./galaxy.md).

> **Galaxy application OOM → release to a dedicated server.** If a galaxy application deploy fails with `502 GALAXY_APP_START_FAILED` specifically due to OOM (the application outgrew the container memory limit of 512 MB), the response contains a structural hint `error.hint` with `recoveryAction: "graduate-to-dedicated-vm"`. The recommended action is to recreate the application on a separate virtual machine: [`POST /v1/infra/servers`](/docs/infra/servers/create) with `placement: "dedicated"` and `graduateFrom` (the identifier of the failed galaxy application, which will be deleted after the server is created), then `POST /v1/infra/servers/:id/deploy` with the same source code. Retry protection via the `Idempotency-Key` header does not extend to this release — together with `graduateFrom` it returns `400 IDEMPOTENCY_UNSUPPORTED_WITH_GRADUATION`. This is allowed when the Bitrix24 account's `serverCreation` policy permits creating servers and you are within quota. A dedicated virtual machine is billed (it sleeps when idle). The hint is added only when the cause is OOM, not on an ordinary crash.

**Response format:** all endpoints return **JSON** by default (201/200 with `{"success": true, ...}`). For `/deploy` and `/exec` a streaming mode is available via `?stream=true` — an SSE (Server-Sent Events) stream with line-by-line progress is returned. For AI agents and MCP clients **always use JSON** (do not add `?stream=true`) — they cannot parse SSE.

**Rate limits:**

| Limit | Value |
|-------------|----------|
| Operations per minute per server | 10 |
| Concurrent `exec`/`deploy` | 1 per server |
| `exec` timeout | 1–600 seconds (default 300) |
| Inline body size (base64 in `/upload`, `/deploy source.content`) | 500 MB |
| File size via URL (`/upload url`, `/deploy source.url`) | 500 MB |
| Multipart archive size in `/deploy` | 500 MB |

Scope: `vibe:infra`

## Operations

- [Run a command](./deploy/exec.md) — `POST /v1/infra/servers/:id/exec`
- [Upload a file](./deploy/upload.md) — `POST /v1/infra/servers/:id/upload`
- [Service logs](./deploy/logs.md) — `GET /v1/infra/servers/:id/logs`
- [Full application deploy](./deploy/deploy.md) — `POST /v1/infra/servers/:id/deploy`
- [Set the application port](./deploy/port.md) — `PATCH /v1/infra/servers/:id/port`
- [Tunnel metrics](./deploy/metrics.md) — `GET /v1/infra/servers/:id/metrics`
- [Clear a stuck lock](./deploy/lock.md) — `DELETE /v1/infra/servers/:id/lock`
- [List runtimes](./deploy/runtimes.md) — `GET /v1/infra/runtimes`

## Capabilities

- [A fast release cycle](./deploy/fast-cycle.md) — techniques that shorten repeat releases without running every step

## Typical scenario

**Full deploy cycle in a single request:**

1. [`POST /v1/infra/servers`](/docs/infra/servers/create) — create a server.
2. Wait for readiness via [`GET /v1/infra/servers/:id`](/docs/infra/servers/get) (`status: "running"` + `blackholeStatus: "CONNECTED"`).
3. [`POST /deploy`](./deploy/deploy.md) — specify `source.url` / `runtime` / `install` / `start` / `port`. All deploy steps run automatically. By default the response is JSON — `?stream=true` is only needed if you want SSE.
4. After the deploy — [`GET /logs?lines=100`](./deploy/logs.md) to verify.
5. While debugging — [`POST /exec`](./deploy/exec.md) for one-off commands.

**Manual cycle (without `/deploy`):**

1. [`POST /upload { source.url }`](./deploy/upload.md) — place the archive, unpack it.
2. [`POST /exec { command: "cd /opt/app && npm install" }`](./deploy/exec.md) — dependencies.
3. [`POST /exec { command: "systemctl start app" }`](./deploy/exec.md) — start the service.
4. [`GET /logs?service=app&lines=50`](./deploy/logs.md) — confirm it works.

[`POST /deploy`](./deploy/deploy.md) does everything at once and checks the application's health itself.

## App icon

The app icon (SVG) shows 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](/docs/infra/app-icon).

## Guides

- [Load a database dump onto a server](/docs/recipes/db-dump-restore) — upload a dump and restore the database in the background via `exec`.

## See also

- [Creating a server](/docs/infra/servers/create) — the step before deploy.
- [Lifecycle](/docs/infra/lifecycle) — `wake` for a sleeping server before deploy.
- [Switch the mode](/docs/infra/access/mode) — the Deploy API does not work in OPEN.
- [Root section — Infrastructure](/docs/infra) — limits and errors in general.
