
## Repair status

`GET /v1/infra/servers/:id/repair-status`

Returns the progress of a background tunnel repair started via [`POST /repair`](./repair.md). Used for periodic polling: the client sees the current step (`wake` / `serial_console` / `ssh_install` / `connect` / …), the final status (`running` / `done` / `failed`), and, in case of an error, the `error` field. Completed records are cleared automatically after 10 minutes.

## Parameters

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

## Examples

### curl — personal key

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

### 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/repair-status
```

### JavaScript — personal key

```javascript
// Progress polling loop
while (true) {
  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()

  if (data.status === 'idle') { console.log('Repair not started'); break }
  if (data.status === 'done')  { console.log(`Done, step: ${data.step}`); break }
  if (data.status === 'failed'){ console.error(`Error at step ${data.step}: ${data.error}`); break }

  console.log(`Step: ${data.step}`)
  await new Promise(r => setTimeout(r, 10000))
}
```

### JavaScript — OAuth application

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

## Response fields

| Field | Type | Description |
|------|-----|----------|
| `success` | boolean | Always `true` on success |
| `data.status` | string | `idle` (repair not started or cleared by timeout), `running` (in progress), `done` (succeeded), `failed` (failed) |
| `data.step` | string | Current/last step: `wake`, `serial_console`, `ssh_install`, `connect`, `iptables`, `cleanup`, `done` |
| `data.agentVersion` | string \| null | Version of the installed agent (filled in at the `ssh_install` step) |
| `data.wasSlept` | boolean | Whether the server was `sleeping` when the repair started (then after `done` it returns to `sleeping`) |
| `data.error` | string | Error text, if `status: "failed"` |
| `data.startedAt` | number | Repair start timestamp (Unix milliseconds) |

For `status: "idle"`, only the `status` field is returned; the remaining fields are absent.

## Response example

Repair not started:

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

Repair in progress, agent installation step completed:

```json
{
  "success": true,
  "data": {
    "status": "running",
    "step": "connect",
    "agentVersion": "1.2.3",
    "wasSlept": false,
    "startedAt": 1745312400000
  }
}
```

Repair failed:

```json
{
  "success": true,
  "data": {
    "status": "failed",
    "step": "ssh_install",
    "agentVersion": null,
    "wasSlept": false,
    "error": "SSH connection refused",
    "startedAt": 1745312400000
  }
}
```

## Error response example

404 — server does not exist:

```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 provided |
| 401 | `INVALID_API_KEY` | Invalid or expired API key |
| 404 | `NOT_FOUND` | Server does not exist, was deleted, or belongs to another API key |
| 429 | `RATE_LIMITED` | The platform-wide request limit was exceeded |

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

## Known specifics

- **Step execution order:** `wake` (if the server is `sleeping`) → `serial_console` (inject the SSH key via the Bitrix24 Cloud serial console) → `ssh_install` (SSH connection and agent reinstall: download the binary, write the configuration, start the service) → `connect` (wait for the agent to connect to the Gateway) → `iptables` (restore the firewall for BLACKHOLE) → `cleanup` (return to `sleeping` if the server was sleeping) → `done`.
- **Right after [`POST /repair`](./repair.md) the status is already `running`, not `idle`.** The status is set to `running` synchronously when the repair starts, so the very first `repair-status` poll (even milliseconds later) sees `running`. Previously there was a brief window where a poll could see `idle` and the poll loop exited prematurely — that window is now gone.
- **TTL of completed records — 10 minutes.** After that, a repeat poll returns `idle`. If you need to confirm the result after the TTL, look at `blackholeStatus` in [`GET /v1/infra/servers/:id`](/docs/infra/servers/get) — if it is `CONNECTED`, the repair worked.
- **Concurrent repair is impossible** — there is an in-memory `repairingServers` lock at the service level. A repeat [`POST /repair`](./repair.md) on a server with a repair already in progress is handled correctly: the second call does not start a new procedure.

## See also

- [Repair the tunnel](./repair.md) — `POST /v1/infra/servers/:id/repair` — start a repair.
- [Get the server](/docs/infra/servers/get) — check the resulting `blackholeStatus`.
- [Refresh status](./refresh.md) — force a provider poll after the repair.
