Skip to content

Your first workflow

Automations are workflows: a graph of nodes on the /workflows canvas. A trigger node says when it fires, the nodes after it say what happens, and every edge carries the same item shape.

This page replaced “Your first job”. The one-off Job engine it described is deleted — see Automation architecture for what runs work now.

  1. Open /workflows and create a workflow. It is saved inactive, so nothing fires while you are still drawing.
  2. Drop a trigger. trigger.schedule takes a cron; trigger.event waits for a domain event; trigger.manual only ever fires from the Run button.
  3. Drop the work after it and connect them. The palette shows only what this deployment can actually run — a node whose integration is not configured is not offered, rather than offered and failing at run time.
  4. Activate it. A workflow with an unrunnable graph, no trigger, or an invalid cron is refused with the reason, not silently left off.

The Run button fires it immediately, whatever its trigger says. Every fire writes a run row before it starts — so a run that is still waiting is visible as queued with its position, rather than looking like a button that did nothing.

const { runId } = await client.workflows.run(workflowId)
const run = await client.workflows.getRun(workflowId, runId)
run.status // queued | running | completed | failed | cancelled
run.nodes // per node: status, counts, message, a capped output sample
run.error // the sentence to show a human, on a failed run

Stop one with client.workflows.cancelRun(workflowId, runId). Cancellation is cooperative: the executor reads it between nodes and polls during one, so a node already past its own write may still finish.

await client.workflows.list()
await client.workflows.listNodes() // the palette, per deployment
await client.workflows.listTemplates() // clone-able starting points
await client.workflows.listRuns(workflowId)

Templates are the fastest start: clone one, change what it points at, activate.