Runs, progress and cancellation.
Submit API runs from saved or inline graphs, observe their lifecycle, cancel work, recover uncertain submissions, and retain the outputs you need.
Interactive API reference Explore endpoints, request schemas and responses. Opens in a new tabA public API run is one asynchronous execution of a graph. POST /api/v1/runs
returns 202 Accepted with a run record, rather than waiting for the final
result. Store its id so you can observe that attempt without submitting
the work again. For canvas controls, use Runs in Studio.
All paths below are relative to /api/v1. Creating and canceling require
runs:execute; reading a run or its events requires runs:read. Runs are
account-owned, not restricted to the individual API key that created them.
Another suitably scoped key for the same owner can read the run. Station
visitor runs are exposed through the Station rather than these run routes.
Track work after the request returns
Create work once from a saved project or inline graph and retain its run identity. Inspect queued, running and terminal states plus any available results. Cancel requests do not reverse provider work. Applying outputs is a separate guarded write for a succeeded saved-project run: use expectedVersion equal to run.projectVersion while the project still matches. Public run details expose source identifiers, not a retrievable graph snapshot body.
Only the succeeded branch of a saved-project run reaches guarded project application. Failed and canceled branches retain available evidence. Inline execution has no saved project to apply to.
Submit a precise request
Provide exactly one source:
| Source | Request fields | Targeting |
|---|---|---|
| Saved project | projectId |
Explicit targetNodeIds, or the saved graph's execution configuration when omitted |
| Transient inline graph | graph |
At least one targetNodeIds entry is required |
Use explicit targets when your application needs predictable intent. An inline graph run does not create a saved project. The server snapshots the graph document before dispatch, so subsequent project edits do not change that attempt's graph. Referenced files and external services still have to be available; the snapshot is not a promise to archive those dependencies.
inputOverrides are keyed by node instance ID, then input pin name:
{
"projectId": "project_example",
"targetNodeIds": ["prompt_node"],
"inputOverrides": {
"prompt_node": {
"inputPrompt": { "type": "string", "value": "a lighthouse at dusk" }
}
}
}
The IDs and pin names must exist in your graph; this example is illustrative.
Supported value tags are string, number, boolean, json, file, and
null. A file value uses fileId instead of value. These are transport
tags, separate from canvas pin types. Overrides affect this run without editing
the saved project; persistInputOverrides: true is currently unsupported.
See Projects and graph documents for graph
structure and validation.
Retry submissions safely
Use Idempotency-Key on supported submission endpoints. Keep the same key and
same request when recovering from an uncertain network result. Changing the
request needs a different logical submission; reusing a key with conflicting
content is an error.
An idempotency replay can return the original accepted response. Read the run detail to learn its current status. A key is not an unlimited promise that every failed, expired, or canceled job can be repeated without cost. Inspect the recorded run before deciding to start a new attempt.
Follow the lifecycle
Use GET /runs/{id} for current status and results:
| Status | Meaning |
|---|---|
accepted |
A validated run record exists and work is being dispatched. |
queued |
Execution has been claimed or queued; completion is still pending. |
running |
The execution layer is working on the graph. |
succeeded |
The attempt finished successfully; inspect its outputs. |
failed |
The attempt ended in error; inspect error and events. |
canceled |
The attempt stopped; do not assume it produced every requested output. |
The last three states are terminal. A client polling slowly can miss short intermediate states. Failure or cancellation can happen before execution starts.
For detailed observation, poll GET /runs/{id}/events or stream
GET /runs/{id}/events/stream using Server-Sent Events. Events include an id,
runId, type, and createdAt; nodeId, progress, and message are optional.
Types include run.accepted, node.progress, and node.log. Progress, when
present, is between 0 and 1.
Polling returns data, nextCursor, and hasMore. Treat cursors as opaque.
Resume SSE with the last SSE id in Last-Event-ID, or the cursor query
parameter. Reuse a cursor only for the same run and API key owner that issued it.
Use structured error information and retain the run ID for support. Back off after rate limiting and avoid unbounded polling loops.
Request cancellation
POST /runs/{id}/cancel returns the updated record. If the run is still
accepted or queued, cancellation makes it terminal immediately. If it is
running, the request sets cancelRequested and the execution layer attempts
to stop it. Keep observing the final status: cancellation can race with
completion, and it cannot recall provider work already accepted externally.
Canceling an already canceled run returns that record. A succeeded or failed run cannot be canceled and returns a conflict. Cancellation is not a refund guarantee and may leave partial outputs.
Read the cost
Terminal records report creditsUsed when reliable accounting is available.
creditsUsedMicrocredits is the exact amount in millionths of a credit,
encoded as a string. The optional spend summary breaks usage down by node,
provider, and charge type.
creditsUsed is null while active. It can also be null on a terminal run when
a reliable summary is unavailable. Treat null as unknown, never as zero.
A failed or canceled attempt may still have incurred charges. These fields
describe actual recorded usage, not a price estimate for another attempt.
Apply results to a saved project
A run's outputs and a saved project's contents are separate. To retain the
server-owned outputs of a succeeded saved-project run in that project, call
POST /runs/{id}/apply-to-project. Inline runs cannot use this operation.
The key needs all three scopes: runs:read, projects:write, and graphs:write.
Send expectedVersion equal to the run's projectVersion. You may supply an
outputKeys subset; omit it to apply all recorded outputs. The endpoint accepts
output selection, not client-supplied output values. Use an Idempotency-Key
for a retryable application request.
If the saved project has changed since the run was created, application fails
with a conflict instead of overwriting newer work. Inspect the current graph
and rerun the intended version before applying results. A successful application
returns the new project version, appliedOutputs, and outputKeys.
Keep output files
Use the public file workflow to upload or register supported inputs, then pass their file IDs. Result metadata can supply a short-lived download URL. Download what your application needs before it expires, or request a fresh authorized download through the file API.
Check ownership and any external-user guards on file references. A bare file ID is not proof that an application user should have access to that file. Run retention, library retention, and a downloaded copy are separate lifecycles.
The API reference (opens in a new tab) defines the current request fields, response schemas, errors, and limits.
Preserve the attempt and its snapshot
Accept: POST /runs returns an attempt ID and snapshots its source; it is not the final result. Observe: use that run's status/events and distinguish succeeded, failed, or canceled with unknown cost kept unknown. Apply: server-recorded outputs can be applied through a separate version-guarded action where eligible. Temporary URLs and saved-project state are different.
Checks and next steps
Saved-project run submission loads the project and retains an execution
snapshot internally. It does not accept a document-write-style
expectedVersion guard. Keep the returned sourceType, projectId,
projectVersion and targets for provenance. Public run details do not return
the snapshot body or a snapshot download route, and projectVersion is not
a certificate of exact bytes during concurrent writes.
For caller-controlled source, retain and submit a supported explicit inline graph. That still does not freeze provider implementations, external services or file lifetimes. A previous saved-project read does not lock submission.
Applying outputs later is a separate version-guarded action. It requires a successful saved-project run, the necessary write scopes, and a compatible unchanged project context. A run result, a temporary media URL, a saved graph, and outputs adopted back into that graph are distinct facts.
If output application reports an unresolved or unavailable project save state, preserve the result and local work. Follow guarded project recovery instead of treating every refusal as a retryable stale version.
For upload and retention contracts see Files and outputs. For an uncertain submission, inspect the original run with its ID and preserve the same logical retry key before considering another paid attempt.
Last reviewed against Kaitoi on 24 October 2026. View this page as Markdown