## Recent server operations

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

Returns recent deploy operations on a server started by the current API key, newest first. This is the recovery channel when the [`POST /deploy`](./deploy.md) response is lost before the client receives an `operationId` — notably when a connection drops during a Galaxy application build.

The endpoint only reads the shared outcome record: it does not wake the server, repair the tunnel, or release a mutex. Server access matches deploy access, while rows are additionally filtered by the exact API key that started them. An application-linked key therefore sees only its own runs, and the shared galaxy host id does not expose its applications' runs. An owner can reconcile its operations after the server is soft-deleted.

## Parameters

| Parameter | In | Type | Required | Description |
|-----------|----|------|:--------:|-------------|
| `id` | path | string | yes | Server or Galaxy application ID |
| `limit` | query | integer | no | Number of rows: 5 by default, maximum 20. Zero is clamped to 1 and an integer above 20 to 20; a negative value, a fraction, or a non-number returns `400 INVALID_LIMIT` |

## Example

```bash
curl -H "X-Api-Key: YOUR_API_KEY" \
  'https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/operations?limit=5'
```

```json
{
  "success": true,
  "data": {
    "operations": [
      {
        "operationId": "clz9k2m4x0001qw8h3f7d2n5p",
        "serverId": "8f14e45f-ceea-467a-9c8d-2f1c5a6b7e30",
        "status": "running",
        "outcomeAvailable": true,
        "step": "build",
        "startedAt": "2026-08-26T09:14:22.117Z",
        "finishedAt": null,
        "error": null
      }
    ]
  }
}
```

## Operation fields

| Field | Type | Description |
|-------|------|-------------|
| `operationId` | string | Identifier for [`GET /v1/infra/operations/:operationId`](./operation-status.md) |
| `serverId` | string | Server or Galaxy application ID |
| `outcomeAvailable` | boolean | Whether the operation outcome is still stored |
| `status` | string | `running`, `succeeded`, `failed`, or `unknown`; absent for an expired terminal outcome |
| `step` | string \| null | Last observed step; absent for an expired terminal outcome |
| `startedAt` | string | Start time, ISO 8601 |
| `finishedAt` | string \| null | Finish time; absent for an expired terminal outcome |
| `error` | object \| null | `{ code, message }` for `failed` only; absent for an expired terminal outcome |

A terminal outcome is retained for 7 days. The row then remains in the list for a while with `outcomeAvailable: false`, but its status, step, and error are no longer exposed. `unknown` is a stable terminal answer when the platform cannot prove the remote outcome, for example after `GATEWAY_UNREACHABLE`; an expired operation still marked `running` is also shown as `unknown`.

## Safe recovery after a dropped connection

1. Do not redeploy blind. Find this key's recent operation in the list.
2. While it is `running`, wait and poll the list or the addressable endpoint every few seconds.
3. Use a confirmed `succeeded` or `failed` outcome. For `unknown` or no matching record, reconcile [`GET /v1/infra/servers/:id`](/docs/infra/servers/get) and the [logs](./logs.md).
4. If a later request confirms `EXEC_BUSY`, first verify that the list has no `running` operation, then account for the server kind. For `STANDALONE`, you may call `POST /v1/infra/servers/:id/unstick` and repeat the read-only checks. A `GALAXY_APP` uses its shared host's exec channel: tenant `unstick` is unsupported; wait 30–60 seconds and contact support if `EXEC_BUSY` persists. After either recovery, reconcile the list, state, and logs again before redeploying.

A standalone deploy with a transport reason of `GATEWAY_UNREACHABLE`, `DEPLOY_CONNECTION_TERMINATED`, `DEPLOY_TIMEOUT`, or `DEPLOY_TUNNEL_STALE`, and post-drop Galaxy `GALAXY_DEPLOY_INTERRUPTED` or `GALAXY_HOST_UNREACHABLE` responses, carry this read-first sequence in `error.hint`. A Galaxy response in this state carries `error.retryable: false`: the dropped connection by itself proves neither success nor failure. The slot, container, and `/data` are preserved while the outcome is unknown — do not delete or recreate the app.

## Errors

| HTTP | Code | Description |
|------|------|-------------|
| 400 | `INVALID_LIMIT` | `limit` is negative, fractional, non-numeric, or exceeds the safe-integer range |
| 401 | `MISSING_API_KEY`, `INVALID_API_KEY` | The key is absent or invalid |
| 404 | `SERVER_NOT_FOUND` | The server is not available to this key |
| 429 | `RATE_LIMITED` | The 60 requests per minute per-key limit was exceeded |

## See also

- [Outcome by identifier](./operation-status.md)
- [Deploy an application](./deploy.md)
- [Application logs](./logs.md)
