Reference

Runs

One question to the agent and everything it did to answer it. Read the guide first; this page is every field.

The run object

json
{
  "object": "run",
  "id": "ac3ac707-bd85-4cf6-b438-6819ded4a5f0",
  "thread_id": "81c7954c-3f7e-4500-b8cf-7b82e35835bb",
  "status": "completed",
  "created_at": "2026-09-22T00:03:45.119Z",
  "completed_at": "2026-09-22T00:03:51.402Z",
  "error": null,
  "required_action": null,
  "output": {
    "text": "Folded — your sequence is **330 residues long**. …",
    "messages": [ { "id": "research-ac3ac707-…", "role": "assistant", "text": "…", "tool_results": [ "…" ] } ],
    "tool_results": [ { "type": "tool_result", "call_id": "call_01a0…", "tool": "fold_protein", "status": "succeeded", "input": {}, "output": {}, "files": [] } ]
  }
}
iduuid
The run.
thread_iduuid
The conversation it belongs to. Pass it to a later run to continue.
statusstring
running, cancelling, requires_action, completed, failed or cancelled. Only the first two mean the run is still going.
created_at / completed_attimestamp
ISO 8601. `completed_at` is null until the run ends.
errorobject | null
On failed: { code, message }. Codes include budget_exceeded, platform_budget_exceeded, workflow_step_timeout and lease_expired. What the run wrote before failing is still in output.
required_actionobject | null
On requires_action: { call_id, tool, input } — the waiting tool and what it asked. Answer with respond.
output.textstring
Everything the agent wrote in this run, as Markdown. Grows while the run is going.
output.messages[]message[]
The assistant messages this run produced, each with its own text and tool_results. Usually one.
output.tool_results[]tool_result[]
Every tool the run used, in order, flattened across its messages.

The tool result object

call_idstring
Identifies this call; the same id names it in the event stream.
toolstring
The tool's name, e.g. fold_protein, search_papers, run_python.
statusstring
running, succeeded, failed or requires_action. A long compute job stays running until it lands.
inputobject
What the agent asked the tool for.
outputany
What the tool returned, less anything meant only for the app's renderer. Tool-specific, and may change as a tool improves — the envelope is the contract, this is not. Null until the tool answers.
errorstring?
On failed, why.
files[]file[]
Every file the output refers to: { id, role, name?, url }. role is where in the output the file was found (structureId, figures[0].id); url is fetched with your key. See files.

Create a run

POST/api/v1/runs
inputstring
The message to send. Up to 100,000 characters.
thread_iduuid?
Continue this thread. Omitted, the run opens a new one.
approvals"manual" | "auto"
Default manual: the run stops for decisions. auto: plans and image requests are approved for you and forks are handed back to the agent; the run never stops.
Idempotency-Keyheader?
Up to 200 characters. A repeat with the same key returns the run the first request started, with 200 rather than 201.

Returns 201 and the run, normally still running. Refusals: 402 when the account cannot pay for the turn, 404 for a thread that is not yours, 409 thread_busy when the thread already has a run going, 409 idempotency_conflict when the key was used with a different request.

Read a run

GET/api/v1/runs/{id}

The run as it stands. Safe to poll every few seconds.

Stream a run's events

GET/api/v1/runs/{id}/events?after={event id}

text/event-stream. Each event has an id (its position in the run's stream), an event name and JSON data. The response ends on its own after a few minutes, or when the run ends; the last event is always run. Reconnect with after (or the Last-Event-ID header) set to the last id seen to skip what you already have. A run that has already ended returns the run event alone.

text.delta
{ text } — a piece of the answer, in order.
reasoning.delta
{ text } — a piece of the agent's reasoning, when the model exposes it.
tool.started
{ call_id, tool, input, requires_action } — a tool call began. requires_action is true for a decision the run will stop for.
tool.result
A tool answered: the same fields as a tool result object.
source
{ url, title? } — a source the model cited.
error
{ message } — something went wrong mid-run; the run event that follows says how it ended.
run
The run object. Final for this connection: if its status is still running, reconnect.

Answer a run's question

POST/api/v1/runs/{id}/respond
answerobject
The decision, in the shape the waiting tool takes — see the guide. Checked before it is recorded: a choice must be one that was offered.
call_idstring?
The required_action.call_id being answered. Optional; refused with 409 if it names a different call.
approvals"manual" | "auto"
For the run that continues.
Idempotency-Keyheader?
As for create.

Returns 201 and a new run, the one that carries on from the answer. 409 not_waiting when the run is not waiting for an answer (already answered, or never asked); the response includes the run as it stands. 400 invalid_request says what was wrong with the answer.

Cancel a run

POST/api/v1/runs/{id}/cancel

Returns the run, now cancelling; it becomes cancelled once the current step notices, usually within seconds. The agent takes no further steps; a compute job it already started may still finish, and what it had written stays in the thread. Cancelling a run that has already ended returns it unchanged.

Every request needs a key — see authentication — and the base URL is https://corollary-labs.com/api/v1.

NextThreadsList, read and delete the conversations runs belong to.