
## Refresh status

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

Forces a poll of the cloud provider, retrieves the current status and IP of the server, and updates the record in the database if anything changed. Useful when the status in the platform diverges from reality — for example, after provider maintenance, a hang in `provisioning`, or a manual stop of the virtual machine through the provider's console.

## 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/refresh
```

### 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/refresh
```

### JavaScript — personal key

```javascript
const res = await fetch(
  `https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/refresh`,
  { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY' } }
)
const { data: status } = await res.json()
console.log(`Current status: ${status}`)
```

### JavaScript — OAuth application

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

## Response fields

| Field | Type | Description |
|------|-----|----------|
| `success` | boolean | Always `true` on success |
| `data` | string | Current status in lowercase: `provisioning`, `running`, `sleeping`, `error` |
| `currentState` | object | State snapshot — the same fields as in `error.currentState` for 422 SERVER_WRONG_STATE: `status`, `blackholeStatus`, `hasExternalId`, `lastSeenAt`. `blackholeStatus` is additionally checked against a gateway snapshot for this response only |
| `availableActions` | string[] | A subset of `['wake','start','reboot','sleep-now','repair','delete']` — actions that make sense to call in the current state |

> The `data` field is a status string kept for backward compatibility. The state snapshot and the list of actions are returned in the separate `currentState` and `availableActions` fields. For a full server snapshot (IP, policy, etc.), call [`GET /v1/infra/servers/:id`](/docs/infra/servers/get).

## Response example

```json
{
  "success": true,
  "data": "running",
  "currentState": {
    "status": "running",
    "blackholeStatus": "CONNECTED",
    "hasExternalId": true,
    "lastSeenAt": null
  },
  "availableActions": ["reboot", "sleep-now", "delete"]
}
```

## Error response example

404 — the server does not exist:

```json
{
  "success": false,
  "error": {
    "code": "SERVER_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` | The key is not recognized — no such key exists on the platform |
| 403 | `INFRA_FORBIDDEN_FOR_COWORK_KEY` | The call was made with a Cowork key — such a key works with data only and cannot perform write operations. To issue a key that can, see [Project key for deploy](/docs/cowork/deploy-key) |
| 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](/docs/infra/servers/list) |
| 403 | `WRONG_KEY` | A live server in your Bitrix24 account is proven to belong to the key owner or one of its live applications, but another key manages it. This diagnostic refusal does not authorize a status refresh. Rebind the server through a human session, then retry with the new managing key |
| 404 | `SERVER_NOT_FOUND` | The server does not exist, was deleted, is in another Bitrix24 account, or no relationship to the key owner or its live application is proven |
| 429 | `RATE_LIMITED` | The platform's overall request limit was exceeded |
| 502 | `PROVIDER_ERROR` | The cloud provider returned an error while polling the virtual machine |

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

## Known specifics

- **It may overwrite the status in the database.** If the provider reports a status that differs from the current one in the database (for example, `stopped` at the provider while `running` in the database), the record is updated: `running → sleeping`, `sleeping → running`, an IP appears, and so on. This is the main way an `error` record "self-heals".
- **Tunnel reconciliation is not a repair.** After the provider poll, a running BLACKHOLE server stored as `CONNECTED` is checked against the gateway. If a successful non-empty snapshot does not contain its tunnel, `currentState.blackholeStatus` becomes `DISCONNECTED` and `availableActions` offers `repair`. This part of the response is not persisted and does not call `repairServer`; an unavailable or empty snapshot preserves the stored value.
- **Comparison gotcha:** `data === 'running'`, not `data.status === 'running'` — the `data` field is intentionally kept as a string for backward compatibility. The state snapshot and the list of available actions are returned in the separate `currentState` and `availableActions` fields. This differs from [`GET /v1/infra/servers/:id`](/docs/infra/servers/get), where all the information is inside `data`.
- **Idempotent and safe.** Frequent calls do not create records, do not start the virtual machine, and do not finalize billing. Suitable for ad-hoc reconciliation. For readiness polling loops, [`GET /v1/infra/servers/:id`](/docs/infra/servers/get) is a better fit — it returns the full object.
- **Does not reset the background monitor timer.** If the provider returns the same status and IP that are already in the database, `/refresh` does not update `updatedAt` — so as not to reset the timer of the internal monitor that counts down `provisioning` timeouts (10 minutes).

## See also

- [Get a server](/docs/infra/servers/get)
- [Repair tunnel](./repair.md)
- [Start the server](./start.md)
