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

# Executions and statuses

> What an execution is, the statuses it moves through, and how to tell when an execution has finished.

One run of a workflow is an **execution**. It carries an ID, a status, the [inputs](/concepts/inputs-and-outputs) you passed, and a result once it reaches an Output node.

Each execution runs exactly one version of the workflow. The version is fixed when the execution starts. See [Versions and publishing](/concepts/versions).

## The status set

An execution holds one status at a time. Each status belongs to a phase.

| Status                  | Phase    | Meaning                                                |
| ----------------------- | -------- | ------------------------------------------------------ |
| `queued`                | pending  | The execution waits for capacity.                      |
| `starting`              | active   | The platform prepares the sandbox.                     |
| `running`               | active   | The workflow is working.                               |
| `paused`                | active   | A person paused the execution.                         |
| `paused_by_agent`       | active   | The workflow asked a question and waits for an answer. |
| `awaiting_confirmation` | active   | The execution waits for a person to approve an action. |
| `completed`             | terminal | The execution finished and reached an Output node.     |
| `cancelled`             | terminal | The execution stopped before it finished.              |
| `failed`                | terminal | The execution hit an error.                            |

No other statuses exist.

<Info>
  An execution starts at `queued` when the platform holds it back. That covers every row of a [batch](/operate/batches), and every execution booked for a future time.

  Everything else starts at `starting`. That covers a direct API call, and each tick of a recurring [schedule](/operate/schedules) that fires one execution.
</Info>

There is no timeout status. An execution that passes its timeout ends as `failed`, or as `cancelled` with the reason `timeout`.

## Terminal statuses

`completed`, `failed` and `cancelled` are terminal. Nothing leaves a terminal status.

<Warning>
  A terminal execution cannot resume. To retry the work, start a new execution.
</Warning>

Handle all three in your code:

* `completed` — read `executionResult` and continue.
* `failed` — log the execution and retry or alert.
* `cancelled` — read the cancel reason, then clean up.

A `completed` run is not always a successful execution. The outcome label inside `executionResult` tells you what the workflow decided. See [Inputs and outputs](/concepts/inputs-and-outputs).

## Transitions

The platform enforces a state machine. A status change outside this diagram is rejected.

```mermaid theme={null}
graph TB
    queued[queued]
    starting[starting]
    running[running]
    paused[paused]
    paused_by_agent[paused_by_agent]
    awaiting[awaiting_confirmation]
    completed[completed]
    failed[failed]
    cancelled[cancelled]

    queued --> starting
    queued --> cancelled
    queued --> failed

    starting --> running
    starting --> failed
    starting --> cancelled
    starting --> completed

    running --> paused
    running --> paused_by_agent
    running --> awaiting
    running --> completed
    running --> failed
    running --> cancelled

    paused --> running
    paused --> cancelled

    paused_by_agent --> running
    paused_by_agent --> cancelled

    awaiting --> running
    awaiting --> completed
    awaiting --> failed
    awaiting --> cancelled

    style completed fill:#dcfce7
    style failed fill:#fee2e2
    style cancelled fill:#fef3c7
    style running fill:#dbeafe
    style starting fill:#e0e7ff
```

Three rules explain the whole diagram:

1. **Terminal is final.** `completed`, `failed` and `cancelled` go nowhere.
2. **`running` is the hub.** It reaches every paused status and every terminal status.
3. **A paused run has two exits.** Both `paused` and `paused_by_agent` resume to `running` or end as `cancelled`. Neither becomes `failed`.

An execution that stays in `paused_by_agent` past the workflow's timeout ends as `cancelled` with the reason `timeout`.

## Cancel reasons

A `cancelled` execution carries a reason. The reason separates a deliberate stop from an exhausted limit.

| Reason            | Meaning                                                                                                              |
| ----------------- | -------------------------------------------------------------------------------------------------------------------- |
| `user_requested`  | A person cancelled the run from the platform or the API.                                                             |
| `timeout`         | The execution passed the workflow's execution timeout. Raise it in [Workflow settings](/concepts/workflow-settings). |
| `no_activity`     | The execution stopped producing activity, so the platform reclaimed it.                                              |
| `budget_exceeded` | The execution spent its model budget mid-flight.                                                                     |
| `script_failed`   | A node script failed, and the node cancels the run on script failure.                                                |
| `max_steps`       | A node reached the maximum number of turns it may take.                                                              |

`user_requested` is the only reason that reflects a deliberate stop. Treat the rest as something to fix — see [Debug your workflows](/operate/debug).

## Changing a status yourself

`POST /executions/{executionId}/status` accepts three values: `running`, `paused` and `cancelled`.

* **Pause** suspends the execution. Progress is kept.
* **Resume** sends the execution back to `running` from where it stopped.
* **Cancel** stops the run for good.

Cancel beats pause. If a pause request is pending and you cancel, the execution cancels.

## Watching an execution

Poll `GET /executions/{executionId}` every 5–10 seconds. Faster polling does not make an execution finish sooner.

<Warning>
  Loop until the status is **terminal**. Do not loop while the status equals `running`.

  A loop on `running` exits the moment the workflow pauses to ask a question. It then reports a half-finished run as final. Handle `paused_by_agent` and `awaiting_confirmation` explicitly.
</Warning>

A single-node execution usually finishes in 30–60 seconds. A multi-node execution takes several minutes.

For long executions, use a webhook instead of a poll loop. See [Webhooks and Slack](/operate/webhooks-and-slack).

<CardGroup cols={2}>
  <Card title="Call a workflow" icon="code" href="/integrate/call-an-agent">Start an execution and poll it, with working code</Card>
  <Card title="Debug your workflows" icon="bug" href="/operate/debug">Find out why an execution stopped</Card>
  <Card title="Versions and publishing" icon="git-commit-horizontal" href="/concepts/versions">Which version an execution uses</Card>
  <Card title="Batch executions" icon="layers" href="/operate/batches">Run one workflow over many rows</Card>
</CardGroup>
