# Operations

> Long-running operations and their event streams.

Long-running operations and their event streams.

| Operation | Method and path |
| --- | --- |
| [Operations in a project](#operations-in-a-project) | `GET /v1/projects/{project}/operations` |
| [Get an operation](#get-an-operation) | `GET /v1/operations/{operation_id}` |
| [Stream an operation's events (Server-Sent Events)](#stream-an-operations-events-server-sent-events) | `GET /v1/operations/{operation_id}/events` |
| [Request cancellation](#request-cancellation) | `POST /v1/operations/{operation_id}/cancel` |

## Operations in a project

```http
GET /v1/projects/{project}/operations
```

- **Operation:** `listProjectOperations`
- **Scopes:** `projects:read`
- **Paginated:** `?limit=` and `?cursor=`

**Parameters**

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `project` * | path | string | Project id (`prj_…`) or slug (resolved in the `Guv-Workspace` workspace, or the caller's default). |
| `status` | query | [OperationStatus](/docs/api/objects/operation-status/) |  |
| `kind` | query | string |  |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `200` OK | A page of Operation objects. | [OperationList](/docs/api/objects/operation-list/) |

**Errors:** `400`, `401`, `403`, `404`, `429`, `500`, as [problem+json](/errors/) with a stable `code`.

**Example**

```bash
curl https://api.guv.dev/v1/projects/shopfront/operations \
  -H "Authorization: Bearer $GUV_TOKEN"
```

**Example response**

```json
{
  "data": [
    {
      "id": "op_01jbx2m9k7q4r8t5v6w3y0z1op",
      "kind": "deployment.create",
      "status": "running",
      "summary": "Deploying web to production",
      "workspace_id": "ws_01jbx2m9k7q4r8t5v6w3y0z1ws",
      "project_id": "prj_01jbx2m9k7q4r8t5v6w3y0z1pr",
      "environment_id": "env_01jbx2m9k7q4r8t5v6w3y0z1en",
      "resource": {
        "type": "deployment",
        "id": "dep_01jbx2m9k7q4r8t5v6w3y0z1dp",
        "url": "/v1/deployments/dep_01jbx2m9k7q4r8t5v6w3y0z1dp"
      },
      "progress": {
        "current_step": "build",
        "completed_steps": 1,
        "total_steps": 6,
        "percent": 20
      },
      "steps": [
        {
          "name": "resolve",
          "title": "Reading your settings",
          "status": "succeeded",
          "attempt": 1,
          "started_at": "2026-10-23T14:02:00Z",
          "finished_at": "2026-10-23T14:02:01Z"
        },
        {
          "name": "build",
          "title": "Building your app",
          "status": "running",
          "attempt": 1,
          "started_at": "2026-10-23T14:02:01Z",
          "finished_at": null
        }
      ],
      "created_by": {
        "type": "user",
        "id": "usr_01jbx2m9k7q4r8t5v6w3y0z1us",
        "display": "Stewart Webb"
      },
      "created_at": "2026-10-23T14:02:00Z",
      "links": {
        "self": "/v1/operations/op_01jbx2m9k7q4r8t5v6w3y0z1op",
        "events": "/v1/operations/op_01jbx2m9k7q4r8t5v6w3y0z1op/events",
        "resource": "/v1/deployments/dep_01jbx2m9k7q4r8t5v6w3y0z1dp"
      }
    }
  ],
  "next_cursor": "string",
  "has_more": false
}
```

## Get an operation

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

- **Operation:** `getOperation`
- **Scopes:** any signed-in principal

**Parameters**

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `operation_id` * | path | string |  |
| `wait` | query | integer | Long-poll up to this many seconds for a status change. |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `200` OK | OK. | [Operation](/docs/api/objects/operation/) |

**Errors:** `400`, `401`, `403`, `404`, `429`, `500`, as [problem+json](/errors/) with a stable `code`.

**Example**

```bash
curl https://api.guv.dev/v1/operations/ope_01jbx2m9k7q4r8t5v6w3y0z1pr \
  -H "Authorization: Bearer $GUV_TOKEN"
```

**Example response**

```json
{
  "id": "op_01jbx2m9k7q4r8t5v6w3y0z1op",
  "kind": "deployment.create",
  "status": "running",
  "summary": "Deploying web to production",
  "workspace_id": "ws_01jbx2m9k7q4r8t5v6w3y0z1ws",
  "project_id": "prj_01jbx2m9k7q4r8t5v6w3y0z1pr",
  "environment_id": "env_01jbx2m9k7q4r8t5v6w3y0z1en",
  "resource": {
    "type": "deployment",
    "id": "dep_01jbx2m9k7q4r8t5v6w3y0z1dp",
    "url": "/v1/deployments/dep_01jbx2m9k7q4r8t5v6w3y0z1dp"
  },
  "progress": {
    "current_step": "build",
    "completed_steps": 1,
    "total_steps": 6,
    "percent": 20
  },
  "steps": [
    {
      "name": "resolve",
      "title": "Reading your settings",
      "status": "succeeded",
      "attempt": 1,
      "started_at": "2026-10-23T14:02:00Z",
      "finished_at": "2026-10-23T14:02:01Z"
    },
    {
      "name": "build",
      "title": "Building your app",
      "status": "running",
      "attempt": 1,
      "started_at": "2026-10-23T14:02:01Z",
      "finished_at": null
    }
  ],
  "created_by": {
    "type": "user",
    "id": "usr_01jbx2m9k7q4r8t5v6w3y0z1us",
    "display": "Stewart Webb"
  },
  "created_at": "2026-10-23T14:02:00Z",
  "links": {
    "self": "/v1/operations/op_01jbx2m9k7q4r8t5v6w3y0z1op",
    "events": "/v1/operations/op_01jbx2m9k7q4r8t5v6w3y0z1op/events",
    "resource": "/v1/deployments/dep_01jbx2m9k7q4r8t5v6w3y0z1dp"
  }
}
```

## Stream an operation's events (Server-Sent Events)

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

Replays past events, then follows live. Resume with `Last-Event-ID`. Ends after `operation.finished`.

- **Operation:** `streamOperationEvents`
- **Scopes:** any signed-in principal

**Parameters**

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `operation_id` * | path | string |  |
| `Last-Event-ID` | header | string |  |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `200` OK | Server-Sent Events stream. Each event's `data` is a JSON OperationEvent. | string |

**Errors:** `400`, `401`, `403`, `404`, `429`, `500`, as [problem+json](/errors/) with a stable `code`.

**Example**

```bash
curl https://api.guv.dev/v1/operations/ope_01jbx2m9k7q4r8t5v6w3y0z1pr/events \
  -H "Authorization: Bearer $GUV_TOKEN"
```

**Example response**

```json
"string"
```

## Request cancellation

```http
POST /v1/operations/{operation_id}/cancel
```

- **Operation:** `cancelOperation`
- **Scopes:** any signed-in principal
- **Idempotency-Key:** required

**Parameters**

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `operation_id` * | path | string |  |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `202` Accepted | Accepted. The work continues in the background; follow the operation. | [Operation](/docs/api/objects/operation/) |

**Errors:** `400`, `401`, `403`, `404`, `409`, `422`, `429`, `500`, as [problem+json](/errors/) with a stable `code`.

**Example**

```bash
curl -X POST https://api.guv.dev/v1/operations/ope_01jbx2m9k7q4r8t5v6w3y0z1pr/cancel \
  -H "Authorization: Bearer $GUV_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)"
```

**Example response**

```json
{
  "id": "op_01jbx2m9k7q4r8t5v6w3y0z1op",
  "kind": "deployment.create",
  "status": "running",
  "summary": "Deploying web to production",
  "workspace_id": "ws_01jbx2m9k7q4r8t5v6w3y0z1ws",
  "project_id": "prj_01jbx2m9k7q4r8t5v6w3y0z1pr",
  "environment_id": "env_01jbx2m9k7q4r8t5v6w3y0z1en",
  "resource": {
    "type": "deployment",
    "id": "dep_01jbx2m9k7q4r8t5v6w3y0z1dp",
    "url": "/v1/deployments/dep_01jbx2m9k7q4r8t5v6w3y0z1dp"
  },
  "progress": {
    "current_step": "build",
    "completed_steps": 1,
    "total_steps": 6,
    "percent": 20
  },
  "steps": [
    {
      "name": "resolve",
      "title": "Reading your settings",
      "status": "succeeded",
      "attempt": 1,
      "started_at": "2026-10-23T14:02:00Z",
      "finished_at": "2026-10-23T14:02:01Z"
    },
    {
      "name": "build",
      "title": "Building your app",
      "status": "running",
      "attempt": 1,
      "started_at": "2026-10-23T14:02:01Z",
      "finished_at": null
    }
  ],
  "created_by": {
    "type": "user",
    "id": "usr_01jbx2m9k7q4r8t5v6w3y0z1us",
    "display": "Stewart Webb"
  },
  "created_at": "2026-10-23T14:02:00Z",
  "links": {
    "self": "/v1/operations/op_01jbx2m9k7q4r8t5v6w3y0z1op",
    "events": "/v1/operations/op_01jbx2m9k7q4r8t5v6w3y0z1op/events",
    "resource": "/v1/deployments/dep_01jbx2m9k7q4r8t5v6w3y0z1dp"
  }
}
```
