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

> ## Agent Instructions
> Autumn AI (autumn.ai) is a people and company intelligence API, a separate company from useautumn.com (billing software); no billing-product routes exist here.
> Base URL https://api.autumn.ai. Auth on every request: `X-API-Key: <key>` or `Authorization: Bearer <key>`. Plain HTTP + JSON. Schemas: https://www.autumn.ai/docs/openapi.json. Every docs page is Markdown at its URL plus `.md`.

# Stream a task into your UI

> Show users live agent progress, then refresh the table when the turn ends.

A task that runs for minutes needs to show the user something better than a spinner. The
SSE routes emit the same events the Autumn dashboard renders, so your UI can narrate the
work as it happens: what the agent is doing now, errors as they occur, and rows the moment
the turn ends.

## 1. Keep the API key on your server

Every stream route requires your API key, so the browser must never connect to
`api.autumn.ai` directly. Start the task server-side, then either proxy the SSE stream
through your backend or forward its events over your own channel.

```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
// server: start the task, return only the task_id to the browser
const { task_id } = await fetch("https://api.autumn.ai/task", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.AUTUMN_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ prompt, clarify: false }),
}).then((r) => r.json());
```

## 2. Subscribe on the server, relay to the client

`GET /task/{task_id}/stream` attaches to the task and replays recent events if a turn is
already active, so a user who opens the page mid-run still sees context:

```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
// server: proxy the task's event stream
const upstream = await fetch(`https://api.autumn.ai/task/${taskId}/stream`, {
  headers: { "X-API-Key": process.env.AUTUMN_API_KEY },
});
// pipe upstream.body to the client response with SSE headers
```

This split (one process starts, another watches) is exactly what the subscribe route is
for; see [Live messages](/docs/guides/streaming) for the event parsing itself.

## 3. Map events to UI states

Each event carries a `type`, a `summary`, and `data`. The `summary` field is written to be
shown, so the cheap version of this UI is a scrolling activity feed of summaries. A step up
is a small state machine:

| Event             | UI                                                                                          |
| ----------------- | ------------------------------------------------------------------------------------------- |
| `tool_start`      | Add an in-progress step to the activity feed.                                               |
| `tool_result`     | Mark that step done.                                                                        |
| `text_delta`      | Append to the agent's running commentary.                                                   |
| `beanstalk_error` | Surface the error inline; the stream, not an HTTP status, carries failures once it is open. |
| `done`            | Close the feed, fetch rows, render the table.                                               |

## 4. On done, fetch the rows

`done` ends the turn, not the task. Refresh the table from
`GET /task/{task_id}/output`, flattening cells for display and keeping `_sources` so each
value can link to where it came from. [Outputs and sources](/docs/concepts/outputs) covers the
cell shape.

## 5. Wire the follow-up box to continue

The natural next interaction is the user asking for changes. Send that through
`POST /task/{task_id}/continue/stream` and reuse the same event pipeline for the new turn.
Disable the box while a turn is in flight; a submit during one returns `409`.

**Decision:** if your UI only needs a progress bar and a finished table, skip the stream
entirely and poll `GET /task/{task_id}` with the terminal check from
[Task lifecycle](/docs/concepts/lifecycle). Streaming earns its complexity when users watch.

## Related

<CardGroup cols={2}>
  <Card title="Live messages" icon="radio" href="/docs/guides/streaming">
    The SSE mechanics: routes, parsing, and event names.
  </Card>

  <Card title="Build a reviewed list" icon="list-checks" href="/docs/cookbook/reviewed-list">
    Put a human reviewer behind this UI.
  </Card>
</CardGroup>
