Batch Runs
A batch run turns one fire into many. Upload a list of 1,000 contacts, fire once, and the flow runs a thousand times — once per contact, each on its own conversation.
What a batch run does
Each fire materialises rows from a data source and dispatches one flow execution per row. Rows run independently, so one failure never blocks the rest.
The failure unit is the row, not the fire. A batch where 997 rows succeed and 3 fail is a batch you retry three rows of — not one you run again from the top.
Choosing the record source
| Source | What it is | Use when |
|---|---|---|
| CSV upload | A file of rows you upload | A one-off list, or a list produced elsewhere |
| Lead query | A live query over the workspace's leads | The audience is defined by a rule, not a file |
A lead query is re-evaluated on every fire, which makes it right for recurring campaigns: "everyone who left an email in the last 7 days and hasn't been contacted" grows and shrinks by itself.
A CSV is fixed. Right for "these 400 people, once".
Both offer a preview of the first rows before you commit — use it, and check the columns are what you think they are.
Mapping rows to the flow
Row mapping connects each row's columns to the flow's state keys. A CSV column phone maps to
a flow-state key customerPhone, and every execution starts with that row's value in place.
This is what makes personalisation work: the flow is written once against customerPhone and
customerName, and each of the thousand runs gets its own.
Unmapped columns still travel with the row but aren't injected into flow state.
Phone numbers
The column that identifies the recipient is read as a phone number, with one set of rules for the
whole product. The same customer written +90 532 …, 0090 532 … or 0532 … is one contact, with
one conversation. A number written without a country code is completed with the automation's
default country (chosen in the wizard, or defaultCountry when set up over MCP). A number that
can't be read with certainty is sent exactly as written.
Without a default country, a number written without a country code is not left as it is at send time: the WhatsApp send completes it with the country of the number you send from, while the opt-out and already-sent checks read it as written. So set the default country whenever the list's numbers belong to a different country than your sending number.
Safety controls
Sending to a thousand people is exactly the situation where a small mistake becomes an expensive one. Three controls exist for that:
| Control | What it does |
|---|---|
| Canary rollout | Sends to a small percentage first (5–25%). If the canary goes badly, the rest is held back |
| Deduplication | Skips recipients a previous fire already reached, so a recurring campaign doesn't message the same person twice |
| Row limit | Caps how many rows a single fire will process |
Canary rollout is the one that saves you — within limits worth knowing:
- It only applies to batches of 10 rows or more. Below that, every row dispatches.
- The bar is a fixed 90% canary success rate; above it, the rest is released automatically.
- It measures whether each run finished, not whether the flow produced a good answer. A run that fails — an error in the flow, or a WhatsApp, Instagram or Facebook send the channel refused in a Tool node — counts as a failure, and the rest of the batch waits until the canary rows have reported. Canary catches a bad phone column, a suspended template or a broken flow; it does not catch a bad prompt.
- A send refused inside an Agent node (the Agent calling its own WhatsApp, Instagram or Facebook tool) is different: that call is marked failed and isn't billed, but the run still finishes, so the row reads success and the canary counts it as one. When the batch's result matters, send through a Tool node.
- When the canary fails, the remaining recipients are not sent and the notification says how many were held back. A recurring automation is also paused; a one-shot has already completed, so there is nothing left to pause.
So it saves you from the failures that show up at send time. Fire Now on a test row is still what catches the rest.
Holding the canary for review
By default a canary that passes releases the rest of the batch on its own. Turning auto-release off instead parks the remaining recipients until someone looks and says go — useful for a first send to a new list, or a campaign where the wording matters more than the timing.
Held recipients stay held indefinitely; nothing times them out. Release them once you are satisfied, either from the run's detail view or by asking an assistant connected over MCP to release it. If you turn auto-release off, make sure somebody knows to come back — a batch waiting on a verdict looks the same as one that is simply slow.
Concurrency and pacing
Rows are dispatched individually rather than all at once. This is deliberate: WhatsApp and Instagram both rate-limit, and both watch quality signals. A thousand identical messages delivered in ten seconds is a recognisable pattern, and the platform's response is to restrict your number.
If you're new to bulk messaging on a number, start smaller than you want to. See WhatsApp credentials for what a quality downgrade looks like.
What each run receives
Each execution gets its row's mapped values in flow state, and its own session — so replies come back to the right conversation, and memory works per recipient.
Otherwise it's an ordinary run: it appears in Executions with a full trace, and the messages it sent appear in View Messages.
For the trigger's in-flow configuration, see Batch run trigger.
Stopping a batch
Pause the automation. Rows already dispatched finish; nothing new is dispatched.
There is no way to un-send what's gone. This is the real argument for the canary: it's the only control that acts before the mistake reaches everyone.
Retrying failures
The batch detail view shows each row's outcome — success, failed, or skipped. Retry Failed re-runs only the failed rows of the latest fire, on the same sessions.
Read success precisely: a row shows it as soon as it is handed off for sending, and turns failed if its run then errors — so while a fire is still finishing, success is provisional. It also means the run finished, not that every send in it went out: a send refused inside an Agent node leaves the row at success. Open an execution to check the outcome itself.
See Failure handling.
Related
- Scheduled runs — timing and lifecycle, which batches inherit
- Failure handling — retries and the row-level outcomes
- WhatsApp channel — templates and the 24-hour window