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

# Flow Executions

> Inspect and debug Orbit Flow runs via the Executions API

# Flow Executions

Every time a published flow runs — triggered by an inbound message, a campaign send, an API call, or a scheduled cron — Orbit records a complete execution trace: which nodes ran, what their inputs and outputs were, how long they took, and any errors raised. Use the Executions API to debug flow logic in production, and forward execution events to your observability stack over [webhooks](/webhooks/events).

## List recent executions

```bash theme={null}
curl -G https://api.orbit.devotel.io/api/v1/flows/executions \
  -H "X-API-Key: dv_live_sk_..." \
  --data-urlencode "flow_id=flow_abc123" \
  --data-urlencode "status=failed" \
  --data-urlencode "limit=25"
```

### Response

```json theme={null}
{
  "data": [
    {
      "id": "exec_xyz789",
      "flow_id": "flow_abc123",
      "flow_name": "Inbound SMS auto-responder",
      "status": "failed",
      "trigger": "event",
      "steps_completed": 4,
      "total_steps": 6,
      "duration_ms": 384,
      "error": "Last failed node node_send_sms: to must be a valid E.164 phone number",
      "started_at": "2026-05-09T10:14:22.103Z",
      "created_at": "2026-05-09T10:14:22.103Z"
    }
  ],
  "meta": {
    "request_id": "req_a1b2c3",
    "timestamp": "2026-05-09T10:15:01.000Z",
    "pagination": {
      "cursor": "2026-05-09T10:14:22.103Z|exec_xyz789",
      "has_more": true
    }
  }
}
```

Each row carries these fields:

| Field             | Type           | Description                                                                               |
| ----------------- | -------------- | ----------------------------------------------------------------------------------------- |
| `id`              | string         | Execution id.                                                                             |
| `flow_id`         | string         | The flow this run belongs to.                                                             |
| `flow_name`       | string         | Current name of the parent flow (`"Untitled flow"` if the flow was deleted).              |
| `status`          | string         | One of the [status values](#status-values) below.                                         |
| `trigger`         | string         | The parent flow's trigger type — `manual`, `webhook`, `schedule`, `event`, or `workflow`. |
| `steps_completed` | number         | Count of steps recorded in this run's trace.                                              |
| `total_steps`     | number         | Count of nodes in the flow definition.                                                    |
| `duration_ms`     | number         | Wall-clock duration in milliseconds.                                                      |
| `error`           | string \| null | The failure message when the run failed, otherwise `null`.                                |
| `started_at`      | string         | ISO-8601 timestamp when the run began.                                                    |
| `created_at`      | string         | Alias of `started_at`.                                                                    |

Pagination is keyset-based: pass `meta.pagination.cursor` back as the `cursor` query parameter to fetch the next page, and stop when `has_more` is `false`.

## Get a single execution

```bash theme={null}
curl https://api.orbit.devotel.io/api/v1/flows/executions/exec_xyz789 \
  -H "X-API-Key: dv_live_sk_..."
```

The single-execution response returns the full trace, including the raw `trigger_data` context and a `steps` array — one entry per node that ran, in execution order:

```json theme={null}
{
  "data": {
    "id": "exec_xyz789",
    "flow_id": "flow_abc123",
    "status": "failed",
    "trigger_data": {
      "channel": "sms",
      "message_id": "msg_sms_abc"
    },
    "steps": [
      {
        "name": "Send Sms",
        "node_id": "node_send_sms",
        "node_type": "sendSms",
        "status": "failed",
        "duration_ms": 42,
        "input": { "to": "+not-a-number" },
        "output": { "error": "to must be a valid E.164 phone number" },
        "error": "to must be a valid E.164 phone number"
      }
    ],
    "error": "Last failed node node_send_sms: to must be a valid E.164 phone number",
    "started_at": "2026-05-09T10:14:22.103Z",
    "updated_at": "2026-05-09T10:14:22.487Z",
    "completed_at": "2026-05-09T10:14:22.487Z"
  },
  "meta": {
    "request_id": "req_a1b2c3",
    "timestamp": "2026-05-09T10:15:01.000Z"
  }
}
```

Each entry in `steps` carries a readable `name`, the originating `node_id` and `node_type` so you can correlate against the flow definition, a `status` (`completed`, `running`, `failed`, `skipped`, or `pending`), a `duration_ms`, and — when the executor recorded them — the step `input`, `output`, and a surfaced `error` message. A `pending` step has been reached but has not started executing yet; a `running` step is in progress, which also covers a node parked on a long delay or send-time schedule that will resume automatically. These per-step statuses are narrower than the run-level [status values](#status-values) below: a step never reports `waiting`, `completed_with_errors`, `timeout`, or `info`.

## Subscribe to execution events

Orbit does not expose a streaming (SSE) endpoint for executions. Execution lifecycle events are delivered over [webhooks](/webhooks/events) — subscribe an endpoint and Orbit will POST each event as the run progresses:

| Event                      | When                                                           |
| -------------------------- | -------------------------------------------------------------- |
| `flow.execution.started`   | A flow run was picked up by a worker and began executing.      |
| `flow.execution.completed` | All nodes finished successfully.                               |
| `flow.execution.failed`    | A node threw an unrecoverable error and the run was abandoned. |

See [Webhook Events](/webhooks/events) for the full catalog and [Event Payloads](/webhooks/event-payloads) for the body shape. To pull current state on demand instead, poll [`GET /flows/executions/:id`](#get-a-single-execution).

## Status values

| Status                  | Meaning                                                                                                                                                          |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `running`               | The run was picked up by a worker and at least one node is currently executing.                                                                                  |
| `waiting`               | Paused on a long delay node; the run will resume automatically at its scheduled time.                                                                            |
| `completed`             | All nodes finished successfully.                                                                                                                                 |
| `completed_with_errors` | The run finished, but one or more nodes failed and were routed via an error edge (or fell through to the default-next). The last failure is recorded in `error`. |
| `failed`                | A node threw an unrecoverable error with no error edge, and the run was abandoned.                                                                               |
| `timeout`               | Execution exceeded the per-flow wallclock cap (300s).                                                                                                            |

## Common errors

| Code           | HTTP | Cause                                                                                       | Fix                                                                                                               |
| -------------- | ---- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `NOT_FOUND`    | 404  | The execution id doesn't belong to the calling org, or the id is incorrect.                 | Verify the execution id and your org id.                                                                          |
| `RATE_LIMITED` | 429  | Per-key request rate exceeds the cap (60 requests/minute on the executions read endpoints). | Honour the `Retry-After` header; the response body also carries a numeric `retry_after` (seconds) inside `error`. |

Both responses use the standard error envelope — `error.code` carries the value above, and `meta.request_id` echoes the `X-Request-Id` for support correlation.

## Retention

Orbit retains execution traces so you can debug recent runs. There is no self-serve setting to configure an execution-retention window today — flow-execution retention is not exposed in the API or the dashboard. If you have a specific retention or data-residency requirement, contact support.
