Executions
Executions run a deployed workflow. Every route below is 503 if no
workflow runtime is configured for this deployment.
Start an execution
POST /projects/{project}/executions
Body: { "workflow": "<name>", "env": "<env>", "input": { ... } }
curl -sS -X POST "$RULEFLOW_API/api/projects/lending/executions" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-H "Idempotency-Key: loan-app-2026-07-21-0001" \
-d '{ "workflow": "loan_application", "env": "dev", "input": { "credit_score": 780 } }'
{ "id": "exec_88df...", "workflow": "loan_application", "env": "dev", "status": "RUNNING", "startedAt": "2026-07-21T18:05:00Z" }
workflow and env are required; a workflow not deployed to that
environment returns 404. Starting an execution reserves a monthly
execution slot against the tenant’s quota (429 if exhausted — see
Usage & quotas) and records one workflow_execution unit of
metered usage, best-effort, before calling into the runtime.
Idempotency
Pass an Idempotency-Key header. A retry with the same key and the same
request re-attaches to the original execution instead of starting a second
one. Reusing a key with a different request body returns 409:
{ "error": "idempotency key reused with a different request" }
Omitting the header starts a fresh execution every call — there is no
implicit dedup on (workflow, env, input).
Observe
| Method & path | Description |
|---|---|
GET /projects/{project}/executions | List this project’s executions, newest first |
GET /projects/{project}/executions/{executionId} | Get one execution merged with live status + history |
GET /executions/search?q=&status=&workflow=&env=&from=&to= | Tenant-wide search across projects |
POST /projects/{project}/executions/reindex | Backfill the search index from stored executions |
curl -sS "$RULEFLOW_API/api/projects/lending/executions/exec_88df..." \
-H "Authorization: Bearer $TOKEN"
{
"execution": { "id": "exec_88df...", "status": "RUNNING", "startedAt": "2026-07-21T18:05:00Z" },
"history": [ { "...": "per-state Step Functions history events" } ]
}
GetExecution always re-pulls live status from the runtime (poll-based, not
push) — the stored record and the live description are merged on every
read.
Human tasks
| Method & path | Description |
|---|---|
GET /projects/{project}/executions/{executionId}/tasks | List pending human tasks for this execution |
POST /projects/{project}/executions/{executionId}/tasks/{stepId}/complete | Resume a paused human task |
curl -sS -X POST \
"$RULEFLOW_API/api/projects/lending/executions/exec_88df.../tasks/review/complete" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{ "output": { "signedOffBy": "underwriter-42" } }'
{ "status": "ok" }
Body: { "output": { ... }, "fail": false, "cause": "" } — all optional; an
empty body is valid. Set "fail": true (with an optional "cause") to fail
the task instead of completing it, which routes to the step’s catch branch
if the author declared one. Completing a step with no pending task for that
id returns 404.
Authorization: if the task has an assignee set, only that assignee (by
token subject) or a caller holding approver/admin may complete it —
otherwise 403. Unassigned tasks can be completed by any authenticated
member of the tenant.