Triggers & Scheduling
A trigger is what kicks a flow off without a human invoking it. A flow can have multiple triggers — fired by a cron at 09:00 and by a webhook on demand and by a file landing in an SFTP directory. The flow body does not change based on which trigger fired it; the difference shows up only in the source payload key, which any step can read.
Trigger types
Section titled “Trigger types”| Type | Fires when… |
|---|---|
| Cron | A cron schedule is due. |
| Webhook | An HTTP request hits the flow’s webhook endpoint. |
| AWS SQS | A message arrives on an SQS queue. |
| A matching message arrives in a watched mailbox (IMAP/POP3). | |
| Filesystem watch | A file appears/changes in a watched directory (local or SFTP). |
| Log monitor | A configured log pattern matches. |
| Flow-to-flow | Another flow calls this one — see Composing Flows. |
Each trigger is named, typed, and parameterised independently.
Cron scheduling
Section titled “Cron scheduling”The simplest scheduling form is a top-level schedule: field with a standard 5-field cron expression:
name: daily-reportschedule: "0 9 * * *" # every day at 09:00
steps: - $report: invoke: http.get with: Url: "https://api.example.com/daily-report" - return: value: "${report.body}"Cron syntax
Section titled “Cron syntax”┌───────────── minute (0-59)│ ┌───────────── hour (0-23)│ │ ┌───────────── day of month (1-31)│ │ │ ┌───────────── month (1-12)│ │ │ │ ┌───────────── day of week (0-6, Sunday=0)* * * * *Special characters: * (any), , (list), - (range), / (step).
| Pattern | Expression |
|---|---|
| Every 15 minutes | */15 * * * * |
| Daily at 9 AM | 0 9 * * * |
| Weekdays at 8 AM | 0 8 * * 1-5 |
| Monday at 6 AM | 0 6 * * 1 |
| First of month, midnight | 0 0 1 * * |
| Every 6 hours | 0 */6 * * * |
Scheduler behaviour
Section titled “Scheduler behaviour”- Cron is evaluated in the system timezone.
- Scheduled flows invoke with no parameters — only system params (
invocation-id,flow-name) are present. - One schedule per flow — use a single cron expression. (For multiple firing patterns, use the richer
triggers:block.) - The scheduler picks up changes automatically; remove the
schedule:field to unschedule.
The triggers: block
Section titled “The triggers: block”For non-cron triggers (and multiple triggers on one flow), use a triggers: block. Each entry is named and typed:
triggers: nightly: type: cron schedule: "0 2 * * *" on-upload: type: filesystem on: drop-zone # a connection alias path: "/incoming/*.csv" on-demand: type: webhookAny step can branch on which trigger fired by reading ${source}:
- if: "source.type == 'webhook'" do: - log: "Triggered on demand by ${source.caller}"Health-check pattern
Section titled “Health-check pattern”A scheduled flow that alerts on failure combines cron, retry, and messaging:
name: health-checkschedule: "0 * * * *"
steps: - $check: invoke: http.get with: { Url: "https://api.example.com/health" } retry: { maxAttempts: 3 } - if: "check.body.status != 'healthy'" do: - $alert: invoke: notify.send with: { Message: "Health check failed: ${check.body.status}" }