API Routes

HTTP API for managing workflows and instances.

The Workflows fragment exposes HTTP routes for workflow management. Mount the fragment under a base path (for example /api/workflows) and use that base URL in clients.

Base URL

All paths below are relative to the fragment base URL, for example:

https://your-app.example.com/api/workflows

Workflows

List workflows

GET /

Returns the registered workflow definition names.

Instances

List instances

GET /:workflowName/instances

Query parameters:

  • status (optional): active | paused | errored | terminated | complete | waiting
  • pageSize (optional, default 25, max 100)
  • cursor (optional)

Create an instance

POST /:workflowName/instances

Body:

{ "id": "optional-id", "params": { "...": "..." } }

If the workflow defines a schema, invalid params return WORKFLOW_PARAMS_INVALID.

Create a batch of instances

POST /:workflowName/instances/batch

Body:

{
  "instances": [{ "id": "required-id", "params": { "...": "..." } }]
}

A batch accepts at most 100 instances. Existing and duplicate instance IDs are skipped. If the workflow defines a schema, invalid params return WORKFLOW_PARAMS_INVALID.

Get instance details

GET /:workflowName/instances/:instanceId

Returns the instance ID, status details, workflow params, timestamps, current run generation, and the current step summary. Every status details object includes runGeneration, including create, list, management, and restart-or-create responses. New instances start at generation 1; each full restart increments it.

Get history

GET /:workflowName/instances/:instanceId/history

Returns persisted steps and events plus step emissions that are still present when the route is read:

{
  steps: WorkflowsHistoryStep[];
  events: WorkflowsHistoryEvent[];
  emissions: WorkflowsHistoryEmission[];
}

System management events are not included in the returned events array. Completed step-emission attempts are removed asynchronously by a durable cleanup hook, so emissions is not a permanent audit archive.

Restart or create

POST /:workflowName/instances/:instanceId/restart-or-create

Atomically creates a missing instance or restarts an existing instance only when its persisted status matches the explicit precondition:

{
  "create": {
    "params": { "orderId": "order-123" }
  },
  "restart": {
    "precondition": {
      "status": { "in": ["errored", "complete"] },
      "runGeneration": { "equals": 3 }
    }
  }
}

The status list must contain at least one instance status: "active", "waiting", "paused", "complete", "errored", or "terminated". The optional runGeneration.equals condition is combined with the status condition using AND, preventing a stale caller from restarting a newer run. The response action is "created", "restarted", or "unchanged". create.params and create.remoteWorkflowName apply only when the instance is missing. An existing instance keeps its original params and remote workflow name, even when the precondition matches and it restarts.

Pause / resume / restart / retry failed step / terminate

POST /:workflowName/instances/:instanceId/pause

POST /:workflowName/instances/:instanceId/resume

POST /:workflowName/instances/:instanceId/restart

POST /:workflowName/instances/:instanceId/retry-failed-step

POST /:workflowName/instances/:instanceId/terminate

Restart deletes the previous run's steps, events, and step emissions, clears its result, increments the run generation, and executes the workflow again from the beginning with the original params.

The failed-step retry route accepts an optional body:

{ "delayMs": 0 }

It accepts an errored instance when its latest top-level step is the only failed top-level step. Earlier completed top-level steps remain cached. Retrying a do step grants it one additional attempt, discards all nested step state beneath it, and reruns completed and failed nested steps. Events consumed by that subtree become pending again. Retrying a failed waitForEvent starts a fresh wait and timeout window, so pending events created before the new deadline are eligible. Nested step callbacks, external effects, event-consumption handlers, and buffered mutations can therefore run again. The run generation is unchanged, and delayMs is limited to 30 days.

Send an event

POST /:workflowName/instances/:instanceId/events

Body:

{ "id": "optional-event-id", "type": "event-type", "payload": { "...": "..." } }

Providing an event ID makes repeated delivery idempotent for the same workflow instance.

Authorization

The Workflows fragment does not add route-specific authorization hooks. Protect the mounted route with your application's framework middleware or request handler before forwarding requests to the fragment.