surface

Runs.

A run executes a graph, from a saved project or from an inline graph you send with the request. Runs are asynchronous, observable while they happen, and report what they cost.

Written for
Anyone executing Kaitoi work from code rather than from the canvas.
You need
A Kaitoi API key with the runs:execute scope; A node type or saved project to execute

A run is one execution of a graph. You create it, it goes away and works, and you find out what happened by polling it or by streaming its events.

Creating a run returns 202 Accepted, not the result. Anything that generates media takes longer than a request should stay open for, so the API does not pretend otherwise.

Two sources, one lifecycle

A run executes either a saved project or an inline graph:

{ "projectId": "proj_..." }
{ "graph": { "nodes": [ ... ] }, "targetNodeIds": ["a"] }

Send one or the other. An inline graph run must name at least one target node, because there is no saved default to fall back on. A saved-project run may omit targetNodeIds and let the service pick the project's default target.

Either way the server snapshots the graph it is about to execute before it starts. A run is not affected by edits made to the project while it is in flight.

Status

A run moves through a small set of states:

Status Meaning
accepted The request was validated and the run exists.
queued Waiting for capacity.
running Executing.
succeeded Finished, outputs available.
failed Finished, error populated.
canceled Stopped before finishing.

succeeded, failed and canceled are terminal. Nothing leaves them.

Cancellation is a request rather than a guarantee of immediacy. A run in accepted or queued becomes terminal straight away, because nothing has started. A run already running is marked cancelRequested and stops at the next safe point, which avoids leaving a half-written output behind.

Watching a run

Two ways, same events underneath.

Poll GET /runs/{id}/events when you want a simple loop and do not need to react within a second. Stream GET /runs/{id}/events/stream for Server-Sent Events when you are driving a UI.

Events carry a stable type such as run.accepted, node.progress or node.log, an optional nodeId, an optional progress number, and a createdAt. The SSE id is an opaque cursor: send it back as Last-Event-ID to resume a dropped stream without replaying everything or missing anything.

Cursors are only valid for the same run and the same key that issued them.

Inputs without editing the project

inputOverrides sets input values for a single run without changing the saved project. It is keyed by node id, then by input name, and each value declares its own type:

{
  "projectId": "proj_...",
  "inputOverrides": {
    "prompt_node": {
      "text": { "type": "string", "value": "a lighthouse at dusk" }
    }
  }
}

The available types are string, number, boolean, json, file and null. A file override references a file id from the Files API rather than carrying bytes.

This is what makes one saved project serve many end users. The project is the template; the overrides are the request.

Cost

When a run reaches a terminal state it reports what it actually cost, in credits, as creditsUsed, with creditsUsedMicrocredits carrying the exact figure in millionths of a credit for anything that needs to reconcile precisely.

creditsUsed is null while a run is active. It can also be null on a terminal run where a reliable figure could not be produced, so treat null as "unknown" rather than as zero.

Keeping the result

A succeeded run's outputs are on the run. If it was a saved-project run and you want those outputs written back into the project, call POST /runs/{id}/apply-to-project. The server persists its own outputs; the endpoint does not accept output values from the client.

Retries

POST /runs accepts an Idempotency-Key header. Send one. A network timeout on run creation is otherwise indistinguishable from a success you did not hear about, and retrying without a key starts a second run that costs real money.

Current limitations

  • Runs are per-account. A run is only readable by the key owner that created it.
  • There is no run-level webhook yet. Observation is polling or SSE.

Last reviewed against Kaitoi on 16 September 2026. View this page as Markdown

Type at least two characters.