# Operations API

> Read an operation's status and result, or follow its persisted events as server-sent events.

- [Get an operation](#get-an-operation): `GET /v1/operations/{operation_id}`
- [Stream operation events](#stream-operation-events): `GET /v1/operations/{operation_id}/events`

## Get an operation

`GET /v1/operations/{operation_id}`

A `stop` reports who asked for it in `stop_reason`: `api`, `auto_stop`, `billing`, `idle_sleep`, `suspension` (the organization was suspended), `abuse` (the sustained-CPU guard stopped a trial machine), or `organization_deleted`. See [Operations and idempotency](/docs/concepts/operations#operation-results).

- **API key:** `Authorization: Bearer vmy_…` with preset `read_only`, `use_existing`, `create_and_use`, `full_access`.
- **Browser session:** the `vmyard_session` cookie.
- **Who:** Any member.

**Parameters**

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `operation_id` | path | `string (uuid)` | Yes |  |
| `X-Organization-ID` | header | `string (uuid)` | No | Required with a browser session. Optional with an API key, which fixes the organization; when sent it must match. |

**Responses**

| Status | Description | Body |
| --- | --- | --- |
| `200` | — | [`OperationDto`](/docs/api/schemas#operationdto) |
| `401` | Not signed in, or the API key is malformed, expired, or revoked (`unauthenticated`, `invalid_api_key`). | [`ProblemDetails`](/docs/api/schemas#problemdetails) |
| `404` | Not found in this organization (`resource_not_found`). | [`ProblemDetails`](/docs/api/schemas#problemdetails) |

```sh title="Request"
curl "$VMYARD_API_URL/v1/operations/$OPERATION_ID" \
  -H "Authorization: Bearer $VMYARD_API_KEY"
```

```json title="Response 200"
{
  "attempt_count": 0,
  "completed_but_unchanged": false,
  "error_code": "string",
  "exec_result": {
    "cancelled": false,
    "exit_code": 0,
    "stderr_base64": "string",
    "stdout_base64": "string",
    "timed_out": false,
    "truncated": false
  },
  "file_ranges": [
    {
      "data_base64": "string",
      "missing": false,
      "offset": 0,
      "path": "notes/todo.txt",
      "size": 0
    }
  ],
  "id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
  "kind": "stop",
  "machine_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
  "starting_soon": {
    "expires_at": "2026-10-12T05:51:01Z",
    "operation_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
    "position": 0,
    "priority": "paid",
    "queued_at": "2026-10-12T05:51:01Z",
    "reason": "no_host_in_region"
  },
  "status": "pending",
  "stop_reason": "idle_sleep"
}
```

## Stream operation events

`GET /v1/operations/{operation_id}/events`

- **API key:** `Authorization: Bearer vmy_…` with preset `read_only`, `use_existing`, `create_and_use`, `full_access`.
- **Browser session:** the `vmyard_session` cookie.
- **Who:** Any member.

**Parameters**

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `operation_id` | path | `string (uuid)` | Yes |  |
| `X-Organization-ID` | header | `string (uuid)` | No | Required with a browser session. Optional with an API key, which fixes the organization; when sent it must match. |
| `Last-Event-ID` | header | `integer \| null` | No | Resume strictly after this persisted monotonic event ID |

**Responses**

| Status | Description | Body |
| --- | --- | --- |
| `200` | Persisted history followed by live events | `text/event-stream` |
| `401` | Not signed in, or the API key is malformed, expired, or revoked (`unauthenticated`, `invalid_api_key`). | [`ProblemDetails`](/docs/api/schemas#problemdetails) |
| `404` | Not found in this organization (`resource_not_found`). | [`ProblemDetails`](/docs/api/schemas#problemdetails) |
| `422` | Invalid request (`invalid_request`); `field_errors` names the fields. | [`ProblemDetails`](/docs/api/schemas#problemdetails) |

```sh title="Request"
curl "$VMYARD_API_URL/v1/operations/$OPERATION_ID/events" \
  -N \
  -H "Authorization: Bearer $VMYARD_API_KEY"
```
