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

# Agent runs

> Start a run, poll it to completion, queue follow-ups, steer a turn already in flight, and stop one that has gone wrong.

A run is one agent turn. You start it with `POST /api/agent/message` and poll `GET /api/agent/status/{call_id}` until it finishes. Everything else on this page - queueing, steering, stopping - exists because turns are long enough that you will want to change your mind while one is running.

```bash theme={null}
export ARG_API_KEY="arg_live_your_key_here"
export ARG_API="https://api.arg.ai"
```

## Start a run

```bash theme={null}
curl -sS -X POST "$ARG_API/api/agent/message" \
  -H "X-API-Key: $ARG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workspace_id": "'"$WS"'",
    "message": "Read data.csv and write summary.txt with revenue by region."
  }'
```

```json theme={null}
{ "job_id": "job_…", "call_id": "call_…", "chat_id": "…" }
```

`chat_id` is optional. Omit it and the run creates its own chat; pass it to continue an existing conversation. Keep the returned `chat_id` - every other endpoint on this page needs it.

<Note>
  A `200` means the turn started. A **`202`** means a turn was already running on
  this chat and yours was queued behind it - see [Queued
  messages](#queued-messages).
</Note>

### Run options

| Field                 | Type      | Description                                                                                               |
| --------------------- | --------- | --------------------------------------------------------------------------------------------------------- |
| `message`             | string    | The instruction to run. Required.                                                                         |
| `chat_id`             | string    | Continue this chat. A new one is created when omitted.                                                    |
| `workspace_id`        | string    | Files and sandbox for the run. Without it the agent has no tools.                                         |
| `model`               | string    | Model id, for example `anthropic/claude-haiku-4.5`. See [list models](/api-reference/models/list-models). |
| `reasoning_effort`    | string    | `none`, `low`, `medium`, or `high`. Clamped to what the model supports.                                   |
| `max_tool_iterations` | integer   | Tool-use rounds allowed this turn, 1 to 100.                                                              |
| `read_only`           | boolean   | Give the agent read-only tools, so it cannot modify the workspace.                                        |
| `disabled_skills`     | string\[] | Skill names to withhold from this turn.                                                                   |
| `disabled_agents`     | string\[] | Subagent names to withhold from this turn.                                                                |

## Poll until it finishes

`status` is `pending` while the run is in flight, then `completed` or `error`. There is no intermediate event stream on this endpoint - poll it every few seconds.

```bash theme={null}
curl -sS "$ARG_API/api/agent/status/$CALL?chat_id=$CHAT" \
  -H "X-API-Key: $ARG_API_KEY"
```

```json theme={null}
{
  "status": "completed",
  "result": {
    "status": "completed",
    "chatId": "…",
    "response": "I wrote summary.txt with revenue totals by region.",
    "toolOutputs": [
      { "tool": "write_file", "args": { "path": "/summary.txt" }, "result": "ok" }
    ]
  }
}
```

`result.toolOutputs` names every file the agent touched, which is the quickest way to find the artifacts a run produced without diffing the whole tree.

A complete poll loop:

```bash theme={null}
until [ "$(curl -sS "$ARG_API/api/agent/status/$CALL?chat_id=$CHAT" \
  -H "X-API-Key: $ARG_API_KEY" | jq -r .status)" != "pending" ]; do
  sleep 3
done
```

### Resuming after a restart

If your process dies mid-run, ask the chat what is still in flight instead of holding the ids in memory:

```bash theme={null}
curl -sS "$ARG_API/api/agent/pending/$CHAT" -H "X-API-Key: $ARG_API_KEY"
```

```json theme={null}
{ "pending_job": { "job_id": "job_…", "call_id": "call_…" } }
```

`"pending_job": null` means the chat is idle and there is nothing to resume.

## Release the run

When a run reaches `completed` or `error`, release it so the chat is ready for the next turn:

```bash theme={null}
curl -sS -X POST "$ARG_API/api/agent/cleanup/$JOB?chat_id=$CHAT" \
  -H "X-API-Key: $ARG_API_KEY"
```

## Queued messages

Send a second message while a turn is running and you get a `202` instead:

```json theme={null}
{ "status": "queued", "queue_id": "q_…", "position": 1, "chat_id": "…" }
```

The queue drains in order once the running turn finishes. You can inspect and rearrange it:

```bash theme={null}
# What is waiting
curl -sS "$ARG_API/api/agent/queue/$CHAT" -H "X-API-Key: $ARG_API_KEY"

# Move a message to the front
curl -sS -X PATCH "$ARG_API/api/agent/queue/$CHAT/$QUEUE_ID/reorder" \
  -H "X-API-Key: $ARG_API_KEY" -H "Content-Type: application/json" \
  -d '{"new_index": 0}'

# Drop one
curl -sS -X DELETE "$ARG_API/api/agent/queue/$CHAT/$QUEUE_ID" \
  -H "X-API-Key: $ARG_API_KEY"
```

### Steering a turn in flight

Waiting for the queue is the wrong move when the agent is heading somewhere you do not want. **Steering** promotes a queued message into the turn that is already running, delivered at the agent's next step boundary:

```bash theme={null}
curl -sS -X POST "$ARG_API/api/agent/queue/$CHAT/$QUEUE_ID/steer" \
  -H "X-API-Key: $ARG_API_KEY"
```

A `409` with `"status": "not_steerable"` means the current turn cannot take a mid-flight message. Leave it queued - it will be delivered normally when the turn ends.

## Stop a run

```bash theme={null}
curl -sS -X POST "$ARG_API/api/agent/stop/$JOB?chat_id=$CHAT" \
  -H "X-API-Key: $ARG_API_KEY"
```

Stopping interrupts the turn and drains anything queued behind it. A `409` means the job was not running - it had already finished.

## Putting it together

```mermaid theme={null}
sequenceDiagram
    participant C as Your service
    participant A as arg.ai
    C->>A: POST /api/agent/message
    A-->>C: 200 job_id + call_id  (or 202 queued)
    loop until status is not pending
        C->>A: GET /api/agent/status/{call_id}
        A-->>C: pending
    end
    A-->>C: completed + result.toolOutputs
    C->>A: GET /files/tree, GET /files/download
    C->>A: POST /api/agent/cleanup/{job_id}
```

## Managing the chat itself

`/api/chats/*` accepts a user access token or an API key. Service-account keys own their own chats; user-owned keys act on yours, within the key's organization.

```bash theme={null}
# List chats
curl -sS "$ARG_API/api/chats" -H "X-API-Key: $ARG_API_KEY"

# Read a chat and its messages
curl -sS "$ARG_API/api/chats/$CHAT" -H "X-API-Key: $ARG_API_KEY"

# Rename it
curl -sS -X PATCH "$ARG_API/api/chats/$CHAT" \
  -H "X-API-Key: $ARG_API_KEY" -H "Content-Type: application/json" \
  -d '{"title": "Revenue rollup"}'

# Delete it (blocked while a run is in flight)
curl -sS -X DELETE "$ARG_API/api/chats/$CHAT" -H "X-API-Key: $ARG_API_KEY"
```

## Related

* [Agents overview](/guides/agents/overview) - what an agent can reach for
* [Unattended runs](/guides/agents/unattended) - running this loop with no human watching
* [Tools](/guides/tools) - call the agent's tools directly, without an agent
* [Agent API reference](/api-reference/agent/send-message) - every field and response
