> ## 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`.

# Quickstart

> Start your first Autumn task over HTTP and read the rows it produces.

One `POST` starts a cloud agent that does the research. You keep the `task_id`, wait while
it works, then read finished rows.

One host, and every route is in the spec:

```txt theme={"theme":{"light":"github-light","dark":"github-dark"}}
Base URL:  https://api.autumn.ai
OpenAPI:   https://api.autumn.ai/openapi.json
Auth:      X-API-Key: YOUR_AUTUMN_API_KEY
```

## 1. Get an API key

Create an API key in Autumn settings under **API**, then put it in your environment:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
export AUTUMN_API_KEY=your_key
```

Every request sends it as `X-API-Key` (or `Authorization: Bearer`).

## 2. Start a task

<CodeGroup>
  ```bash curl theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -sS -X POST "https://api.autumn.ai/task" \
    -H "X-API-Key: $AUTUMN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "prompt": "List the top 20 posts on Hacker News today with their points",
      "clarify": false
    }'
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import os, requests

  AUTUMN = "https://api.autumn.ai"
  HEADERS = {"X-API-Key": os.environ["AUTUMN_API_KEY"]}

  task = requests.post(
      f"{AUTUMN}/task",
      headers=HEADERS,
      json={"prompt": "List the top 20 posts on Hacker News today with their points",
            "clarify": False},
  ).json()

  task_id = task["task_id"]
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const AUTUMN = "https://api.autumn.ai";
  const HEADERS = {
    "X-API-Key": process.env.AUTUMN_API_KEY,
    "Content-Type": "application/json",
  };

  const res = await fetch(`${AUTUMN}/task`, {
    method: "POST",
    headers: HEADERS,
    body: JSON.stringify({
      prompt: "List the top 20 posts on Hacker News today with their points",
      clarify: false,
    }),
  });
  const { task_id } = await res.json();
  ```
</CodeGroup>

The response is your handle on the task:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "task_id": "8fab6f34",
  "status": "execute",
  "phase": "execute",
  "stream_url": "/task/8fab6f34/stream",
  "output_url": "/task/8fab6f34/output"
}
```

Store `task_id`. It stays valid after the run finishes.

## 3. Wait for it to finish

Poll `GET /task/{task_id}`. A finished task returns to `status: "plan"` with
`activity: "idle"`.

<Warning>
  Don't poll on `status` alone. `plan` is also the state a task sits in *before* it executes,
  so `status: "plan"` by itself does not mean finished. A task is still working while `phase`
  is `execute`, `status` is `execute`/`running`, or `activity` is
  `executing`/`running`/`planning`/`thinking`. Treat `deleted` and an `error` of
  `out_of_credits`/`error` as terminal too, or the loop will never exit.
</Warning>

<CodeGroup>
  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import time

  ACTIVE_STATUSES = {"execute", "running"}
  ACTIVE_ACTIVITIES = {"executing", "running", "planning", "thinking"}

  def is_terminal(task):
      if task.get("status") == "deleted" or task.get("activity") == "deleted":
          return True
      if task.get("error") in {"out_of_credits", "error"}:
          return True
      return not (task.get("phase") == "execute"
                  or task.get("status") in ACTIVE_STATUSES
                  or task.get("activity") in ACTIVE_ACTIVITIES)

  while True:
      task = requests.get(f"{AUTUMN}/task/{task_id}", headers=HEADERS).json()
      if is_terminal(task):
          break
      time.sleep(2)
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const ACTIVE_STATUSES = new Set(["execute", "running"]);
  const ACTIVE_ACTIVITIES = new Set(["executing", "running", "planning", "thinking"]);

  const isTerminal = (t) =>
    t.status === "deleted" || t.activity === "deleted" ||
    ["out_of_credits", "error"].includes(t.error) ||
    !(t.phase === "execute" ||
      ACTIVE_STATUSES.has(t.status) ||
      ACTIVE_ACTIVITIES.has(t.activity));

  let task;
  do {
    await new Promise((r) => setTimeout(r, 2000));
    task = await fetch(`${AUTUMN}/task/${task_id}`, { headers: HEADERS }).then((r) => r.json());
  } while (!isTerminal(task));
  ```

  ```bash curl theme={"theme":{"light":"github-light","dark":"github-dark"}}
  # poll every 2s until status=plan and activity=idle
  while :; do
    curl -sS "https://api.autumn.ai/task/$TASK_ID" -H "X-API-Key: $AUTUMN_API_KEY"
    sleep 2
  done
  ```
</CodeGroup>

This is the complete terminal check, including the `deleted` and out-of-credits cases.
[Task lifecycle](/docs/concepts/lifecycle) explains why each one is in there. Prefer live events
over polling? See [Live messages](/docs/guides/streaming).

## 4. Read the rows

<CodeGroup>
  ```bash curl theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -sS "https://api.autumn.ai/task/$TASK_ID/output?limit=100" \
    -H "X-API-Key: $AUTUMN_API_KEY"
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  rows = requests.get(
      f"{AUTUMN}/task/{task_id}/output",
      headers=HEADERS,
      params={"limit": 100},
  ).json()["rows"]

  for row in rows:
      print({k: v["value"] for k, v in row.items() if isinstance(v, dict) and "value" in v})
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const { rows } = await fetch(
    `${AUTUMN}/task/${task_id}/output?limit=100`,
    { headers: HEADERS },
  ).then((r) => r.json());
  ```
</CodeGroup>

Each field arrives as a cell, `{"value": ..., "source_id": ...}`, so every value carries
the source behind it. Flatten to plain values when you just want the data, and keep the
cells when you need provenance. See [Outputs](/docs/concepts/outputs).

## 5. Continue instead of restarting

The `task_id` is durable. To refine or extend results, send the same task new
instructions rather than starting over:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -sS -X POST "https://api.autumn.ai/task/$TASK_ID/continue" \
  -H "X-API-Key: $AUTUMN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"message": "Add the submitting user for every row, and find 10 more"}'
```

## What a task can do

* **Data extraction**: scrape sites and collect structured rows with sources
* **Enrichment**: fill in people, companies, jobs, contacts, filings
* **Multi-step research**: search across many sources, compare, and summarize
* **List building**: find N entities that match criteria, with per-row evidence
* **Continuation**: refine, expand, or fix a previous task without starting over

## Next

<CardGroup cols={2}>
  <Card title="Structured output" icon="braces" href="/docs/guides/structured-output">
    Declare the exact columns you want back.
  </Card>

  <Card title="Live messages" icon="radio" href="/docs/guides/streaming">
    Stream events as the agent works.
  </Card>

  <Card title="Follow-up tasks" icon="repeat" href="/docs/guides/follow-up">
    Continue the same task with new instructions.
  </Card>

  <Card title="Task API" icon="terminal" href="/docs/api-routes">
    Every route, field, and response shape.
  </Card>
</CardGroup>
