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

# Runs and tasks

> The durable unit of work (a run) and the ephemeral unit of execution (a task).

The API models two related but distinct things:

* A **run** is a durable document. It persists across many calls and
  retains what the agent "knows" about what it built.
* A **task** is one execution against a run — the act of submitting a
  prompt, running the agent, and producing output.

A run can have many tasks. The first task creates the run; subsequent
tasks (when you pass `run_id`) resume it.

## Why separate them

In the web app, agents work on a document over many chat turns. The API
mirrors that: turn 1 creates the scaffold, turn 2 adds a section, turn 3
changes the branding — and each turn should cost a fraction of turn 1
because the agent remembers what it built.

Without run-level durability, every turn would re-inspect the document
from scratch. With it, bookmark IDs, sheet names, chart references —
everything the agent learned in turn 1 — are still in context for turn 5.

## Creating a run (implicit)

Every generation endpoint creates a run if you don't pass `run_id`:

```json theme={null}
POST /excel/generate
{ "prompt": "Create a Q3 sales report" }

→ {
  "run_id": "run_01HXYZ...",
  "task_id": "task_01HXYZ...",
  "download_url": "...",
  "status": "completed",
  ...
}
```

The `run_id` is yours to keep. Store it with whatever record in your
system represents this document.

## Resuming a run

Pass the same `run_id` on the next call and add a new prompt:

```json theme={null}
POST /excel/generate
{
  "run_id": "run_01HXYZ...",
  "prompt": "Now add a forecast tab for FY26"
}
```

Semantics:

* The agent's conversation state is restored from our durable store,
  keyed on `run_id`.
* The last saved document bytes are reloaded into the same run context
  the agent was using.
* The new prompt is appended as a fresh user message.
* The agent continues, using everything it already built.
* `download_url` points to the new saved state after this turn.

## Tasks

Each invocation produces a task. In sync mode the task shape is hidden
— you get the finished result back directly. In async mode you get a
`task_id` to poll:

```json theme={null}
POST /excel/generate
{ "prompt": "...", "async": true }

→ {
  "run_id": "run_01HXYZ",
  "task_id": "task_01HXYZ",
  "status": "queued"
}
```

Then:

```json theme={null}
GET /tasks/task_01HXYZ

→ {
  "task_id": "task_01HXYZ",
  "run_id": "run_01HXYZ",
  "status": "running",
  "phase": "agent_turn",
  "turn_index": 3,
  "progress": 45,
  "created_at": "...",
  "updated_at": "..."
}
```

See [Async vs sync](/concepts/async-vs-sync) for the full state machine.

## Listing runs

```bash theme={null}
GET /runs?limit=20&format=excel&status=completed
```

Returns the most recent runs for your org, newest first. Cursor-based
pagination via the `next_cursor` field.

```json theme={null}
{
  "items": [
    {
      "run_id": "run_01HXYZ",
      "format": "excel",
      "status": "completed",
      "prompt": "Create a Q3 sales report with...",
      "credits_used": 84,
      "duration_ms": 18432,
      "created_at": "2026-04-17T11:20:00Z",
      "file_name": "workbook.xlsx"
    }
  ],
  "next_cursor": "run_01HXY..."
}
```

## Downloading

Two options per run:

```bash theme={null}
# Option A: JSON response containing download_url (signed, 24h TTL)
GET /runs/{run_id}

# Option B: 302 redirect to the signed URL
GET /runs/{run_id}/download
```

Option B is what you want from a browser `<a href>` — no extra round-trip.

## Exporting to other formats

Convert a run's output to PDF, PNG, etc. via
[POST /runs/{run_id}/export](/api-reference):

```json theme={null}
POST /runs/{run_id}/export
{ "format": "pdf" }

→ {
  "format": "pdf",
  "download_url": "...",
  "expires_at": "..."
}
```

Supported conversions:

| Source | Targets                     |
| ------ | --------------------------- |
| `xlsx` | `pdf`, `csv`, `png`, `html` |
| `docx` | `pdf`, `html`, `txt`, `odt` |
| `pptx` | `pdf`, `png`, `odp`         |

Exports are cached — calling `/export?format=pdf` twice for the same run
only runs the conversion once.

## Retention

Runs are retained for **30 days** after their last task. After that:

* The `run_id` still resolves via `GET /runs/{run_id}` for audit, but its
  state is marked `expired`.
* Resuming an expired run returns `410 gone`. Start a fresh run instead.
* The saved document bytes are removed from storage 30 days after expiry.

Enterprise customers can extend retention — [contact
us](mailto:support@overten.ai).
