Flows
Flows are CairnCMS’s automation primitive. Each flow runs a sequence of operations in response to a trigger, with the ability to read or write data, send email and notifications, transform values, branch on conditions, call external services, and chain to other flows.
Most use cases that would otherwise require a separate background worker, cron daemon, or external orchestrator can be expressed as a flow. Everything in a flow runs server-side; nothing runs in the user’s browser.
What is a flow?
Section titled “What is a flow?”Each flow has three parts:
- a trigger that defines when the flow runs
- one or more operations that do the work
- a data chain that operations read and write as the flow progresses
Flows are configured under Settings > Flows in the app.
Triggers
Section titled “Triggers”A trigger is the entry point for a flow. CairnCMS supports five trigger types:
- Event hook — fires when something happens in the platform (item created, item updated, user logged in, and so on). Filter triggers can transform or veto the event; Action triggers run after the event is committed.
- Webhook — fires on an incoming HTTP request to a flow-specific URL.
- Schedule (cron) — fires on a cron schedule.
- Another flow — fires from a Trigger Flow operation in another flow. This is how flows compose.
- Manual — fires when a user clicks a button in the app on a collection or item page.
The full list of trigger types and their configuration is on the Triggers page.
Operations
Section titled “Operations”An operation is one step inside a flow. Operations cover three broad jobs:
- read data from CairnCMS or an external service
- process data by transforming, validating, or branching on it
- write data back to CairnCMS or send it to an external service
Built-in operations include item CRUD, condition branching, sending email and notifications, calling external URLs, sleeping, transforming payloads, running custom scripts, and triggering other flows. Custom operations can also be added through the extension system.
The full list of operations and their configuration is on the Operations page.
The data chain
Section titled “The data chain”Every flow runs against a single JSON object called the data chain. As each operation finishes, it appends its result onto this object under its operation key. Subsequent operations can then reference earlier results.
Four keys are present from the start of every flow:
$trigger— data generated by the trigger (the event payload, the webhook body, the manual selection, and so on)$accountability— context about who or what initiated the flow (user, role, IP address, user agent)$env— environment variables exposed to flows through theFLOWS_ENV_ALLOW_LISTconfig option$last— the result of the most recently completed operation
Each operation also writes under its own key, named after the operation:
{ "$trigger": { }, "$accountability": { }, "$env": { }, "$last": { }, "fetch_user": { "id": "abc", "name": "Alex" }, "send_email": null}null is appended for operations that complete without producing a value (sending email, logging to console, sleeping, and so on).
Data chain variables
Section titled “Data chain variables”Operations reference earlier values using double-mustache syntax:
{ "to": "{{ fetch_user.email }}", "subject": "Welcome, {{ $trigger.payload.name }}"}Dot notation traverses nested objects. Array indexing also works: {{ items[0].title }}.
The mustache syntax substitutes values; it does not evaluate expressions. For computation, use the Run Script operation.
Most configuration fields support data chain variables, including dropdowns, toggles, and other inputs once you enable the raw editor on that field.
Control flow
Section titled “Control flow”Operations can succeed or fail. Each operation has two outgoing paths:
- the success path runs the next operation if this one succeeded
- the failure path runs a different operation if this one failed
This lets a flow branch on the outcome of a single operation. Failures do not automatically stop a flow . They redirect to the failure path. A flow ends only when it reaches an operation with no path defined for its outcome.
The Condition operation is the most common way to branch deliberately: it always runs, evaluates a filter rule against the data chain, and routes execution to the success or failure path based on the result.
Every flow with logging enabled records each run. Logs are reached from the section on a flow’s page in the app. Each log shows:
- the trigger options and payload
- the accountability context
- each operation’s options and the value it appended
$last is not stored separately in logs. It is always equivalent to the last operation’s payload.
Logs are written to the database. Long-running deployments with high-frequency flows should periodically prune log records.
Creating a flow
Section titled “Creating a flow”The basic workflow is the same regardless of trigger type:
- Go to Settings > Flows and create a new flow.
- Choose a trigger and configure it.
- Add operations, connecting each one to the success or failure path of the previous operation.
- Save and test.
Each operation is added by clicking the success or failure connector on the previous operation. Operations can also be duplicated, copied between flows, repositioned, and unlinked or relinked through the flow editor.
Where to go next
Section titled “Where to go next”The next two pages cover the full reference of trigger types and operations:
- Triggers covers each trigger type and its configuration.
- Operations covers each built-in operation, what it does, and what it appends to the data chain.
For sending and receiving HTTP requests, see the Webhooks page.