Run flows and agents with dispatch
POST /v1/dispatch runs a flow or an agent in one request. The request body
names the target, says whether to save the flow definition and the record, and
chooses how the result comes back. The following table lists the choices and
their defaults:
Before you begin
- Create an API key that
has full access or one of the
DISPATCH:*,FLOWS:*, orFLOWS:EXECUTEpermissions. The same permissions run agents through dispatch. - Set the
RUNTYPE_API_KEYenvironment variable to your API key.
Run a saved flow
To run a flow that you saved in the dashboard, pass its ID in flow.id. Values
in inputs become variables that the flow’s templates reference as
{{variableName}}. The following TypeScript example runs a saved flow and
waits for one JSON response:
The following Python example runs the same flow:
The following cURL command runs the same flow:
Replace the following:
YOUR_API_KEY: your Runtype API keyYOUR_FLOW_ID: the ID of the saved flow, which starts withflow_
To run an inline flow definition instead, send flow.name and flow.steps
and set flowMode. For a complete inline example, see
Quickstart.
Choose a flow mode
The options.flowMode field controls what dispatch does with the flow
definition. The following table describes each mode:
Use upsert when you send the same flow definition from code on every run.
When upsert changes a saved flow, it saves the previous steps as a version
first. It refuses to overwrite a flow that was last changed outside code, such as in
the dashboard, and returns 422 with FLOW_DEFINITION_WRITE_REJECTED. To overwrite
it anyway, set options.upsertOptions.allowOverwriteExternalChanges to true.
For more information, see
Manage flows as code.
Bind the run to a record
A flow run can read a record’s fields through {{_record.name}} and
{{_record.metadata.industry}} template variables. Without a record object, the
flow runs with no record. The options.recordMode field controls how dispatch
resolves the record object. The following table describes each mode:
The following request body creates a company record and runs a saved flow
against it:
A record ID that doesn’t exist, or that your API key can’t read, returns 422
with FLOW_RECORD_UNRESOLVED. For more information about records, see
What are Records?.
Run an agent
To run an agent, send an agent object instead of a flow object and pass
the conversation in messages. To run a saved agent, set agent.agentId. To
run an agent without saving it, set agent.name and agent.model, and
optionally agent.systemPrompt. The following TypeScript example runs an
inline agent:
The following Python example runs a saved agent:
The following cURL command runs the same saved agent:
Replace YOUR_AGENT_ID with the ID of the saved agent, which starts with
agent_.
A buffered agent response carries the final text in result, plus success,
iterations, totalCost, and stopReason. To run a specific saved version,
set agent.alias or agent.versionId.
For more information, see
Agent versioning and publishing.
To decide which target fits your task, see
Choosing between a flow and an agent.
Choose a response type
Dispatch streams Server-Sent Events (SSE) unless you set
options.streamResponse to false. Flows and agents share one event
vocabulary. The kind field on execution_start and execution_complete is flow
or agent. Read text_delta events for generated text, and read the
outcome field (completed, error, or aborted) on the terminal
execution_complete or execution_error event for how the run ended. For a stream-reading example and sample
output, see Quickstart.
In the TypeScript SDK, client.dispatch.executeStream(request) returns the
streaming Response, and client.dispatch.execute(request) returns the JSON
body. In the Python SDK, client.dispatch(request) streams by default, and
stream=False returns the JSON body.
With streamResponse set to false, a flow response carries success,
status, and an events array that holds the same events as the stream. The
status is completed, paused, or failed. A paused run waits for an
approval or a tool result and carries a pausedReason. For how to continue a
paused run, see
Pause and resume on an agent dispatch.
An agent stream can end with an await event whose awaitReason is
detached while the agent keeps running. The TypeScript SDK reconnects for
you. For other clients, see
Detached streams.
Run in the background and poll for the result
To start a run without holding the HTTP connection open, send the
Prefer: respond-async header. Dispatch returns 202 Accepted with an
execution handle, and the run continues without the connection. The following
TypeScript example starts a run and polls until it finishes:
The following Python example sends the header on a dedicated client and polls the status endpoint:
The following cURL command starts the same run:
The response is similar to the following:
To check progress, send a GET request to https://api.runtype.com followed
by the statusUrl path, with the same Authorization header:
Replace YOUR_EXECUTION_ID with the executionId from the handle.
The status field is queued or running while the run is in progress. The
run ends as completed, failed, or cancelled, with the output in result
or the failure in error. A paused run waits for an approval or a tool
result, and polling doesn’t resume it. Poll the status endpoint instead of
repeating the dispatch request, because a repeated request starts a second
run.
A background run doesn’t accept inline secrets or an identity_proof, and
it allows longer flow timeouts than an attached run. For those limits and the
error codes, see
Timeouts and long-running work.
Troubleshoot dispatch errors
The following table lists the dispatch-specific errors and how to fix them:
For authentication, spending-limit, and rate-limit errors, see Quickstart.
Next steps
- Runtime tools: give a dispatched agent tools for one request
- Steer an active agent execution: send more input to a running agent
- Flow variables and templates: reference
inputsand record fields in steps - Dispatch API reference: every request field and response schema