The assistant that runs inside the app is also reachable with an API key, so your own program can hand Monofile a task, watch it work, and stop it. With [[Calling Tools]] you drive each tool yourself. Here you describe the goal and the assistant picks the tools.

> [!NOTE]
> You need a paid plan for this. On a personal workspace that is Pro, in an organization it is Team. See [[Plans and Billing]].

## Start a task

`POST /api/chats/stream` creates a conversation and starts a run in one request.

```http tab="HTTP"
POST /api/chats/stream
{
  "mode": "agent",
  "effort": "balanced",
  "messages": [
    { "role": "user", "parts": [{ "type": "text", "text": "Read /Notes/plan.md and tidy its headings." }] }
  ]
}
```

```bash tab="curl" title="Terminal"
curl -N https://www.monofile.ai/api/chats/stream \
  -H "Authorization: Bearer $MONOFILE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "agent",
    "effort": "balanced",
    "messages": [
      { "role": "user", "parts": [{ "type": "text", "text": "Read /Notes/plan.md and tidy its headings." }] }
    ]
  }'
```

| Field | Meaning |
|---|---|
| `messages` | The conversation so far, newest last. A first turn is a single user message. |
| `mode` | `read-only` to let it look but not touch, `agent` to let it write. |
| `effort` | `fast`, `balanced`, `thorough` or `max`. Higher effort thinks longer and costs more. |
| `model` | An explicit model instead of an effort preset. Effort wins if you send both. |
| `mentions` | Files whose content to attach to this turn. |

The response is a stream of UI message events, the text as the model writes it plus a marker for every tool call and its result. Three headers tell you what you are watching:

| Header | Use it for |
|---|---|
| `x-run-id` | The run id (`run_...`). Keep it for reconnecting, checking status and stopping. Older clients still get the same value as `x-workflow-run-id`. |
| `X-Chat-Id` | The conversation id. Send it back to continue the same thread. |
| `X-Model` | The model the server resolved. |

To continue an existing conversation, post to `/api/chats/{chatId}/stream` with the full message history.

```http
POST /api/chats/{chatId}/stream
```

## The run keeps going without you

Closing the connection does not stop the task. The server keeps running it and records every event it streams, so a long task survives your process exiting and you can rejoin the stream. See [[Long-Running Tasks]].

### Reconnect

```http
GET /api/chats/{chatId}/runs/{runId}/stream
```

Replays every event from the start of the run, then keeps streaming live until the run settles. Recorded events last seven days. A `204` means the run is over and its events are gone, so read the saved conversation with `GET /api/chats/{chatId}` instead.

### Poll

```http
GET /api/chats/{chatId}/runs/{runId}
```

Returns `{ "run": { ... } }` with the run's `status`, `error`, `costCents`, `budgetCents`, token and step counts and timestamps. Statuses are `queued`, `running`, `cancelling`, `waiting_approval`, `completed`, `failed` and `cancelled`. The next read of a run that has produced nothing for 15 minutes marks it `failed` with an "interrupted" error.

### Stop

```http
POST /api/chats/{chatId}/runs/{runId}/cancel
```

Stops the run and keeps what it already did. The reply is `{ "runId", "mode", "status" }`. `mode` is `requested` when the loop will stop at its next step, with status `cancelling` until it does, or `finished` when the run was already over.

Treat the finish of the stream and the finish of the run as two different things. The stream ends first; the conversation and the run ledger settle a moment later. If you need the saved transcript, poll until the status is terminal.

## One run per conversation

A conversation runs one task at a time. Posting a new message while a run is live returns `409` with `code: "RUN_ACTIVE"` and the id of the run already in flight. Either wait for it, reconnect to it, or cancel it.

## Approvals

Some actions pause for approval: reverting a whole run, deleting a version, revoking a share link, a destructive shell command. The run's status becomes `waiting_approval` and the stream carries a tool part awaiting a decision. Your client answers by sending the conversation back with an approval response attached, the same way the web client does. To avoid approval prompts entirely, run in `read-only` mode. See [[Approvals]].

## What it costs

Monofile meters runs in credits against the workspace that owns the key, with a per-run budget. When the budget runs out, the run stops. `GET /api/chats/{chatId}/runs/{runId}` reports `costCents` as it goes. See [[AI Credits and Usage]].

## Next steps

:::cards
- [[Long-Running Tasks]] — Durable runs that survive reloads and closed tabs, and how to watch or stop them.
- [[Reviewing Changes]] — The diff view and the changeset card: keep or revert everything an agent touched.
- [[Calling Tools]] — The one-endpoint pattern, the MCP-shaped envelope, and the index of every tool.
- [[Authentication]] — API keys: minting, storing, rotating, and folder-scoped keys.
:::
