# Cycles

A **cycle** is a multi-task unit of work with its own conversation. These operations create cycles, dispatch them, add tasks to them, and read their events, timeline, usage and artifacts.

Generated from contract version `1.0.0` — the same document [`/v1/api/openapi.json`](/api/openapi/) serves.

## Prerequisites

- An API key in `x-api-key`, or a browser session cookie
- `X-Organization-Id` naming the workspace to act in, unless the session already has an active one
- The base URL for your deployment, `https://server.hlix.ai` by default

## Operations

| Method | Path | Operation |
| --- | --- | --- |
| `GET` | `/v1/api/cycles` | [List cycles](#list-cycles) |
| `POST` | `/v1/api/cycles` | [Propose a cycle](#propose-a-cycle) |
| `DELETE` | `/v1/api/cycles/{id}` | [Delete a draft or failed cycle](#delete-a-draft-or-failed-cycle) |
| `GET` | `/v1/api/cycles/{id}` | [Get one cycle with its tasks](#get-one-cycle-with-its-tasks) |
| `PATCH` | `/v1/api/cycles/{id}` | [Update a cycle's title, description or target branch](#update-a-cycles-title-description-or-target-branch) |
| `GET` | `/v1/api/cycles/{id}/artifacts` | [List a cycle's stored artifacts](#list-a-cycles-stored-artifacts) |
| `GET` | `/v1/api/cycles/{id}/artifacts/{filename}` | [Get a signed download URL for one cycle artifact](#get-a-signed-download-url-for-one-cycle-artifact) |
| `GET` | `/v1/api/cycles/{id}/diagnostics` | [Read why the cycle's run failed or is parked](#read-why-the-cycles-run-failed-or-is-parked) |
| `GET` | `/v1/api/cycles/{id}/events` | [List a cycle's own events](#list-a-cycles-own-events) |
| `POST` | `/v1/api/cycles/{id}/execute` | [Run a cycle's lifecycle](#run-a-cycles-lifecycle) |
| `GET` | `/v1/api/cycles/{id}/messages` | [Read a cycle's conversation](#read-a-cycles-conversation) |
| `POST` | `/v1/api/cycles/{id}/messages` | [Send a message to a cycle's conversation](#send-a-message-to-a-cycles-conversation) |
| `POST` | `/v1/api/cycles/{id}/messages/stream` | [Send a message and stream the reply (SSE)](#send-a-message-and-stream-the-reply-sse) |
| `GET` | `/v1/api/cycles/{id}/pending-requests` | [List a cycle's pending requests](#list-a-cycles-pending-requests) |
| `POST` | `/v1/api/cycles/{id}/stop` | [Stop a running cycle](#stop-a-running-cycle) |
| `GET` | `/v1/api/cycles/{id}/stream` | [Stream a cycle's lifecycle events (SSE)](#stream-a-cycles-lifecycle-events-sse) |
| `POST` | `/v1/api/cycles/{id}/tasks` | [Add a task to a cycle](#add-a-task-to-a-cycle) |
| `DELETE` | `/v1/api/cycles/{id}/tasks/{taskId}` | [Remove a task from a cycle](#remove-a-task-from-a-cycle) |
| `PATCH` | `/v1/api/cycles/{id}/tasks/{taskId}` | [Update a task inside a cycle](#update-a-task-inside-a-cycle) |
| `GET` | `/v1/api/cycles/{id}/timeline` | [List a cycle's events plus its tasks'](#list-a-cycles-events-plus-its-tasks) |
| `GET` | `/v1/api/cycles/{id}/transcript` | [Get post-hoc step transcripts for a cycle's planner + coder turns](#get-post-hoc-step-transcripts-for-a-cycles-planner--coder-turns) |
| `GET` | `/v1/api/cycles/{id}/usage` | [Get the cycle's cost and token roll-up](#get-the-cycles-cost-and-token-roll-up) |

## List cycles

`GET /v1/api/cycles` · operation ID `listCycles`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `projectId` | query | no | string | Only this project's cycles. |
| `orderBy` | query | no | string | `createdAt` (default, newest first) or `priority` (Triage's urgency tier first, ties keep createdAt order). |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | CycleSummary[] | The matching cycles, newest first (or priority-first when `orderBy=priority`), each with a Linear deep link when it came from Linear. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |

## Propose a cycle

`POST /v1/api/cycles` · operation ID `proposeCycle`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `CreateCycle` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `description` | string | **yes** | min length 1, max length 10000 |
| `projectId` | string (uuid) | **yes** |  |
| `targetBranch` | string | no |  |
| `title` | string | **yes** | min length 1, max length 200 |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `202` | CycleProposed | The proposal was recorded. `adopted` says whether the orchestrator took it straight away; if not, it is adopted on the next planning pass. |
| `400` | ValidationError \| ApiError | The JSON body failed schema validation (`ValidationError`), or the request named no active organization (`ApiError`). |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such project in this workspace — or a client collaborator it was never shared with (existence is deliberately not revealed). |

## Delete a draft or failed cycle

`DELETE /v1/api/cycles/{id}` · operation ID `deleteCycle`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | MessageAck | The cycle was deleted. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such cycle in this workspace — or a client collaborator it was never shared with (existence is deliberately not revealed). |
| `409` | ApiError | Only a cycle in `draft` or `failed` status can be deleted. |

## Get one cycle with its tasks

`GET /v1/api/cycles/{id}` · operation ID `getCycle`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | CycleDetail | The cycle, its tasks with dependencies, and the live preview URL when one is deployed. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such cycle in this workspace — or a client collaborator it was never shared with (existence is deliberately not revealed). |

## Update a cycle's title, description or target branch

`PATCH /v1/api/cycles/{id}` · operation ID `updateCycle`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `UpdateCycle` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `description` | string | no | min length 1, max length 10000 |
| `targetBranch` | string | no |  |
| `title` | string | no | min length 1, max length 200 |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | Cycle | The updated cycle. |
| `400` | ValidationError \| ApiError | The JSON body failed schema validation (`ValidationError`), or the request named no active organization (`ApiError`). |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such cycle in this workspace — or a client collaborator it was never shared with (existence is deliberately not revealed). |

## List a cycle's stored artifacts

`GET /v1/api/cycles/{id}/artifacts` · operation ID `listCycleArtifacts`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | StoredArtifact[] | The stored objects. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such cycle in this workspace — or a client collaborator it was never shared with (existence is deliberately not revealed). |

## Get a signed download URL for one cycle artifact

`GET /v1/api/cycles/{id}/artifacts/{filename}` · operation ID `getCycleArtifactUrl`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `filename` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | SignedArtifactUrl | A short-lived signed URL. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such cycle, or no such artifact under it. |

## Read why the cycle's run failed or is parked

`GET /v1/api/cycles/{id}/diagnostics` · operation ID `getCycleRunDiagnostics`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | RunDiagnostics | The run's own account of itself: the failure it recorded, its un-collapsed engine status, and every step it is parked on with the labels a resume may address. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such cycle, or it has no run to diagnose. |

## List a cycle's own events

`GET /v1/api/cycles/{id}/events` · operation ID `listCycleEvents`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | ActivityEvent[] | The cycle's own activity rows, newest first. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |

## Run a cycle's lifecycle

`POST /v1/api/cycles/{id}/execute` · operation ID `executeCycle`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `mode` | query | no | string | `sandbox` (default) or `desktop`. |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | CycleExecutionStarted | The lifecycle run was started. It proceeds asynchronously — watch it on the stream or timeline endpoints. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such cycle, or its project is gone. |
| `409` | ApiError | The cycle's status does not allow execution. |
| `502` | ApiError | The dispatch could not be queued — the cycle was NOT started. Phase 2.9 commits the state change and the outbox row together, so nothing is half-written; retry is safe. |

## Read a cycle's conversation

`GET /v1/api/cycles/{id}/messages` · operation ID `listCycleMessages`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `agentId` | query | no | string | Read this agent's thread instead of the cycle's. |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | WireMessage[] | The transcript, oldest first. An unknown cycle or an unresolvable thread reads as an EMPTY list, not a 404. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | The cycle's project is out of reach — a client collaborator it was never shared with (existence is deliberately not revealed). |

## Send a message to a cycle's conversation

`POST /v1/api/cycles/{id}/messages` · operation ID `sendCycleMessage`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `CycleMessage` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `agentId` | string (uuid) | null | no |  |
| `content` | string | **yes** | min length 1 |
| `messageId` | string (uuid) | no |  |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | CycleTurn | The turn was stored, and the transcript as it stands afterwards. A view-only client collaborator may store a turn but never drives the agent. |
| `400` | ValidationError \| ApiError | The JSON body failed schema validation (`ValidationError`), or the request named no active organization (`ApiError`). |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such cycle in this workspace — or a client collaborator it was never shared with (existence is deliberately not revealed). |
| `409` | ApiError | The supplied `messageId` is already in use — either on another conversation, or on this one with different content. |

## Send a message and stream the reply (SSE)

`POST /v1/api/cycles/{id}/messages/stream` · operation ID `streamCycleMessage`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `CycleMessage` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `agentId` | string (uuid) | null | no |  |
| `content` | string | **yes** | min length 1 |
| `messageId` | string (uuid) | no |  |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | string | `user_message` (the echoed turn), then `token` chunks of raw text, `tool_start` / `tool_end` around each tool call, and finally `complete` or `error`. |
| `400` | ValidationError \| ApiError | The JSON body failed schema validation (`ValidationError`), or the request named no active organization (`ApiError`). |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such cycle in this workspace — or a client collaborator it was never shared with (existence is deliberately not revealed). |
| `409` | ApiError | The supplied `messageId` is already in use — either on another conversation, or on this one with different content. |

## List a cycle's pending requests

`GET /v1/api/cycles/{id}/pending-requests` · operation ID `listCyclePendingRequests`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | PendingRequest[] | This cycle's requests. Resolved ones are included — `status` says which are still open. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |

## Stop a running cycle

`POST /v1/api/cycles/{id}/stop` · operation ID `stopCycle`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | CycleStopped | The run was cancelled and the cycle moved to `canceled` through the governed transition. Cancellation is checked BETWEEN steps: the step in flight completes and nothing after it starts — a coding agent already running in the sandbox is NOT interrupted. `orchestratorNotified` reports whether a parked project run was told; `false` is normal for a cycle executed on its own. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such cycle in this workspace — or a client collaborator it was never shared with (existence is deliberately not revealed). |
| `409` | ApiError | There is no running or suspended run to stop; the body names the status that was actually found. |

## Stream a cycle's lifecycle events (SSE)

`GET /v1/api/cycles/{id}/stream` · operation ID `streamCycle`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | string | One frame per new timeline event, a `keepalive` roughly every 30s, a `done` event on a terminal status, and a hard stop after ~20 minutes. A cycle that does not exist is reported as a frame on an open 200 stream, not as a 404. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | The cycle's project is out of reach — a client collaborator it was never shared with (existence is deliberately not revealed). |

## Add a task to a cycle

`POST /v1/api/cycles/{id}/tasks` · operation ID `addCycleTask`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `CreateCycleTask` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `dependsOn` | string (uuid)[] | no |  |
| `description` | string | **yes** | min length 1, max length 5000 |
| `title` | string | **yes** | min length 1, max length 200 |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `201` | Task | The created task. |
| `400` | ValidationError \| ApiError | The JSON body failed schema validation (`ValidationError`), or the request named no active organization (`ApiError`). |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such cycle in this workspace — or a client collaborator it was never shared with (existence is deliberately not revealed). |

## Remove a task from a cycle

`DELETE /v1/api/cycles/{id}/tasks/{taskId}` · operation ID `deleteCycleTask`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `taskId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | MessageAck | The task was deleted. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such task under this cycle. |
| `409` | ApiError | Only a task in `queued` or `blocked` status can be deleted. |

## Update a task inside a cycle

`PATCH /v1/api/cycles/{id}/tasks/{taskId}` · operation ID `updateCycleTask`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `taskId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `UpdateCycleTask` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `description` | string | no | min length 1, max length 5000 |
| `sortOrder` | integer | no | min -9007199254740991, max 9007199254740991 |
| `title` | string | no | min length 1, max length 200 |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | Task | The updated task. |
| `400` | ValidationError \| ApiError | The JSON body failed schema validation (`ValidationError`), or the request named no active organization (`ApiError`). |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such task under this cycle. |

## List a cycle's events plus its tasks'

`GET /v1/api/cycles/{id}/timeline` · operation ID `getCycleTimeline`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | ActivityEvent[] | The cycle's activity rows merged with its tasks', oldest first. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |

## Get post-hoc step transcripts for a cycle's planner + coder turns

`GET /v1/api/cycles/{id}/transcript` · operation ID `getCycleTranscript`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | CycleTranscript | Every completed agent turn for this cycle — its planner turn and each task's native hlix coder turn — oldest first. A run that used an external ACP coder, or the reviewer's turn, has no entry (see the route's docblock for why). |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such cycle in this workspace. |

## Get the cycle's cost and token roll-up

`GET /v1/api/cycles/{id}/usage` · operation ID `getCycleUsage`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | AgentUsageRollup | Totals plus two breakdowns of the same runs: by execution lane (`byRole`) and by worker persona (`byPersona`). A lane that never ran is ABSENT rather than reported as a zero row; `byPersona` instead keeps a `null` bucket for runs whose dispatch knew no persona, so both breakdowns sum to `totals`. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such cycle in this workspace — or a client collaborator it was never shared with (existence is deliberately not revealed). |

## If a request fails

These apply to every operation on this page.

- `400` — the body failed schema validation, or the request named no active organization. A `ValidationError` body carries the failing fields; an `ApiError` body carries only `error`.
- `401` — no valid session or API key.
- `403` — authenticated, but not a member of the named organization, or a client collaborator without the required access.
- `404` — no such resource **in this workspace**. Absent and not-visible are deliberately the same answer; do not infer cross-tenant existence from it.
- `409` — the expected revision or state is stale, or another operation currently owns the transition.
- `500` — the operation failed server-side. Retry only where an idempotency key makes that safe.

## Next steps

[API reference](/api/reference/)
  [API & OpenAPI](/api/openapi/)
  [TypeScript SDK](/sdk/typescript/)
  [CLI reference](/reference/cli/)