Automations
Automations are how you run a drip campaign, a welcome sequence, a churn recovery, a trial conversion flow — anything that looks like "when X happens, do Y, then wait, then maybe do Z."
Under the hood, an automation is a directed acyclic graph (DAG) of steps. You drag step nodes onto a canvas and connect them with edges. When a profile enters the automation, they walk through it one step at a time.
Anatomy
Every automation has:
- A trigger — what kicks it off.
- Steps — the work to do.
- A state — DRAFT (not running yet), ACTIVE (firing for new profiles), or PAUSED (stopped).
Triggers
subscription_trial— fired when a Stripe subscription entersstatus = "trialing". Most common for "new trial user" onboarding sequences.subscription_paid— fired when a subscription moves tostatus = "active". Most common for "welcome to the paid plan" sequences.stage_enter— fires whenever a profile enters any stage. Legacy trigger; prefer the subscription-specific triggers when you can.churn(coming soon) — fired when a subscription is canceled.
Step types
| Step | What it does | Config |
|---|---|---|
| SEND_EMAIL | Render blocks, enqueue an email send | Email blocks, sender, subject |
| WAIT | Pause for a fixed duration | Months / days / hours / minutes |
| WAIT_UNTIL | Pause until an event fires | Event name (e.g., email_opened), optional timeout |
| CONDITIONAL_SPLIT | Branch on a condition | Condition (e.g., email_opened == true), two output branches |
| PERCENTAGE_SPLIT | A/B split deterministically | Percent to left branch (e.g., 50 / 50) |
Status
Per-profile run state:
RUNNING— currently walking through the graph.WAITING_FOR_EVENT— parked on a WAIT_UNTIL step, waiting for the trigger.COMPLETED— reached the end successfully.CANCELLED— exited early (e.g., the profile unsubscribed, or you paused the automation).
Per-automation state:
DRAFT— not running yet.ACTIVE— new profiles enter as they match the trigger.PAUSED— no new enrollments, existing runs keep executing.
A typical automation
Trial welcome
trigger: subscription_trial
│
▼
[SEND_EMAIL: "Welcome — here's the 60-second quickstart"]
│
▼
[WAIT: 2 days]
│
▼
[SEND_EMAIL: "3 things Pro users do first"]
│
▼
[WAIT: 3 days]
│
▼
[CONDITIONAL_SPLIT: did they upgrade yet?]
│ │
▼ yes ▼ no
[SEND_EMAIL: "Glad you stuck around"] [SEND_EMAIL: "Trial ends tomorrow"]
Churn recovery
trigger: churn (or: stage_enter CUSTOMER where bucket=Churned)
│
▼
[WAIT: 7 days]
│
▼
[SEND_EMAIL: "Can you tell us why?"]
│
▼
[WAIT_UNTIL: email_opened (timeout: 7 days)]
│ │
▼ opened ▼ timed out
[SEND_EMAIL: 20% discount offer] [SEND_EMAIL: "Last chance — 30% off"]
How execution works
A cron runs every 5 minutes, picks up all RUNNING automation runs whose nextStepAt is in the
past, and advances them one step:
- SEND_EMAIL — enqueues the email (actual send happens in the email cron).
- WAIT — sets
nextStepAt = now + delay, staysRUNNING. - WAIT_UNTIL — sets status to
WAITING_FOR_EVENT. When the event fires, the run flips back toRUNNINGand continues. - CONDITIONAL_SPLIT — evaluates the condition, follows the matching edge.
- PERCENTAGE_SPLIT — hashes (automationRunId + stepId) mod 100, compares to threshold, follows the matching edge. Deterministic — the same profile always takes the same branch.
Unsubscribe and suppression
If a profile unsubscribes at any point during an automation run, their current run is
immediately marked CANCELLED. They also won't receive emails from any other campaign or
automation in the workspace — unsubscribes are workspace-wide.
Plan limits
| Plan | Automations per stage | Max step depth | Email/month |
|---|---|---|---|
| FREE | 0 | — | — |
| HOBBY | 1 | 3 | 3,000 |
| PRO | 5 | 5 | 20,000 |
"Step depth" counts unique steps along the longest path — a 3-step sequence with one split branching off is depth 3, not 4.
Next: Conversion → • Full funnel tracking →