> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.cloudraker.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.cloudraker.com/_mcp/server.

# Agents

The [capability verbs](/paperwork/capabilities/extract) do one thing per call. An **agent** does a *sequence* of things. Example: read the intake pack, extract the fields, fill the form, wait for a human to countersign, file the result. An agent is a saved, reviewed automation. It holds a list of steps, the [saved configs](/paperwork/capabilities/actions) it may use, and the points where a person must sign off.

`GET /v1/agents` lists the agents your organization can run. `POST /v1/agent-runs` starts one on a set of files. After that, you work with one object: the **agent run** (`agr_…`). Poll it or subscribe to it.

An **agent** in the API is a **playbook** in the CloudRaker app. They are the same object with the same runs. What you build and review under [Playbooks](/workspace/playbooks/overview) is what `GET /v1/agents` returns. A run started over the API also shows up there.

## An agent

```json
{
  "object": "agent",
  "id": "01JQ8ZKMRT4V6WXYZ0ABCDEFGH",
  "name": "Client intake",
  "description": "Reads an intake pack, files the data, and collects a signature.",
  "version": 7,
  "tasks": [
    { "id": "task-1", "title": "Extract the intake fields", "executor": "agent", "dependsOn": [] },
    { "id": "task-2", "title": "Countersign the engagement letter", "executor": "human", "dependsOn": ["task-1"] }
  ],
  "actions": [
    { "name": "Extract structured data", "approval": "output" },
    { "name": "Sign document", "approval": "before" }
  ],
  "updatedAt": "2026-07-28T14:02:11.884Z"
}
```

| Field       | What it tells you                                                                                                                                                       |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `tasks[]`   | The **step ledger**: the shape of the work. `executor: "human"` marks the steps that come back to you. `dependsOn` lists the steps that must close before a step opens. |
| `actions[]` | What the agent may do, and the `approval` gate on each.                                                                                                                 |
| `version`   | The revision a new run will snapshot. Edits to the agent do not change runs already in flight.                                                                          |

The API lists only **active** agents. Ids are opaque strings. Do not parse them.

## Who does each step

Every step has an `executor`. That field sets the full division of labour:

* **`agent`** — the step runs by itself. You do nothing.
* **`human`** — the step waits. Complete it with [`POST /v1/agent-runs/:id/tasks/:taskId/complete`](/paperwork/developers/agent-runs#complete-a-human-step). Attach a note and files if you need to.

On a run, each step also carries a `status`: `pending` (blocked on its `dependsOn`), `ready` (open), `in_progress`, `completed`, or `skipped`. A skipped step satisfies dependencies the same way a completed step does.

## Sign-off gates

An action's `approval` says where a human must agree before the agent proceeds:

| `approval` | Gate                                                                                                              |
| ---------- | ----------------------------------------------------------------------------------------------------------------- |
| `auto`     | No sign-off. The agent runs the action.                                                                           |
| `before`   | Approve the **proposed inputs** before the action runs. The approval carries the `params` the agent wants to use. |
| `output`   | Approve the **result** before the agent uses it.                                                                  |
| `both`     | Both gates.                                                                                                       |

Every outstanding sign-off appears in `approvals[]` on the run. Each entry carries a `kind` of `before` or `output`, the action's name, and the files it touches. A `before` gate also carries the proposed `params`. Answer it with [`POST /v1/agent-runs/:id/approvals/:approvalId`](/paperwork/developers/agent-runs#decide-an-approval). When you approve, you can replace those `params` or `files` first. When you reject, you must include a `note`.

## Run statuses

| Status       | Meaning                                                                                              |
| ------------ | ---------------------------------------------------------------------------------------------------- |
| `queued`     | Accepted. The API is still preparing its files. **Reading the run picks it up** once they are ready. |
| `processing` | The agent is working.                                                                                |
| `waiting`    | Blocked on a person. See `waiting`, `approvals[]`, and the `ready` human steps in `tasks[]`.         |
| `paused`     | Stopped short and resumable. **Not a failure.** `paused.reason` is `model_error` or `system_error`.  |
| `completed`  | Finished. The run carries `result` and `output`.                                                     |
| `failed`     | Finished without a result. `error.code` and `error.message` say why.                                 |
| `cancelled`  | Stopped on request.                                                                                  |
| `expired`    | Reached `expiresAt` without finishing.                                                               |

`completed`, `failed`, `cancelled`, and `expired` are terminal.

A `completed` run that had outstanding work also carries **`incomplete: true`**. The run closed with unfinished steps, and `tasks[]` shows which. Treat this as done with gaps, not as a failure.

A `paused` run keeps everything it produced, and you can start it again. The API **never takes back** work an agent run already filed: imported records, attached files, or a sealed signature. This holds at every status.

## Long-lived by design

An agent run that is blocked on a person can wait **days**. The API supports that:

* **`expiresAt` is about seven days out.** That is the run's deadline, not a cleanup timer. An unfinished run parks itself for good when it passes the deadline. A human step must land before then.
* **The API never purges input files on a deadline.** Files you pass as `{ "url": … }` join your reusable [file corpus](/paperwork/developers/files). The run keeps its inputs however long it waits. `POST /v1/agent-runs` has no `ttl`.
* **`output.files[]` links are short-lived.** Each signed URL is valid for about an hour. Re-read the run to get a fresh one.

Agent runs are a **separate surface from [runs](/paperwork/developers/runs)**. They do not appear in `GET /v1/runs`. They have no list endpoint, and no cancel or delete. Keep the `agr_` id you got at create, or find the run again with your own `metadata`.

## Next steps

#### [Agent runs](/developers/agent-runs)

Start a run, poll it, answer an approval, and complete a human step, with curl examples.

#### [Webhooks](/developers/webhooks#agent-runs)

The five `agent_run.*` events. Subscribe to them instead of polling for days.

#### [Saved configs](/capabilities/actions)

The catalog that supplies an agent's steps.

#### [Playbooks in the app](/playbooks/overview)

Build and review the same automation from the CloudRaker interface.