> To find and run AgentRouter tools, connect to https://mcp.agentrouter.to/. To search this documentation, use https://docs.agentrouter.to/_mcp/server. Append .md to a page URL for Markdown. For the documentation index, see https://docs.agentrouter.to/llms.txt.

# Runs

Every accepted invoke creates a Run. The Run is the receipt: it keeps the provider's output, the run status, the provider's own outcome, and the charge with its reason. The same run is visible to whichever entry made it — HTTP, CLI, MCP or the web Playground — and in [Usage](https://www.agentrouter.to/settings/usages).

The run receipt includes the submitted `input`. In Usage, open a run to view and copy its input and saved output. These reads use the same account authorization as the receipt; another account cannot read them. Input and receipt metadata remain in the run history after output expires.

Provider failures include `error.details` when available: a sanitized response body and a `truncated` flag. Credentials, authentication fields and internal pricing fields are redacted. JSON error evidence is limited to 20,000 characters; non-JSON error pages are omitted. Older runs cannot recover error bodies that were not saved. This diagnostic evidence is retained with the run receipt, and a provider error remains a failed, uncharged run.

## Three separate facts

| Field                       | Values                                                                                             | Meaning                                                       |
| --------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| `status`                    | `READY`, `RUNNING`, `STOPPING`, `COMPLETED`, `FAILED`, `BLOCKED`, `STOPPED`, `TIMED_OUT`           | Where the run is                                              |
| `provider_response.outcome` | `success`, `empty`, `provider_error`, `pending`                                                    | What the provider said, with its `http_status` and request id |
| `billing.reason`            | `charged`, `charged_capped`, `free_promotion`, `zero_base`, `waived_*`, `blocked_before_execution` | Why the charge is what it is                                  |

A `$0` charge always has a reason next to it, for example `waived_provider_error` or `free_promotion`.

## Long-running calls

Invoke waits up to about 25 seconds (`wait_ms` can shorten that). If the provider has not finished, invoke returns HTTP `202` with `status: RUNNING` and a `POLL_RUN` hint. The run continues on the server:

```bash
curl -s "https://api.agentrouter.to/v1/runs/$RUN_ID?wait_ms=30000" -H "Authorization: Bearer $AGENTROUTER_API_KEY"
```

* Your client giving up does not cancel, refund or re-run anything. Fetch the same `run_id` later.
* Never call invoke again to "check" a run; that is a new call with a new charge. If you lost the response, retry with the same `Idempotency-Key` to get the original run back.
* A run that passes the tool's `max_duration_ms` ends as `TIMED_OUT` and is not charged.

## Results

Small outputs are returned inline in `output`, exactly as the provider sent them (numbers are not rounded or re-encoded). Large outputs are stored instead: `result.inline` is `false` and `result.url` downloads them.

```bash
curl -s "https://api.agentrouter.to/v1/runs/$RUN_ID/result" -H "Authorization: Bearer $AGENTROUTER_API_KEY" -o result.json
agentrouter runs get "$RUN_ID" --output result.json
```

Viewing, copying or downloading a saved result never re-runs the tool or charges again. Results are kept until `result.expires_at` (30 days by default); opening a dispute keeps the disputed runs' existing results from expiring. After expiry, `result.available` is false, `result.expired` is true and the result URL is null. A direct download returns HTTP 410 `RESULT_EXPIRED`; the UI shows that the output expired.

Web previews show up to 20,000 characters and explicitly identify truncated previews. Copy and Download JSON include the complete saved output. Large results load when you choose **View saved output**. HTTP output and both MCP response representations preserve numeric literals, including large integer IDs. When consuming JSON in your own code, use a parser that preserves these numbers; ordinary JavaScript `JSON.parse` can round them.

## Stopping

`POST /v1/runs/{run_id}/stop` (MCP `stop_run`, CLI `agentrouter runs stop`) works only for tools whose describe says `execution.stoppable: true`. A run stopped before the provider completes is not charged. For other tools the call returns `RUN_NOT_STOPPABLE` and the run settles normally.

## Pages

When more results exist, the run has `next_cursor` and a `NEXT_PAGE` hint naming the input field that takes it. The next page is a new invoke and is charged as a new call. Decide how many pages the task needs before fetching them.

## History

```bash
curl -s "https://api.agentrouter.to/v1/runs?session_id=research-7&limit=20" -H "Authorization: Bearer $AGENTROUTER_API_KEY"
```

Filter by `status` (`running` covers READY, RUNNING and STOPPING), `tool_id`, `session_id` or `caller_id`, and page with `next_cursor`. The CLI equivalent is `agentrouter runs list`, and MCP has `list_runs`.

## Receipt fields

| Field                                                                                     | Meaning                                                                                                       |
| ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `run_id`, `tool_id`, `tool_version`, `provider`                                           | What ran                                                                                                      |
| `caller`, `channel`, `session_id`                                                         | Who ran it (API key, OAuth host or web session) and through which entry                                       |
| `replayed`, `billing.charge_is_new`                                                       | `true` / `false` when an idempotency key returned an existing run                                             |
| `billing.pricing_version`, `price_multiplier`, `promotion_id`                             | The price terms the run was accepted under; recovery keeps them                                               |
| `billing.max_cost_usd`, `reserved_usd`                                                    | The cap and the hold taken before running                                                                     |
| `billing.base_charge_usd`, `customer_charge_usd`, `customer_refund_usd`, `net_charge_usd` | Price before the multiplier, the charge, refunds and the net                                                  |
| `billing.usage`                                                                           | Provider usage the charge is based on (`quantity` and `unit`, or `unknown`)                                   |
| `error`                                                                                   | `code`, `message`, `origin` (`provider`, `platform` or `client`) and `retryable`                              |
| `hints`                                                                                   | Machine-readable next steps such as `POLL_RUN`, `NEXT_PAGE`, `TOP_UP`, `DESCRIBE_TOOL`, `DISPUTE_IF_UNUSABLE` |