Skip to main content

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

SourceWhat it isUse when
CSV uploadA file of rows you uploadA one-off list, or a list produced elsewhere
Lead queryA live query over the workspace's leadsThe 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.

Safety controls

Sending to a thousand people is exactly the situation where a small mistake becomes an expensive one. Three controls exist for that:

ControlWhat it does
Canary rolloutSends to a small percentage first (5–25%). If the canary goes badly, the rest is held back
DeduplicationSkips recipients a previous fire already reached, so a recurring campaign doesn't message the same person twice
Row limitCaps 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 messages were dispatched, not whether the flow produced a good answer. A batch whose flow errors on every row still reads 100% and releases. Canary catches a bad phone column or a suspended template; it does not catch a bad prompt.

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.

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: it means the row was handed off for sending, not that the flow ran successfully afterwards. A batch can show 100% success while every run failed inside the flow — open an execution to check the outcome itself.

See Failure handling.