# Run status and steps

Agent Mission Control developer docs > Bring your own agent

> The status document AMC polls, every run and step status it understands, step content, and the live event stream.

**Before you start:** An endpoint that serves `POST /runs`. See [Start and cancel a run](/developers/byo-start-a-run/).

AMC's status sync calls `GET /runs/{id}/status` on every live run, every 60 seconds by default. It is the record of the run. AMC also calls it whenever someone opens the run, to draw the step list, so keep finished runs readable.

`GET /runs/{id}/status`
```json
{
  "orchestratorRunId": "run_5f2c0e8a41b94c55",
  "status": "running",
  "currentStep": 2,
  "totalSteps": 3,
  "steps": [
    {
      "stepId": "fetch",
      "name": "Fetch invoice",
      "status": "completed",
      "agentId": null,
      "agentName": "Fetcher",
      "startedAt": "2026-10-17T09:30:00.300000+00:00",
      "completedAt": "2026-10-17T09:30:04.900000+00:00",
      "tokenCount": 0
    },
    {
      "stepId": "summarize",
      "name": "Summarize",
      "status": "running",
      "agentId": null,
      "agentName": "Summarizer",
      "startedAt": "2026-10-17T09:30:05.000000+00:00",
      "completedAt": null,
      "tokenCount": 4810,
      "inputTokens": 4200,
      "outputTokens": 610,
      "cachedInputTokens": 3000,
      "model": "<model-id>"
    },
    { "stepId": "approve", "name": "Approve summary", "status": "pending", "tokenCount": 0 }
  ],
  "runName": "invoice-INV-1042"
}
```

## Run fields

| Field | Meaning |
| --- | --- |
| `orchestratorRunId` | Your run id. |
| `status` | The run status. See the table below. |
| `currentStep` | How many steps have started (the 1-based position of the latest one). |
| `totalSteps` | How many steps the run has. |
| `steps` | Every step, in order, including ones not started yet. |
| `runName` | Optional. Renames this run in AMC. Sticky: leaving it out or sending blank keeps the last name. Ignored once the run has ended. |
| `assigneeRef` | Optional. The email of the person this run is about. See [Ask a person mid-run](https://www.agentmissioncontrol.ai/developers/byo-human-in-the-loop/). |
| `failureReason` | Optional. Why the run failed, in words a person can act on. See [Errors and timeouts](https://www.agentmissioncontrol.ai/developers/byo-errors-and-timeouts/). With `outcome: "partial"`, what wasn't done. |
| `outcome` | Optional. `"partial"` on a `completed` run marks it **Completed with issues**. See [Completed with issues](#completed-with-issues). |

For `runName`, `assigneeRef` and `failureReason`, an absent or null value means "no statement". It never clears what AMC already recorded.

## Run status values

| Status | AMC records | People see |
| --- | --- | --- |
| `running` | Running | **Running** |
| `human_intervention` | Waiting, and opens an intervention for the waiting step | **Intervention**, plus an item in the Review queue |
| `waiting` or `paused` | Waiting, with no intervention | **Intervention**, with nothing to answer |
| `completed` | Completed, outcome `success` (or `partial` with `outcome: "partial"`) | **Completed** (or **Completed with issues**) |
| `failed` | Failed, outcome `failure` | **Failed**, with your reason |
| `cancelled` (or `canceled`) | Cancelled | **Cancelled** |
| anything else | Waiting, and keeps polling | **Intervention** |

> **Important:** Report `running` while your agent waits on anything other than a person (a queue, an API, a timer). `waiting`, `paused` and unknown values all show as **Intervention**, which sends people looking for a question that isn't there.

Once AMC records `completed`, `failed` or `cancelled`, the run is final: it stops polling, and later reports don't change it.

## Completed with issues

When a run produced a usable result but part of the work wasn't done, report `completed` with `outcome: "partial"` and a run-level `failureReason` that says what wasn't done. The run's status stays `completed`; its outcome is `partial` instead of `success`.

`GET /runs/{id}/status, completed with issues`
```json
{
  "orchestratorRunId": "run_5f2c0e8a41b94c55",
  "status": "completed",
  "currentStep": 2,
  "totalSteps": 2,
  "outcome": "partial",
  "failureReason": "Slack post failed; the report was saved but nobody was notified.",
  "steps": [
    { "stepId": "report", "name": "Save report", "status": "completed", "tokenCount": 0 },
    { "stepId": "notify", "name": "Notify channel", "status": "failed", "tokenCount": 0,
      "failureReason": "Slack returned 503" }
  ]
}
```

- `partial` is the only value AMC reads. It matches after trimming, without regard to case. Any other value, or no `outcome`, is no statement, and the run is a clean success.
- AMC honors it only with `status: "completed"`. On a `failed` or `cancelled` run it is ignored.
- Send it on the same report as `completed`. Once the run is final, later reports don't change it.
- AMC never derives a partial outcome from failed steps. A `completed` run with a `failed` step and no `outcome` is a clean success. Whether a failed step matters is your agent's call.
- AMC stores up to 2000 characters of `failureReason`. Without a run-level reason, it uses the first failed step's `failureReason`.
- People see **Completed with issues** with the reason, and the completion email's subject starts with **Completed with issues**. The run counts as neither a pass nor a failure. An admin can mark it complete or failed.

## Step fields

| Field | Meaning |
| --- | --- |
| `stepId` | Required, stable, unique within the run. AMC addresses step content and replies by it. |
| `name` | Required. The label on the run page. |
| `status` | `pending`, `running`, `waiting` (on a person), `completed`, `failed` or `cancelled`. |
| `agentId`, `agentName` | Optional. Which agent ran the step. |
| `startedAt`, `completedAt` | Optional timestamps. |
| `tokenCount` | Total tokens for the step. |
| `inputTokens`, `outputTokens`, `cachedInputTokens`, `model`, `modelUsage` | What AMC prices the step from. See [Report tokens and cost](https://www.agentmissioncontrol.ai/developers/byo-tokens-and-cost/). |
| `delivered` | On a `waiting` step, the question for the person. Other steps serve their output from the content endpoint. |
| `failureReason` | On a `failed` step, why it failed. |

## Declared steps

If you registered declared steps, AMC shows the full plan as pending from the start of the run. It matches each declared step to a reported one by `key` equal to `stepId` (then by name, ignoring case). Reported steps that match nothing stay in the order they ran, alongside the matched ones. When the run ends, declared steps that never ran are dropped.

## Step content

When someone opens a step, AMC calls `GET /runs/{id}/steps/{stepId}/content`. AMC doesn't store it, so serve it for as long as people may look at the run.

`GET /runs/{id}/steps/summarize/content`
```json
{
  "stepId": "summarize",
  "action": null,
  "delivered": "Invoice INV-1042: 14 line items, three cost centers, total within limit.",
  "reasoning": null,
  "activityLog": [
    { "time": "2026-10-17T09:30:05.200000+00:00", "type": "thinking", "tool": null,
      "text": "Grouping line items by cost center", "result": null },
    { "time": "2026-10-17T09:30:06.800000+00:00", "type": "tool", "tool": "get_invoice",
      "text": "{\"id\": \"INV-1042\"}", "result": "{\"total\": 1200}" }
  ]
}
```

`delivered` is the step's headline output. Each `activityLog` row is one detail line under it: `type` is `thinking`, `tool` or `result`. AMC also accepts a bare string as a row and shows it as a tool line.

## Live events

`GET /runs/{id}/events` returns `text/event-stream`. Replay the run's events from the start, then follow new ones, and close the stream when the run ends. Each event is one `data:` line holding a JSON object.

`GET /runs/{id}/events`
```text
data: {"eventType": "step.status", "orchestratorRunId": "run_5f2c0e8a41b94c55", "stepId": "fetch", "payloadFragment": "{\"status\": \"running\"}", "at": "2026-10-17T09:30:00.300000+00:00"}

data: {"eventType": "step.status", "orchestratorRunId": "run_5f2c0e8a41b94c55", "stepId": "fetch", "payloadFragment": "{\"status\": \"completed\"}", "at": "2026-10-17T09:30:04.900000+00:00"}

data: {"eventType": "run.completed", "orchestratorRunId": "run_5f2c0e8a41b94c55", "stepId": null, "payloadFragment": "{\"summary\": \"...\"}", "at": "2026-10-17T09:31:10.000000+00:00"}
```

`payloadFragment` is a string that itself holds JSON. AMC parses it by event type and drops events it can't read:

| `eventType` | `stepId` | `payloadFragment` | Live view |
| --- | --- | --- | --- |
| `step.status` | Required | `{"status": "running"}` or `{"status": "completed"}`. A running step may add `"activity": {"type", "tool", "text", "result"}`. | Advances or completes the step, adds an activity line |
| `token.delta` | Optional | `{"totalTokens": n, "agentTokens": n, "hostTokens": n}` | Updates the token count |
| `step.paused` | Required | Not read | Shows the step is waiting on a person |
| `run.renamed` | None | `{"name": "invoice-INV-1042"}` | Renames the run in place |
| `run.status` | None | `{"status": "failed", "reason": "..."}` or `{"status": "cancelled"}` | Ends the view as failed or cancelled |
| `run.completed` | None | Not read | Ends the view as completed |

Events are display only. Anything you send on the stream must also appear in `/status`, because the poll is what AMC records.

## Related

- [Report tokens and cost](https://www.agentmissioncontrol.ai/developers/byo-tokens-and-cost/)
- [Ask a person mid-run](https://www.agentmissioncontrol.ai/developers/byo-human-in-the-loop/)
- [Errors and timeouts](https://www.agentmissioncontrol.ai/developers/byo-errors-and-timeouts/)

---
Source: https://www.agentmissioncontrol.ai/developers/byo-run-status/ · Last updated 2026-10-21 · Full index: https://www.agentmissioncontrol.ai/llms.txt
