
## Get a server

`GET /v1/infra/servers/:id`

Returns details of a single server by ID. If the server is in the `provisioning` status, the endpoint automatically polls the cloud provider for the current status and IP — suitable for a polling loop after creation. A deleted server (`status: "deleted"`) is not accessible: a 404 is returned.

## Parameters

| Parameter | In | Type | Required | Description |
|----------|---|-----|:-----:|----------|
| `id` | path | string (UUID) | yes | Server ID from [`POST /v1/infra/servers`](./create.md) or [`GET /v1/infra/servers`](./list.md) |

## Examples

### curl — personal key

```bash
curl -H "X-Api-Key: YOUR_API_KEY" \
  https://vibecode.bitrix24.com/v1/infra/servers/e765edfc-ba0a-43de-b8ea-838dd872c522
```

### curl — OAuth application

```bash
curl -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID
```

### JavaScript — personal key

```javascript
// Poll the server until it is ready
async function waitReady(serverId) {
  while (true) {
    const res = await fetch(
      `https://vibecode.bitrix24.com/v1/infra/servers/${serverId}`,
      { headers: { 'X-Api-Key': 'YOUR_API_KEY' } }
    )
    const { data } = await res.json()
    if (data.status === 'running' && data.blackholeStatus === 'CONNECTED') {
      return data
    }
    if (data.status === 'error') {
      throw new Error(`Server in error: ${data.id}`)
    }
    await new Promise(r => setTimeout(r, 10000))
  }
}
```

### JavaScript — OAuth application

```javascript
const res = await fetch(
  `https://vibecode.bitrix24.com/v1/infra/servers/${serverId}`,
  {
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
    },
  }
)
const { data } = await res.json()
```

## Response fields

| Field | Type | Description |
|------|-----|----------|
| `success` | boolean | Always `true` on success |
| `data.id` | string (UUID) | Server ID |
| `data.status` | string | `provisioning` \| `running` \| `sleeping` \| `error`. A deleted server returns 404 |
| `data.provider` | string | Provider ID |
| `data.kind` | string | Resource type: `STANDALONE` (a dedicated virtual machine), `GALAXY` (a host carrying Galaxy applications) or `GALAXY_APP` (a Galaxy application — a container on a shared host). Determines the deploy contract — check it before uploading code |
| `data.galaxyId` | string (UUID) \| null | For `GALAXY_APP` — the ID of the host the application runs on. `null` for other types |
| `data.appCount` | number \| null | For a `GALAXY` host — the number of non-deleted applications on it. `null` for other types |
| `data.name` | string | System name of the server — the technical identifier |
| `data.displayName` | string \| null | Human-readable name for the UI. Equals `name` if it was not provided at creation |
| `data.description` | string \| null | Application description shown on the Bitrix24 catalog card. `null` if no description was set. Changed via [`PATCH /v1/infra/servers/:id`](./update.md) |
| `data.ip` | string \| null | Public IP. `null` until the virtual machine receives an address |
| `data.ssh` | object \| null | For an OPEN server: `{ user, port, hasPassword }`. For BLACKHOLE it may be `null` or the same block without actual access. **The password and private key are not returned here** — they are returned only once, by [`POST /v1/infra/servers`](./create.md), at creation |
| `data.plan` | string | Plan. **For a Galaxy application** (`kind: "GALAXY_APP"`) the host's plan is returned, not the one requested at creation — applications share the host's resources |
| `data.region` | string | The region the server actually landed in. **For a Galaxy application** the host's region is returned (the platform picks placement itself), not the one requested |
| `data.image` | string | OS image |
| `data.monthlyCost` | string | Catalog monthly cost in Vibe credits (Ꝟ) as a string (for example `"24"`). The amount actually billed may differ. Compare via `Number(data.monthlyCost)` |
| `data.mode` | string | `BLACKHOLE` or `OPEN` |
| `data.createdVia` | string | `api` — a call through the Vibecode API, `ui` — an action in the Vibecode dashboard, `galaxy` — a Galaxy application. Servers of agents and bots carry their own values |
| `data.subdomain` | string | Subdomain for the application |
| `data.blackholeStatus` | string | `NONE` \| `WAITING` \| `CONNECTED` \| `DISCONNECTED` |
| `data.accessPolicy` | string | `OWNER_ONLY` \| `NAMED_USERS` \| `DEPARTMENT` \| `PORTAL` \| `AUTHENTICATED` \| `PUBLIC` |
| `data.runtimeId` | string \| null | ID of the runtime installed via POST /:id/deploy (server creation always returns `null`). |
| `data.runtimeStatus` | string \| null | Runtime status from the last deploy: `null` (fresh server), `installing`, `ready`, or `error`. Server creation always returns `null` — the runtime is installed via POST /:id/deploy. |
| `data.appUrl` | string \| null | HTTPS address of the application |
| `data.localPort` | number | Local port the tunnel forwards traffic to (default `3000`). Changed via [`PATCH /v1/infra/servers/:id/port`](/docs/infra/deploy/port) |
| `data.sleepAfterMinutes` | number \| null | After how many idle minutes the server is put to sleep automatically. `null` — never auto-sleep |
| `data.provisionError` | string \| null | A short reason for the last provisioning/build failure. `null` if there were no errors |
| `data.provisionErrorCode` | string \| null | Machine-readable failure category: `PREEMPTIBLE_EVICTION` / `PROVISION_TIMEOUT` / `NO_CAPACITY` / `GENERIC`. `null` if there were no errors |
| `data.provisionReason` | string \| null | Structured cause of a Galaxy application failure: `oom` — the container ran out of memory, or `crash`. `null` for regular servers and when there was no failure. `oom` is the signal to move the application to a dedicated server; the procedure is described in [Create a server](./create.md) |
| `data.buildLog` | string \| null | Tail of the docker build log (≤8 KB) for a failed Galaxy application build. `null` for regular servers and on a successful build |
| `data.nextScheduledWakeAt` | string (ISO 8601) \| null | The next scheduled wake time (lead offset included). `null` if the server has no enabled wake windows. Configured via [Scheduled wake](/docs/infra/wake-schedules) |
| `data.wakeScheduleCapable` | boolean | Whether scheduled wake windows can be configured for the server — depends on the server kind and whether the feature is enabled for the Bitrix24 account |
| `data.buildHint` | string \| null | A localized recommendation on what to do about a failed Galaxy application build. The field is always present. It is `null` for regular servers, for a Galaxy application outside the `error` status, and when the failure could not be matched to any known category |
| `data.createdAt` | string (ISO 8601) | Creation timestamp |

## Response example

```json
{
  "success": true,
  "data": {
    "id": "e765edfc-ba0a-43de-b8ea-838dd872c522",
    "status": "running",
    "provider": "bitrix-cloud",
    "kind": "STANDALONE",
    "galaxyId": null,
    "appCount": null,
    "name": "vibe-server-pd9l",
    "displayName": "vibe-server-pd9l",
    "description": null,
    "ip": "111.88.251.211",
    "ssh": {
      "user": "ubuntu",
      "port": 22,
      "hasPassword": true
    },
    "plan": "bc-small",
    "region": "bc-eu-central",
    "image": "ubuntu-2404-lts",
    "monthlyCost": "24",
    "mode": "OPEN",
    "createdVia": "ui",
    "subdomain": "app-05b67cf7",
    "blackholeStatus": "CONNECTED",
    "accessPolicy": "OWNER_ONLY",
    "runtimeId": null,
    "runtimeStatus": null,
    "appUrl": "https://app-05b67cf7.vibecode.bitrix24.com",
    "localPort": 3000,
    "sleepAfterMinutes": null,
    "provisionError": null,
    "provisionErrorCode": null,
    "provisionReason": null,
    "buildLog": null,
    "nextScheduledWakeAt": null,
    "wakeScheduleCapable": true,
    "buildHint": null,
    "createdAt": "2026-04-03T13:30:25.819Z"
  }
}
```

## Error response example

404 — a server with this ID does not exist or belongs to another API key:

```json
{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Server not found"
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|----------|
| 401 | `MISSING_API_KEY` | The `X-Api-Key` header was not passed |
| 401 | `INVALID_API_KEY` | Invalid or expired API key |
| 404 | `NOT_FOUND` | Server not found or belongs to another API key |
| 429 | `RATE_LIMITED` | The platform's overall request limit was exceeded |

The full list of common API errors — [Errors](/docs/errors).

## Known specifics

- **No provider request is made for `running`/`sleeping`/`error`.** Automatic provider polling happens only when the status is `provisioning`. If you need to reconcile the state of other statuses — use [`POST /v1/infra/servers/:id/refresh`](/docs/infra/lifecycle/refresh).
- **The readiness criterion is two fields.** To continue working with the [Deploy API](/docs/infra/deploy) you need both `status: "running"` **and** `blackholeStatus: "CONNECTED"` at the same time. If only `running` is set — the virtual machine is already alive, but the tunnel agent has not connected yet. If `runtime` was used during deploy — additionally wait for `runtimeStatus: "ready"`.
- **`blackholeStatus: "DISCONNECTED"` with `running`** — the tunnel lost its connection on a live server. Try [`POST /v1/infra/servers/:id/repair`](/docs/infra/lifecycle/repair).
- **`monthlyCost` pitfall:** the field is returned as a string. Two such strings are compared character by character: `"24" > "1000"` returns `true`, and `.sort()` orders the values by text rather than by size. Convert to a number via `Number(data.monthlyCost)`.
- **If you lost the SSH credentials from the creation response — they cannot be recovered.** Recreate the SSH key manually via [`POST /v1/infra/servers/:id/exec`](/docs/infra/deploy/exec) (for BLACKHOLE) or recreate the server.

## See also

- [Create a server](./create.md)
- [List servers](./list.md)
- [Update name and description](./update.md)
- [Delete a server](./delete.md)
- [Refresh status](/docs/infra/lifecycle/refresh)
- [Tunnel metrics](/docs/infra/deploy/metrics)
