Runs
Receipts, long-running calls, results, stopping and pages
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.
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
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:
- Your client giving up does not cancel, refund or re-run anything. Fetch the same
run_idlater. - 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-Keyto get the original run back. - A run that passes the tool’s
max_duration_msends asTIMED_OUTand 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.
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
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.