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_enrollments tables
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

  1. 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.
  2. On Launch, compileSequenceToFlow turns 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.
  3. The compiled flow saves to the flows table, status active. Every contact you selected on the campaign gets a row in flow_enrollments with the current node, the wait-until timestamp, and a per-row status.
  4. The flows cron tick (driven by cron-job.org, not Vercel) hits /api/flows/process on 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

You're editing the steps before compile, not the compiled graph. That means you can change copy, change wait days, toggle AI mode on a step (so the writer drafts dynamically at send time instead of using static text), even add a phone number or assistant id per step. You don't move steps around or branch the flow, that's intentional, it keeps the engine boring and the campaigns predictable. If you need a fundamentally different shape you pick a different template.

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_configured and 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.

Ask Ciela