Docs · Concepts
Templates and flows.
You don't draw flow DAGs by hand in Ciela. Every multi-channel sequence starts from one of four templates, which gets compiled into a nodes-and-edges shape the engine knows how to run. This page is the one-pager on how that pipeline works, what each piece owns, and where you actually edit what.
The shape
- Templates
lib/flows/templates.ts- Compile step
compileSequenceToFlow- Engine schema
flows+flow_enrollmentstables- Driver
- Cron tick at
/api/flows/process - Editor surface
- Omnichannel modal on the dashboard
- Source of truth
- The template you picked, customized inline
The omnichannel templates
- email-linkedin. Email opens on Day 0, LinkedIn connect Day 2, three LinkedIn follow-ups across the next two weeks, then a closing email on Day 16. Safe default when you don't know the buyer well. Drop
{{demoLink}}into any step body to have Theo auto-provision a per-prospect AI demo URL at send time. - linkedin-first. LinkedIn connect on Day 0, two LinkedIn follow-ups across the first week, then email lands Day 10 with a closer Day 14. Best for founders, agency owners, and growth roles who live on LinkedIn.
- sprint. Email Day 0, LinkedIn connect Day 1, LinkedIn nudge Day 4, repeat email Day 7, breakup LinkedIn message Day 10. Short and dense for time-bound offers, event follow-up, or warm-but-cold retargeting.
- marathon. LinkedIn connect Day 0, alternating email and LinkedIn touches every 5-7 days, closing email Day 27. Built for mid-market VPs, enterprise buyers, and skeptic agency owners on high-ACV deals.
Each template is a linear list of {kind, ...fields, days} steps. The kinds are email, linkedin_connect, linkedin_message, and wait. The first three map to Mira and Eli, the wait is a pure cooldown.
How a template becomes a running flow
- You open the Omnichannel modal on the dashboard, pick one of the four templates, and customize the copy on each step. Subjects, bodies, connection notes, all editable inline, the template just gives you a sane starting point.
- On Launch,
compileSequenceToFlowturns the linear list of steps into a{nodes, edges}graph the flow engine understands. Wait steps become wait nodes, send steps become send nodes, edges chain them in order. - The compiled flow saves to the
flowstable, status active. Every contact you selected on the campaign gets a row inflow_enrollmentswith the current node, the wait-until timestamp, and a per-row status. - The flows cron tick (driven by cron-job.org, not Vercel) hits
/api/flows/processon a schedule, the route walks every active enrollment, advances anything past its wait, fires the channel-specific send, and updates the row.
What customizing actually changes
What runtime does on its own
- Reply detection. A reply on any channel flips the enrollment to stopped, no more sends on any other step for that contact.
- Scheduled window. A flow can have a start date and an optional end date, same as a single-channel LinkedIn or email campaign. Before the start the enrollment sits idle (its wait-until is the start moment), so nothing sends early. Past the end date the cron force-completes the flow and stops every in-flight enrollment where it stands, no further steps go out. No end date means it runs until the cadence finishes.
- Graceful channel pause. Email step with no account configured logs
skipped reason:no_account_configuredand breaks the chain for that row. Account flagged auth-failed parks the enrollment until the next cron tick, by which time you've reconnected. - No silent retries. Every skip and every queue-and-retry shows up in the enrollment row, so the dashboard always tells you why a step didn't fire.
Keep reading
Need help?
Ciela can walk you through any step. Or write to support@ciela.ai and we'll jump on the connection with you.