Skip to main content
Program models long-running work as workflows. Each execution is a Workflow SDK run (wrun_...). You start (and cancel / product-resume) from domain endpoints; you read status and subscribe via the generic workflow routes.
Live subscribe is run-scoped. Stay on one wrun_... for the whole orchestration (including step retries). A new start (newest-wins) returns a new run — switch to that run’s stream_url from the start response.

Mental model

Kinds at a glance

Full chunk shapes, reconnect rules, and webhook pairing: Live updates.

What you get on create

Domain starts return 202 with the run already available. Example (programming):
Clarifications start responses include workflow_id + stream_url. Audit start responses include workflow_id on the audit resource (no stream_url — subscribe via GET /v1/workflows/{workflow_id}/stream). Content-edit returns an SSE body instead of NDJSON.

Run detail

Lean binding + World status (id, kind, status, stream_url, terminal output / error). Authz: binding must exist in the workspace (missing → 404). Domain views stay survey-scoped when the product needs them — e.g. GET .../programming (lean status + empty phases for greenfield; legacy in-flight runs may still include phased steps). Prefer workflow_id + generic GET/stream for new UIs.

Statuses

Resolving hooks

Greenfield configure gates and clarifications expose SDK hook tokens (often via anatomy resumePath). Resume with:
The JSON body is kind-specific (validated server-side). Programming also keeps product resume paths: PUT .../programming/target and PUT .../programming/template when the run is waiting on those gates. See Programming.

Cancel

Domain cancel: POST .../programming/cancel (and similar domain surfaces). Cancelling a terminal workflow returns 409.

Execution World

  • The Workflow SDK World is execution truth (steps, hooks, streams, cancellation).
  • Program Postgres stores bindings and related receipts only.
  • Hosted deployments use a durable serverless World (Upstash Redis + QStash into Nitro /.well-known/workflow/v1/*). Local development uses the Local World — no QStash required.

Webhooks (not a live socket)

Account webhooks (workflow.*, questionnaire.clarifications.updated, content.updated, …) fan out tip / lifecycle changes at-least-once. Use them for backends and reconciliation — not as a substitute for the run stream while you are attached to a wrun_.... See Webhook event types.