Skip to main content
POST
Run a workflow (sync default; mode=async returns job id; mode=stream returns SSE)
The one endpoint that executes anything. Send a definition inline, or a pipeline_id for one you stored. mode decides how you get the result: sync (default) waits and returns the finished run, stream returns SSE progress events, async returns a run id immediately and you poll or take a webhook. Missing or wrongly-typed inputs are reported all at once with invalid_pipeline_input, before anything is executed or charged. Send an Idempotency-Key header to make a retry safe. See Running a workflow for the modes, resuming a failed run, and the SSE contract.

Authorizations

Authorization
string
header
required

API key in format: Bearer inf_***

Headers

Idempotency-Key
string

Replay guard, scoped to the workspace and never expired: a second run with a key already seen returns the FIRST run instead of executing again, in every mode. In stream mode a completed run is replayed as a synthetic event sequence, and a run still in flight is a 409 (idempotency_in_progress). The value is stored in a 120-character column and is not length-checked before that, so keep keys short.

Body

application/json
input
object
required

Top-level inputs referenced as ${input.X}

pipeline_id
string

Reusable workflow id (provide either this OR definition)

pipeline_version
integer

Specific version of pipeline_id (defaults to latest)

definition
object

Inline workflow definition (use instead of pipeline_id)

mode
enum<string>

Execution mode (default sync). When "stream" the response is text/event-stream.

Available options:
sync,
async,
stream
only_step_id
string

Run ONLY this step, using the outputs its upstream steps recorded on earlier runs. Requires pipeline_id, and every step it reads must already have a succeeded result. Not available with mode=async.

resume_from_run_id
string

CONTINUE THIS FAILED RUN instead of starting over: the steps it recorded as succeeded are reused, and only the step that failed and everything downstream of it runs again. A reused step is not dispatched and not billed. Send definition (or pipeline_id) alongside to fix the step that failed — swap the model, change the params, replace the step; send neither and the run is resumed against the definition it originally executed. REFUSED, before anything is billed, when: the run did not fail (resume_run_not_failed); the edit changes a step that already produced a result, which is a new run rather than a resume (resume_upstream_definition_changed); input differs from the input that run used (resume_input_changed); a reused step's artifact has since been deleted (resume_artifact_expired); the run did not record which version of the workflow it executed and the workflow has been saved since (resume_source_definition_unknown); or with mode: "async" (resume_async_unsupported) or with only_step_id (resume_with_only_step). A step with no recorded result — including one whose result was lost — simply runs again.

rerun_from_step_id
string

RUN THIS STEP AND EVERYTHING THAT DEPENDS ON IT, reusing the results of the run named by resume_from_run_id — which may be in ANY finished state (succeeded, failed or cancelled), not only failed. The step runs, every step that transitively reads its output runs, and every other step is reused from that run: not dispatched, not billed. DEPENDENCY-BASED, NOT POSITIONAL: a step declared after it that does not read it (directly or through another step) could not have a different result, so it is neither re-run nor re-billed. Send an edited definition (or pipeline_id) alongside to change what the step does — unlike a bare resume, an edit to a step that already produced a result is NOT refused here: it widens the set that runs again to include that step and everything below it, and the credit hold covers the wider set. A STEP WITH NO RECORDED RESULT ALWAYS RUNS AGAIN, which on a CANCELLED run means work that was in flight when it stopped may have been charged already and is charged again. REFUSED, before anything is billed, when: sent without resume_from_run_id (rerun_from_step_without_run); the run has not finished (rerun_run_not_finished); no step of the definition has this id (rerun_from_step_unknown); or with mode: "async" (rerun_async_unsupported). resume_input_changed, resume_artifact_expired and resume_source_definition_unknown apply here too.

Response

One of two JSON shapes, by mode: the completed run (sync), or the queued run's identity (async). With mode: "stream" the response is text/event-stream — a sequence of the named SSE events listed in the operation description above, matching NEITHER JSON schema below. OpenAPI 3.0 has no way to express a dozen distinctly-shaped named event types, so the text/event-stream entry is deliberately just {type: "string"}: an honest admission that this document cannot describe that body, not a claim that it is JSON or that it matches either schema below.

id
string
required

Run UUID.

Example:

"3c9a7e51-8b24-4f0d-9a17-6e2b5c4d8a03"

status
enum<string>
required

Terminal statuses are succeeded, failed and cancelled. queued/running are only ever seen by reading a run that has not finished. partial exists in the enum and no writer in this repo produces it — do not build on it.

Available options:
queued,
running,
succeeded,
failed,
cancelled,
partial
Example:

"succeeded"

attempt
number
required

Current run-level attempt, 1-based. Only an async run can exceed 1; sync and stream runs never retry at the run level.

Example:

1

maxAttempts
number
required

Run-level attempts configured, from the definition's retry.max_attempts clamped to 1..5. 1 for sync and stream runs.

Example:

1

creditsUsed
number
required

Credits actually settled for this run, summed from the per-step settles. This is real money spent — it is NOT the estimate, and it is not capped by one: POST /v1/workflows/estimate is a quote, and the credits_reserved figure the run row carries is written but read by nothing.

Example:

4.128

stepRuns
object[]
required

One entry per step ATTEMPT. Ordered by step id then attempt on GET /v1/workflows/runs/{id} — LEXICOGRAPHIC, not execution order — while a fresh sync run returns them in the order the runner executed them. Reading a run that is still running returns the steps written so far, including ones still running themselves.

durationMs
number
required

Wall-clock duration of the run in milliseconds. 0 when the row never recorded one.

Example:

8421

createdAt
string
required

ISO-8601 timestamp the run was created.

Example:

"2026-05-04T09:15:22.113Z"

input
object

The input the run was given, AFTER declared defaults were applied. Returned by GET /v1/workflows/runs/{id} and by an idempotent replay; ABSENT from the response of a fresh sync run, which is built from the runner's result rather than the row. {} is a real answer (the workflow declares inputs and the caller sent none) — the field is omitted, never null, when there is nothing.

output
object

The run's output, resolved from the definition's output block against the steps' results. Absent for a run that failed or was cancelled before producing one.

error
object

Present only for a failed run. A cancelled run carries no error.