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

# Concepts

> Understanding runs, output, and citations in the Seltz Agent API

## Overview

**Agent** turns a question into a multi-step research loop: it plans its own
searches, follows up on what it finds, and keeps going until it has enough to
answer, rather than the single grounding search
[Answer](/answer/answer-concepts) makes. Because that
loop can take a while, a run is asynchronous rather than a single request/response.

This topic explains the terminology used in Agent and how the feature works.

## The run lifecycle

A run moves through a small, closed state machine:

```
pending → running → completed / failed / cancelled
```

[`create`](/api-reference/agent/start-run) returns at once with the run in
`pending` state. There is no notification when it finishes. Poll
[`get`](/api-reference/agent/get-run) by id, or let the SDKs' `wait` /
`create_and_wait` (`createAndWait`) do the polling for you. Runs typically
finish in under a minute for a simple question, but a harder one can take
several minutes and up to around an hour.

[`status`](/api-reference/agent/get-run#response-status) is the coarse
outcome; [`stop_reason`](/api-reference/agent/get-run#response-stop-reason-one-of-1)
is the fine-grained one, and it appears only once a run reaches a terminal
state:

| `status`    | Legal `stop_reason` values                                      | Meaning                                                       |
| ----------- | --------------------------------------------------------------- | ------------------------------------------------------------- |
| `completed` | `finished`, `budget_reached`, `timeout`                         | Usable output, whether or not the run ran to full completion. |
| `failed`    | `budget_reached`, `timeout`, `invalid_output`, `internal_error` | No usable output.                                             |
| `cancelled` | `cancelled`                                                     | Stopped on request; a cancelled run has no output.            |

`budget_reached` and `timeout` are cut-offs, not verdicts on their own: a
budget-capped run with schema-valid partial output is `completed` +
`budget_reached`; one with nothing usable is `failed` + `budget_reached`. See
[Reference](/agent/reference#run-status-and-stop-reason) for the full table.

## Output: text or structured

By default, [`output.text`](/api-reference/agent/start-run#response-output-one-of-1)
is a cited Markdown report: inline `[n]` markers point at entries in
[`output.sources`](/api-reference/agent/start-run#response-output-one-of-1),
the list of pages the run consulted.

Pass [`output_schema`](/api-reference/agent/start-run#body-output-schema-one-of-0)
(the same OpenAI-style `response_format` object `answer` and chat
completions accept) to also get
[`output.structured`](/api-reference/agent/start-run#response-output-one-of-1),
a JSON result shaped by your schema. Requesting structured output does not
replace the text report; both are present on a completed run. See
[Structured output](/agent/guides/structured-output).

## Sources, grounding, and citations

Three related lists carry attribution, at two different levels of the output:

* **`output.sources`**: every page the run consulted, in retrieval order.
  Each entry has a stable `id` (starting at 1) and a `url`. This is the list
  `output.text`'s inline `[n]` markers point into.
* **[`output.grounding`](/api-reference/agent/start-run#response-output-one-of-1)**:
  present only alongside `output.structured`. One entry per field of the
  structured result the run could ground, keyed by a dot-notation `field`
  path (e.g. `"acquisitions.0.acquirer"`).
* Each grounding entry's **`citations`** point back into `output.sources` by
  `source_id`, so a field can cite more than one source.

A field the run could not ground is `null` in `output.structured`; the model
does not invent a value, and the field has no corresponding
`output.grounding` entry.

## Cancellation is best-effort

[`cancel`](/api-reference/agent/cancel-run) requests that a run stop; it is
not a guarantee. It cancels a
`pending` run at once, but a `running` one stops at its **next step**. If the
run is close enough to finishing, it can complete before the cancellation
takes effect, so `cancel` returns whatever the run's status actually is at
that moment rather than forcing it to `cancelled`. This makes `cancel` safe
to call speculatively: it never errors on a run that already ended, so you
can retry it and race it against completion.

## Next steps

To learn more about Seltz Agent, check out the following topics:

* [Quickstart](/agent/quickstart): making your first request
* [Basic run](/agent/guides/basic-run): the full request/response cycle, including the cURL poll
* [Structured output](/agent/guides/structured-output): requesting a JSON result instead of Markdown
* [List runs](/agent/guides/list-runs): paging this org's runs, newest first
* [Poll for completion](/agent/guides/poll-for-completion): managing the wait yourself
* [Cancel a run](/agent/guides/cancel-a-run): best-effort cancellation, and why it can lose the race to completion
* [Handle errors](/agent/guides/handle-errors): rejected requests versus failed runs
* [Reference](/agent/reference): endpoints, fields, limits and errors
* [Agent API Reference](/api-reference/agent/start-run): full REST request and response specification
