Workflows & durable runs
Workflows & durable runs
The Workflows API publishes versioned workflow definitions and starts durable runs against them. A run survives process restarts and can wait for external input — an approval, a webhook, a long-running job — then resume exactly where it left off. Use it to orchestrate multi-step processes you need to track, pause, retry, and audit, rather than fire-and-forget jobs.
Concepts
| Term | Meaning |
|---|---|
| Definition | A named workflow, identified by workflowKey within a namespace. |
| Revision | An immutable, numbered snapshot of a definition's graph. Publishing never overwrites a revision — it adds a new one. |
| Run | A durable execution of one revision. Runs persist their state and event history, so they resume after an interruption instead of restarting. |
| Artifact | An immutable piece of data attached to a run — its input, an intermediate result, or output. Capped at 256 KiB of UTF-8 text. |
| Wait node | A point in the graph where a run pauses until a matching event arrives. |
Publish a definition
Publishing adds a new immutable revision; it never edits or deletes an existing one.
curl -sf -X POST "https://api.falcata.io/api/v1/workflows/definitions/$WORKFLOW_KEY/revisions" \
-H "Authorization: Bearer $FURNACE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"namespace":"'"$NAMESPACE"'","definition":'"$(cat definition.json)"',"expectedLatestRevision":0}'
expectedLatestRevision guards against a concurrent publish: pass 0 to require this be the first revision, or the current revision number to prevent overwriting someone else's publish. Optional fields: displayName, description, and retentionDays (default 30, range 1–365).
List definitions and fetch one revision:
curl -sf "https://api.falcata.io/api/v1/workflows/definitions?namespace=$NAMESPACE&limit=50" \
-H "Authorization: Bearer $FURNACE_TOKEN" | jq '.data'
curl -sf "https://api.falcata.io/api/v1/workflows/definitions/$WORKFLOW_KEY/revisions/$REVISION?namespace=$NAMESPACE" \
-H "Authorization: Bearer $FURNACE_TOKEN" | jq '.data'
Start a run
A run always executes a specific revision — the latest published one, unless you pin revision. Give it an initial artifact as input.
curl -sf -X POST "https://api.falcata.io/api/v1/workflows/runs" \
-H "Authorization: Bearer $FURNACE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"namespace":"'"$NAMESPACE"'","workflowKey":"'"$WORKFLOW_KEY"'","initialArtifact":{"contentType":"text/plain","text":"..."},"idempotencyKey":"'"$START_KEY"'"}'
The response is 201 for a newly created run, or 200 if idempotencyKey matches a run you already started — safe to retry a start call without risking a duplicate run.
Check status and history
Runs are durable, so polling is the normal way to track progress — there's no push stream yet.
curl -sf "https://api.falcata.io/api/v1/workflows/runs/$RUN_ID" \
-H "Authorization: Bearer $FURNACE_TOKEN" | jq '.data'
curl -sf "https://api.falcata.io/api/v1/workflows/runs/$RUN_ID/events?limit=100" \
-H "Authorization: Bearer $FURNACE_TOKEN" | jq '.data'
Status is one of queued, running, waiting, completed, failed, or canceled. List runs with optional workflowKey and status filters:
curl -sf "https://api.falcata.io/api/v1/workflows/runs?namespace=$NAMESPACE&status=waiting&limit=50" \
-H "Authorization: Bearer $FURNACE_TOKEN" | jq '.data'
Send an event to resume a wait
When a run pauses at a wait node, send the named event it's waiting for to resume it. The idempotency key is required — there's no free-standing retry-without-a-key path for events.
curl -sf -X POST "https://api.falcata.io/api/v1/workflows/runs/$RUN_ID/events" \
-H "Authorization: Bearer $FURNACE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"nodeId":"approval","eventName":"approved","artifact":{"contentType":"text/plain","text":"..."},"idempotencyKey":"'"$EVENT_KEY"'"}'
Like starting a run, this returns 201 for a new delivery and 200 for a retried one with the same idempotency key.
Cancel or restart a run
Cancel stops a run outright. Restart only applies to a failed run, and only from a parallel node the definition declared — it can't jump to an arbitrary step.
curl -sf -X POST "https://api.falcata.io/api/v1/workflows/runs/$RUN_ID/cancel" \
-H "Authorization: Bearer $FURNACE_TOKEN"
curl -sf -X POST "https://api.falcata.io/api/v1/workflows/runs/$RUN_ID/restart" \
-H "Authorization: Bearer $FURNACE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"parallelNodeId":"review-fanout","idempotencyKey":"'"$RESTART_KEY"'"}'
Read an artifact
Fetch any artifact by ID — the initial input, or output a run produced along the way.
curl -sf "https://api.falcata.io/api/v1/workflows/artifacts/$ARTIFACT_ID" \
-H "Authorization: Bearer $FURNACE_TOKEN" | jq '.data'
Everything else — pagination limits, definition schemas, and full field-by-field responses — is in the full reference.