Start with the schema.
GET /api/v1/workflows/schema returns every trigger and node type with its provider, the config fields each needs, the outputs it exposes to later nodes, plan requirements and the graph rules.Scopes
Endpoints
Building a graph
Nodes may carry akey of your choosing so edges can reference them before they have ids; ids are assigned on save. trigger_config mirrors the trigger node ({ provider, form_id } for form triggers) and is derived from it when omitted.
Publishing, pausing, resuming
A workflow is created as a draft.PATCH with { "status": "active" } validates the graph (missing config, unconnected nodes, plan limits), publishes it and starts running it on its trigger; the response carries the validation problems when it is not ready. Edits to an active workflow are saved as a draft (has_unpublished_changes: true) until status: "active" is sent again. { "status": "paused" } stops new runs; sending "active" again resumes it, and process_queue (all, skip, none) says what happens to submissions queued while it was paused.
Pass expected_updated_at (the updated_at you last read) with a PATCH to have the save refused with 409 conflict when someone changed the workflow meanwhile.
Running
POST /api/v1/workflows/:id/run with contact_ids starts one run per contact (the trigger must be Contact Added or Form Submission); the same contact_ids with the same idempotency_key never run twice. With trigger_data the workflow runs once with that data; the response carries a trigger_key, and GET /api/v1/workflows/:id/runs?trigger_key=... finds that run. Both respond 202: runs execute in the background, so poll the run for its status and per-node steps. Runs can send email, call integrations and change CRM data.
CRM API
The objects workflows create and update
MCP tools
The same operations as MCP tools