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

Reboot server

POST /v1/infra/servers/:id/reboot

Reboots a running server at the cloud provider. During the reboot the server moves to provisioning, the tunnel is briefly dropped — blackholeStatus becomes DISCONNECTED — and reconnects after the virtual machine starts. The operation is atomic: an internal database-level guard prevents races if several calls arrive at once. If the provider does not support reboot, the endpoint returns 501 and the status is rolled back to running.

Parameters

Parameter In Type Required Description
id path string (UUID) yes ID of a server in running status

The request body is empty.

Examples

curl — personal key

Terminal
curl -X POST -H "X-Api-Key: YOUR_API_KEY" \
  https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/reboot

curl — OAuth application

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

JavaScript — personal key

javascript
await fetch(
  `https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/reboot`,
  { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY' } }
)

// Poll readiness after the reboot
while (true) {
  await new Promise(r => setTimeout(r, 5000))
  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') break
}

JavaScript — OAuth application

javascript
await fetch(
  `https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/reboot`,
  {
    method: 'POST',
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
    },
  }
)

Response fields

Field Type Description
success boolean true. The reboot command was sent to the provider

Response example

JSON
{ "success": true }

Error response example

422 — the server exists but is not in running status. The response carries the current state and the actions available now:

JSON
{
  "success": false,
  "error": {
    "code": "SERVER_WRONG_STATE",
    "message": "Server is SLEEPING; /reboot requires RUNNING.",
    "userMessage": "Server is currently SLEEPING. Reboot only applies to a RUNNING server.",
    "currentState": { "status": "sleeping", "blackholeStatus": "DISCONNECTED", "hasExternalId": true },
    "availableActions": ["wake", "start", "repair", "delete"]
  }
}

409 — the server status changed during the operation (race):

JSON
{
  "success": false,
  "error": {
    "code": "CONFLICT",
    "message": "Server state changed during operation"
  }
}

Errors

HTTP Code Description
401 MISSING_API_KEY The X-Api-Key header was not provided
401 INVALID_API_KEY Invalid or expired API key
402 ACCOUNT_FROZEN The Vibecode balance is frozen. Top up and retry
403 INFRA_FORBIDDEN_FOR_COWORK_KEY The call was made with a Cowork/Code key — such a key works with data only and cannot perform write operations. To issue a key that can, see Project key for deploy
403 SERVER_ROLE_FORBIDDEN You are on this server's development team with the Developer role, and this operation is open to the Administrator role. error.hint carries your role, the required threshold and the list of calls that are open to you. Role breakdown — List servers
404 SERVER_NOT_FOUND No server with this id — deleted, or belonging to another API key while you are not on its development team
409 CONFLICT State race — the server status changed during the operation. Retry the request after checking GET /v1/infra/servers/:id
422 SERVER_WRONG_STATE The server exists but is not in running status. error.currentState carries the current state; error.availableActions lists what you can do now
422 VM_MISSING The server record has no cloud VM (provisioning never finished or the VM was removed manually) — delete the server and create a new one
429 RATE_LIMITED The platform's overall request limit was exceeded
501 NOT_SUPPORTED The cloud provider does not support reboot. Use the sequence /stop/start
502 PROVIDER_ERROR The cloud provider returned an error. The server status is automatically rolled back to running

The full list of common API errors — Errors.

Known specifics

  • Atomic transition running → provisioning. The database is updated with a single updateMany conditioned on status = 'RUNNING'. If another /reboot or /stop arrives at the same moment, the second call gets 409 CONFLICT.
  • Automatic rollback on a provider error. If adapter.rebootServer() throws an exception, the record is reverted to running status — so the client is not left with a "stuck" provisioning.
  • To restart only the application (without rebooting the virtual machine), use POST /exec with the command systemctl restart app — it is dozens of times faster and does not break the tunnel.
  • After a reboot, wait for both fields. For the server to be ready, you need both status: "running" and blackholeStatus: "CONNECTED" at the same time — the tunnel reconnects after the virtual machine starts.

Galaxy apps (kind=GALAXY_APP)

For a Galaxy app container (kind=GALAXY_APP — it has no virtual machine of its own), /reboot restarts the container on the host rather than rebooting a VM. It is a self-recovery kick for a stuck or crash-looping app: it does not wipe the persistent /data volume (unlike deletion).

The restart is advisory — it does not change the record's status and does not clear the crash marker. After the restart the container is probed, and the response carries a healthy verdict: whether the container came up and stopped restarting. This inspects the container state (docker inspect), not the app's HTTP response. A crash-looping app is authoritatively fixed by redeploying its source via POST /v1/infra/servers/:id/deploy — redeploy is what clears the error state.

The app accepts /reboot in the running or error status (a regular server accepts only running).

Response fields

The verdict is nested under data (unlike a regular server reboot, whose body is the flat { "success": true }).

Field Type Description
success boolean true — the command ran
data.restarted boolean true — the container was restarted; false — it could not be restarted (container missing / image deleted) — redeploy needed
data.healthy boolean true — the container came up and stopped restarting; false — it is crashing again (redeploy needed). This inspects the container, not the app's HTTP response
data.hint string present only when data.healthy: false — how to deploy a fixed version
JSON
{ "success": true, "data": { "restarted": true, "healthy": false, "hint": "Redeploy the fixed source via POST /v1/infra/servers/:id/deploy" } }

Errors

HTTP Code Description
404 GALAXY_APP_NOT_FOUND No app with this id on the host — the container is already gone, or the record does not match the host
409 CONFLICT The app status changed during the operation. Re-read the state and retry
409 GALAXY_APP_REBOOT_USE_AGENT_CONTROLS The app was created by an agent or a bot — manage it from that agent's or bot's controls, not via /reboot
409 GALAXY_APP_BUSY Busy — either another command is running on the host (a neighbouring app's build) or another operation already holds the lock for this same app (a repeat click / a deploy). Retryable: the response carries a Retry-After header plus error.retryable: true and error.retryAfter in the body
422 SERVER_WRONG_STATE The app is not in running/error status (e.g. sleeping). error.availableActions lists what you can do now. In any status outside running/error this refusal additionally starts a host repair — see below
502 GALAXY_HOST_UNREACHABLE The galaxy host is unreachable — its tunnel has dropped. error.hint says what to do. Retry after the host recovers

A refusal to an app also repairs the host

A Galaxy app whose host has lost its connection to the platform hits the same barrier in every operation: both waking and deploying go through the host, and the host is unreachable. So before the 422 SERVER_WRONG_STATE refusal, the platform starts restoring the host connection in the background — the refusal itself still stands, but the next attempt has a chance to go through.

If the repair did start, the error body carries an optional hint object:

Field Type Description
error.hint.reason string Why the refusal, and what was started
error.hint.recovery string Which operation to retry — POST /deploy
error.hint.retryAfterSeconds number Lower bound of the wait, in seconds. A guideline, not a promise of readiness

The hint object may be absent, and that is not an error. It is missing when no repair was started: the host connection is in fact alive, a repair is already under way or finished recently, the host itself is off or asleep, it was woken recently, the guest system on the machine does not boot, the machine is blocked from waking, or automatic recovery is switched off on the platform. Read hint as an optional cue — if it is there, wait the stated time and retry the deploy; if it is not, act on the error code.

Repeat calls do not start a new repair. While a repair is running, and for 10 minutes after it ends — successfully or not — the platform starts no new one, so a repeat refusal arrives without hint. This is the same ten-minute window as the lifetime of a completed record in Repair status. A repair that broke off and stopped reporting is treated as dead after 20 minutes and may be started again.

The retryAfterSeconds value is 300 and stays a lower bound on the wait rather than a promise of readiness: retrying sooner buys nothing, retrying later is fine.

The 502 GALAXY_HOST_UNREACHABLE refusal carries a different hint — four fields instead of three, with their own set of values. They are described under "The error.hint field of GALAXY_HOST_UNREACHABLE" on the Galaxy app page. The shape of the cue is set by the refusal code, so parse it by the code rather than by the page it appeared on.

See also