> For the complete documentation index, see [llms.txt](https://docs.amigo.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.amigo.ai/developer-guide/platform-api/conversations/runs.md).

# Runs

The unified runs endpoint is the public browse surface for conversation runs across voice, text, SMS, email, and web, plus terminal framework runs that reached the durable projection. Framework-run projection is best-effort, so this endpoint is not a live or guaranteed-complete framework-run ledger. Use `kind=framework` to browse the projected framework history.

{% hint style="info" %}
Live voice entries come from a best-effort active-call overlay. A live call can appear late or be temporarily absent when that source is unavailable. A terminal conversation record can become available after persistence succeeds, but clients should not treat the live listing as a complete audit ledger.
{% endhint %}

## List Runs

Returns a paginated, newest-first list of conversation runs and projected terminal framework runs under one contract.

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/runs" method="get" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

### Authentication

Workspace API key (bearer token) or operator identity token. The bearer's workspace must match the path workspace.

### Status Mapping

The `status` field on each run is a canonical value derived from the underlying source:

* **Framework runs**: Terminal status is projected on a best-effort basis. A framework run may be absent if its terminal projection was not recorded.
* **Conversation runs (voice)**: An active call with no completion reason maps to `running`. A timed-out call maps to `timed_out`. Calls that ended due to errors or no audio map to `failed`. All other completed calls map to `completed`.
* **Conversation runs (non-voice)**: Active or in-progress conversations map to `running`. Closed or completed conversations map to `completed`. Failed conversations map to `failed`.

The virtual `live` status filter expands to `running` + `paused`, returning active conversation runs. Projected framework history is terminal-only.

### Example Request

```
GET /v1/{workspace_id}/runs?limit=20&status=running&status=paused&kind=conversation&channel=voice
Authorization: Bearer {api_key}
```

### Example Response

```json
{
  "items": [
    {
      "run_id": "a1b2c3d4-...",
      "workspace_id": "w1x2y3z4-...",
      "kind": "conversation",
      "status": "running",
      "channel": "voice",
      "framework": null,
      "entity_id": "e1f2g3h4-...",
      "service_id": "s1t2u3v4-...",
      "started_at": "2026-07-15T14:30:00Z",
      "ended_at": null,
      "source_call_sid": "CA1234...",
      "source_conversation_id": "c1d2e3f4-...",
      "source_framework_run_id": null
    }
  ],
  "has_more": true,
  "continuation_token": 20
}
```

### Error Responses

| Status                     | Condition                                                                                  |
| -------------------------- | ------------------------------------------------------------------------------------------ |
| `403 Forbidden`            | Bearer workspace does not match the path workspace.                                        |
| `422 Unprocessable Entity` | Invalid query parameter (unsupported `sort_by` field, invalid `continuation_token`, etc.). |
| `502 Bad Gateway`          | Run data is temporarily unavailable.                                                       |

## Runs Summary

Summarizes the same unified inventory. Repeated kind and channel filters use OR semantics, and a channel filter restricts results to conversation runs.

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/runs/summary" method="get" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

## Get a Run

Returns one available framework or conversation run. Framework results are limited to terminal runs that reached the best-effort projection. The workspace-scoped `run_id` is channel-neutral; inspect `kind`, `channel`, and the `source_*` fields to decide whether to open conversation detail, call detail, or framework trajectory next. Returns `404` when the run does not exist in the workspace.

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/runs/{run\_id}" method="get" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

## Get a Framework Trajectory

Returns ordered structural steps for a framework run. Check `truncated` before treating the returned sequence as complete.

Returns `404` when the run does not exist and `409` when the run is a conversation run. Use conversation detail for per-turn conversation history.

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/runs/{run\_id}/trajectory" method="get" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

## Takeover Eligibility

Every run carries a server-computed `takeover` object that tells a caller whether an operator can act on the run now. Clients should use this field instead of recreating channel and status rules.

Live voice runs expose `listen` and `takeover`. Live text, SMS, email, and web runs expose `takeover` only; an operator drives those channels by staging authored turns rather than joining a live media stream. Framework and non-live runs are not eligible.

## Operator Takeover

An operator can take over a live run and hand it back by channel-neutral `run_id`. Voice takeover uses a live media session and supports listen or drive mode. Text, SMS, email, and web takeover pauses the agent while the operator stages the next outbound turn.

All six operations below require `Operator:Update`, which the operator, admin, and owner roles carry. The `operator_id` in the body must match the authenticated operator; impersonation is rejected.

### Take Over a Run

Registers the operator on a live run. In `takeover` mode the agent is suspended so the human drives; in `listen` mode the operator monitors without driving. Non-voice channels support `takeover` mode only.

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/runs/{run\_id}/takeover" method="post" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

### Hand a Run Back

Releases the operator from the run. For non-voice channels, the stored status moves from `paused` back to `active`; for voice, the operator leaves the live media session and the agent is resumed. Subsequent behavior uses whatever conversation state and takeover evidence the runtime successfully retained; the handback response does not guarantee a complete transcript of operator activity.

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/runs/{run\_id}/handback" method="post" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

### Author a Non-Voice Turn

Stages the next operator-authored reply on a taken-over text, SMS, email, or web run. A run can hold one pending authored reply; staging another before it is consumed replaces the earlier text. The reply is consumed before downstream delivery completes, so a later delivery failure does not restore that pending value automatically. This is not an exactly-once delivery guarantee. Wait for a staged turn to be consumed before staging another.

Voice runs return `409` because the operator drives them through live audio.

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/runs/{run\_id}/authored-turn" method="post" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

### Switch Mode

Toggles an operator who has already joined a voice run between `listen` and `takeover`. Non-voice runs return `409` because they support authored-turn takeover only.

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/runs/{run\_id}/switch-mode" method="post" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

### Mint a Browser-Audio Access Token

Mints browser-audio credentials used to attach an operator to a live voice run. Non-voice runs return `409`.

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/runs/{run\_id}/access-token" method="post" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

### Send Guidance

Sends text guidance to a live voice run. Guidance is delivered as a prioritized instructional event that can interrupt current agent speech, unlike a factual [external event](/developer-guide/platform-api/conversations/voice-agent.md), which queues behind current speech. The returned delivery status does not guarantee exact response timing or that the model follows the instruction verbatim. Non-voice channels return `409`; use authored-turn takeover when an operator must send a reply.

The audit record captures the run, channel, operator identity, and a content fingerprint, never the raw guidance text.

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/runs/{run\_id}/guidance" method="post" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

## Agent Forge CLI

Agent Forge `v0.1.44+` exposes the unified read surface:

```bash
forge platform run list \
  --kind conversation \
  --channel voice \
  --status live \
  --limit 50 \
  --env <env>

forge platform run summary --kind conversation --env <env>
forge platform run get <run_id> --env <env>
```

Add `--json` for the raw response. The CLI accepts one value per filter flag and prints `--continuation-token` when another page is available; pass that token unchanged to the next `run list` call. The REST API itself supports repeated filter values.

## Rate Limits

Each list, summary, detail, and trajectory operation allows 60 requests per minute. Each takeover, handback, authored-turn, mode-switch, access-token, and guidance operation allows 10 requests per minute. Limits are enforced per authenticated credential and operation. Successful limit checks return `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset`; a `429` response also returns `Retry-After`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.amigo.ai/developer-guide/platform-api/conversations/runs.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
