Skip to main content
A workflow is a graph document plus a set of triggers. Both are replace-sets: every write sends the complete desired state, and anything you leave out is deleted. Read first, change what you mean to, send the whole thing back. The product-side walkthrough is Workflows. This page covers what the contract can’t tell you. Activation, runs, and run history are shown here as sumcli commands, which handle the optimistic-concurrency and confirmation flags for you.

POST /v1/workflows

Create a workflow from a graph document.
A 403 here usually means the workflows API is not open for the tenant, not that your request is malformed. Access to workflows in the app does not by itself open the API.

Schedule

In the graph, this is the Schedule node: summation.trigger.schedule/v1. Its own config is empty; the cadence itself lives in the request’s triggers array, alongside the graph. The node says that the workflow is scheduled, and the trigger row says when. The two halves have to agree: include the schedule trigger node exactly when the request also carries triggers, or the write is refused.
Cadence type is one of cron, interval, one_time, daily, weekly, biweekly, monthly, month_end, or yearly, with the matching fields set (days_of_week in UPPERCASE for weekly and biweekly, cron_expression for cron, every_minutes for interval).
Triggers are a full replace-set on every write. A workflow’s triggers are exactly the ones the request carries; any you omit are deleted along with their backing schedule. Echo back the id of every trigger you mean to keep.
Only schedule triggers can be created through the API today.

Playbook

In the graph, this is the Run playbook node: summation.playbook.run/v1. Config: playbook_file_id (required), params, output_ids.

Delivery

Create a workflow

POST /v1/workflows

Create a workflow from a graph document.
The graph is the full desired document on every write, not a patch: what you send replaces what is stored. It must contain a trigger node wired to the first work node:
Get playbook_file_id from GET /v1/projects/{project_id}/playbooks. The document serializes to at most 200,000 characters. Graphs authored through the API are adopted by the web editor, which normalizes them on its next save.

Activate, then run

expected_revision is optimistic concurrency: pass the revision from your last read and the write is refused if the workflow moved on in between. This matters because triggers and the graph are replace-sets: without it, two concurrent edits silently lose one. To run one immediately, outside its schedule:
Both activate and run require --confirm, because both send real email and Slack to the recipients the graph names. Activating starts the cadence; running executes the delivery steps now.
Pass --request-id <uuid> to make a run idempotent: retry with the same value and you get the same run, not a second one. A run needs an activated version; the CLI reads activeVersionId for you when you omit --version.

Watch what happened

A run is pending, dispatched, running, then succeeded, failed, canceled, or timed_out. Each node in the run reports its own status, and a node that never ran reads skipped with the reason it was passed over.