Run Workflow (Synchronous)
POST /api/v1/workflows/:workflowId/run — execute a published workflow and wait for the result.
Runs the currently-deployed version of a published workflow and blocks until it finishes, up to 30 seconds. For anything longer — and for any workflow containing a Human Review node — use /run-async instead.
POST /api/v1/workflows/{workflowId}/runThe workflow must be published
A run always executes the version pinned by the workflow's active deployment — never the latest
draft. An unpublished workflow returns 409 workflow_not_published. See
Publishing.
Path parameters
| Parameter | Type | Description |
|---|---|---|
workflowId | string (UUID) | The workflow to run. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
input | object | No | Arbitrary JSON object passed to the run. Defaults to {} — an omitted body is legal. Validated against the fields declared on the graph's HTTP Request trigger, if it declares any. |
The input object is what {{ trigger.* }} reads inside the graph: {"input": {"orderId": "A-1001"}} makes {{ trigger.orderId }} resolve to "A-1001".
There is deliberately no versionId field. Letting a caller name a version would be a way to run unpublished work.
{
"input": {
"orderId": "A-1001",
"priority": 2
}
}Response
200 OK
{
"executionId": "8f2a1c9e-...",
"workflowId": "3f9c1a2e-...",
"status": "completed",
"output": { "summary": "Order A-1001 approved." },
"error": null,
"createdAt": 1732550123
}| Field | Description |
|---|---|
executionId | The run's durable id. Use it with GET /workflow-jobs/:jobId. |
status | One of the four terminal statuses below. |
output | The output of the node(s) that terminated the executed graph — see below. null if none completed. |
error | Why the run failed, or null. |
createdAt | Unix seconds, when this API accepted the run. |
What output contains
output is derived from the graph, not assembled by a node you place — Elizon takes the nodes that terminate the path the run actually walked (no outgoing edge, completed):
- One — its own output, unwrapped. Any JSON value, not necessarily an object.
- Several — an object keyed by node id.
- None —
null.
Note nodes and the nodes inside a Loop's body never count. See Building a workflow.
Terminal statuses
status | Meaning |
|---|---|
completed | Every node finished successfully. |
failed | A node errored, or a node never became reachable. error names the node ids. |
loop_limit_reached | A Loop node stopped on its iteration ceiling. Not a failure — error is null and output is real. |
policy_blocked | A budget or policy cap rejected the run before any node ran. Not a failure — error is null. |
loop_limit_reached and policy_blocked are never collapsed into completed or failed. Handle them as their own outcomes.
Timeout behaviour
If the run hasn't finished within 30 seconds:
504 Gateway Timeout
{
"error": "execution_timeout",
"message": "Workflow execution exceeded the 30 s limit. Use /run-async for long-running tasks.",
"executionId": "8f2a1c9e-..."
}The run is not cancelled
Unlike POST /agents/:agentId/run, which cancels its upstream run on timeout,
a timed-out workflow run keeps executing. It has a durable record, streams node status into
Studio's Activity tab, and meters its own usage — throwing away 30 seconds of already-billed work
would be worse than letting you collect it. That is what the executionId in the 504 body is
for: poll GET /workflow-jobs/:jobId with it. Cancel
explicitly via POST /workflow-jobs/:jobId/cancel if you
don't want it to continue.
Errors
| Status | error | When |
|---|---|---|
400 | validation error ({ "errors": [...] }) | The request body fails validation |
403 | forbidden | The workflow belongs to a different project than your project-scoped key |
404 | workflow_not_found | No such workflow in your organization (also returned for a deleted one) |
409 | workflow_not_published | The workflow has no active deployment |
429 | concurrency_limit_reached | Your organization is at its concurrent-run ceiling. Body includes the rejected run's executionId. |
500 | execution_create_failed | The run record could not be created |
502 | bad_gateway | The workflow engine was unreachable — nothing was started |
504 | execution_timeout | The run didn't finish within 30 seconds (it continues in the background) |
A workflow in another organization returns 404, never 403, so workflow ids cannot be enumerated by status code.
Example
curl -X POST https://api.elizon.com/api/v1/workflows/{workflowId}/run \
-H "X-API-Key: elz_your_key_here" \
-H "Content-Type: application/json" \
-d '{"input": {"orderId": "A-1001"}}'