
## Repair tunnel

`POST /v1/infra/servers/:id/repair`

Starts a background repair of the Black Hole tunnel through the cloud provider's serial console. Use it when the virtual machine is in `running` but `blackholeStatus` is stuck in `DISCONNECTED` or `WAITING` — that is, the tunnel agent does not connect. The procedure goes through the serial console (bypassing the firewall) and includes: SSH-key injection → SSH connection → a full reinstall of the agent with the current version → waiting for reconnection. It takes up to 2 minutes; the call itself returns immediately and does not wait for completion. Track the progress via [`GET /repair-status`](./repair-status.md).

> **This is not a way to clear `EXEC_BUSY`.** `/repair` is a full reinstall of the tunnel agent: live processes started via [`/exec`](../deploy/exec.md) get interrupted along with their side effects (for example, an open `COPY` transaction in an external database will hang and hold its locks until that side's timeout). If the server responds with `409 EXEC_BUSY`, release the lock with [`DELETE /v1/infra/servers/:id/lock`](../deploy/lock.md) — the agent and running processes are left untouched. Keep `/repair` for its actual purpose: the tunnel genuinely failing to connect.

## Parameters

| Parameter | In | Type | Required | Description |
|----------|---|-----|:-----:|----------|
| `id` | path | string (UUID) | yes | Server ID |

The request body is empty.

## Examples

### curl — personal key

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

### curl — OAuth application

```bash
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/repair
```

### JavaScript — personal key

```javascript
// Start the repair and poll the status periodically
await fetch(
  `https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/repair`,
  { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY' } }
)

while (true) {
  await new Promise(r => setTimeout(r, 10000))
  const res = await fetch(
    `https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/repair-status`,
    { headers: { 'X-Api-Key': 'YOUR_API_KEY' } }
  )
  const { data } = await res.json()
  console.log(`Step: ${data.step ?? data.status}`)
  if (data.status === 'idle' || data.status === 'completed' || data.status === 'failed') break
}
```

### JavaScript — OAuth application

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

## Response fields

| Field | Type | Description |
|------|-----|----------|
| `success` | boolean | `true` — the repair was successfully started in the background |
| `data.status` | string | Always `"started"` on success |

## Response example

```json
{
  "success": true,
  "data": { "status": "started" }
}
```

## Error response example

409 — repair blocked (for example, the server is marked `preventWake=true`):

```json
{
  "success": false,
  "error": {
    "code": "REPAIR_BLOCKED",
    "message": "Repair blocked: server prevents wake"
  }
}
```

## 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 |
| 404 | `NOT_FOUND` | The server does not exist, was deleted, or belongs to another API key |
| 409 | `REPAIR_BLOCKED` | Repair blocked: `preventWake=true` (billing freeze, administrative block) or the server is in a special state |
| 422 | `VM_MISSING` | The record has no `externalId` — the virtual machine was not created at the provider. Delete the server and create a new one |
| 429 | `RATE_LIMITED` | The platform's overall request limit was exceeded |

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

## Known specifics

- **Why the serial console, not SSH.** When the agent is not connected, SSH through the iptables of a BLACKHOLE server is unavailable. The Bitrix24 Cloud provider's serial console bypasses the firewall at the hypervisor level and lets you inject an SSH key into an already-running virtual machine without rebooting it.
- **Idempotent.** The procedure runs a full cycle (stop the agent → download a fresh binary → clean configuration → start) and is safe for a healthy server — it cannot do harm. A repeated call during an ongoing repair simply returns 409 / the same `started`, breaking nothing.
- **The server mode is preserved.** An OPEN server stays OPEN (iptables is not touched), a BLACKHOLE one stays BLACKHOLE.
- **How to unblock `REPAIR_BLOCKED`.** If the server is marked `preventWake` (billing freeze, an expired trial, an admin block) — first resolve the cause (top up the balance, upgrade the plan), then retry `/repair`.

## See also

- [Repair status](./repair-status.md) — `GET /v1/infra/servers/:id/repair-status` — progress of the current operation.
- [Refresh status](./refresh.md) — check whether `blackholeStatus` recovered after the repair.
- [Get server](/docs/infra/servers/get) — check `blackholeStatus` and `status`.
- [Reboot server](./reboot.md) — an alternative if `repair` did not help.
