> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymorfa.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Operations

> List, inspect, wait for, and cancel asynchronous team and project operations.

Some requests start work that finishes later, such as a campaign send or a
production enrollment. Polymorfa tracks that work as an operation. The request
that starts it returns an `operationId`, and the operations routes of the
Platform API report its progress:

```http theme={null}
GET  /platform/operations
GET  /platform/operations/{operationId}
GET  /platform/operations/{operationId}/transitions
POST /platform/operations/{operationId}/cancel
```

Reads require `operations:read`. Cancellation requires `operations:cancel`.

A team API key sees team-owned operations and the operations of every project
in the team. A project token sees only its own project's operations. When a
project token asks for another project, or for an operation outside its
project, the API returns `404`.

Each route also has a project form under
`/platform/projects/{projectId}/operations`, which addresses exactly one
project.

## Operation fields

| Field                      | Meaning                                                                                       |
| -------------------------- | --------------------------------------------------------------------------------------------- |
| `id`                       | Operation ID.                                                                                 |
| `projectId`                | Owning project, or `null` for a team-owned operation.                                         |
| `kind`                     | What the operation does, for example `campaign` or `production_enrollment`.                   |
| `resource`                 | The `type` and `id` of the resource the operation acts on.                                    |
| `status`                   | `pending`, `running`, `action_required`, `cancelling`, `succeeded`, `failed`, or `cancelled`. |
| `sequence`                 | Increases by one on every status transition.                                                  |
| `capabilities.cancellable` | `true` when the operation accepts cancellation right now.                                     |
| `progress`                 | The latest progress code, or `null`.                                                          |
| `error`                    | The failure code when `status` is `failed`, or `null`.                                        |
| `actionRequired`           | What the operation is waiting for when `status` is `action_required`.                         |

`succeeded`, `failed`, and `cancelled` are terminal. A terminal operation
doesn't change again.

## List operations

List results come newest first. Filter by `projectId`, `status`, `kind`,
`resourceType` with `resourceId`, `since`, and exclusive `until`:

```bash theme={null}
curl "https://api.polymorfa.com/platform/operations?status=running&resourceType=campaign&resourceId=$CAMPAIGN_ID" \
  -H "Authorization: Bearer $POLYMORFA_KEY"
```

A page holds at most 100 operations. When more remain, `page.nextCursor` is
set. The cursor carries the filters and the project of the page that issued
it, so send it with `limit` only. Adding a filter, or sending it with a
different project, returns `400`.

## Wait for an operation

Add `wait` to hold the request open until something changes. `wait` accepts
0 to 30 seconds:

```bash theme={null}
curl "https://api.polymorfa.com/platform/operations/$OPERATION_ID?wait=30" \
  -H "Authorization: Bearer $POLYMORFA_KEY"
```

The API responds as soon as one of these is true:

* the operation reaches a terminal status;
* `afterSequence` is set and the operation's `sequence` is greater than it; or
* the wait ends.

The response is always the operation's state at that moment, with status
`200`. Check `status` before you act: an expired wait returns a non-terminal
operation. To follow each transition, send the last `sequence` you saw as
`afterSequence` on the next request.

## Read the transition history

`GET /platform/operations/{operationId}/transitions` lists every status change
in ascending `sequence` order, with the progress, error, and action-required
snapshot recorded at that transition.

## Cancel an operation

Only running or action-required campaign and production-enrollment operations
accept cancellation. Check `capabilities.cancellable` first, then send an
`Idempotency-Key`:

```bash theme={null}
curl -X POST "https://api.polymorfa.com/platform/operations/$OPERATION_ID/cancel" \
  -H "Authorization: Bearer $POLYMORFA_KEY" \
  -H "Idempotency-Key: cancel-$OPERATION_ID"
```

The operation moves to `cancelling` and later reaches `cancelled`, or another
terminal status if it finished first. Wait for it as shown above.

| Response                   | Meaning                                                                                                                                                      |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `200`                      | Cancellation was accepted. The receipt contains the updated operation. A retry with the same key returns the same receipt with `idempotency.replayed: true`. |
| `404`                      | The operation doesn't exist in your team or project.                                                                                                         |
| `409 operation_conflict`   | The operation can't be cancelled now. The body contains the current operation.                                                                               |
| `409 idempotency_conflict` | The key was already used for a different request on this route. Keys are scoped to the route you call.                                                       |

## SDK, CLI, and MCP

* The TypeScript SDK exposes `client.operations.list`, `get`, `listTransitions`,
  `wait`, and `cancel`. See [SDKs](/sdks/overview#operations).
* The CLI provides `polymorfa operation list`, `view`, `wait`, `watch`, and
  `cancel`. `wait` and `watch` exit `0` when the operation succeeds, `1` when it
  fails or is cancelled, and `8` when `--timeout` ends first.
* The [MCP server](/integrations/mcp-server#track-operations) provides
  `operations_list`, `operations_get`, and `operations_wait`. It doesn't cancel
  operations.
