Buni.aiDocs
NewAutomation

Loop

Repeats the nodes on its body handle once for each item in a list, with optional pacing, then continues with the collected results.

Loop runs part of an automation once per item in a list. The nodes connected to its each item handle run for the first item, then the second, and so on, one at a time. When every item is done, the flow continues from the done handle with all the results collected.

When to use it

  • Send a WhatsApp message to every contact in a list.
  • Create one record per row returned by an API or a Data Store query.
  • Call a rate-limited API for many items without tripping its limit, using pacing.
  • To run a few different steps at the same time rather than the same steps many times, use Parallel.
  • To drop repeated items before looping, put Remove Duplicates in front.

Automation projects only

Loop appears only in the palette of automation projects.

Loop settings with Items expression set to state.contacts, Even pacing at 20 per second, and Carry on, then report selected

Settings

Prop

Type

When you choose a pacing mode, the panel estimates how long the pacing alone takes at Max iterations and compares it with the 180-second run budget: Fits, Tight (over half the budget) or Over budget.

If an item fails

OptionWhat happens
Stop the whole runThe remaining items are never attempted and the run is marked failed.
Skip the item and carry onThe failure is recorded in the results and the run finishes as a success.
Carry on, then reportEvery item is attempted. The run finishes, and a summary of which items failed is written to {{state.loopResultsSummary}} and shown in the run's activity. Best for sending to a list.

Outputs

HandleWhat runs
each itemOnce per item. Every node on this branch can read input.item (the current item), input.index (its position, from 0) and input.loop.
doneOnce, after the last item. Its input is the loop's input plus the results under the output variable's name.

Written to state:

  • {{state.loopResults}}: an array with one entry per item, the value the body's last node returned. A skipped item is recorded as { loopIterationError, index }.
  • {{state.loopResultsSummary}} (with Carry on, then report only): { total, succeeded, failed, failures }, where each failure has index, label, message and the node that failed.

The names follow Output variable: set it to sent and you get state.sent and state.sentSummary.

Example

A scheduled automation reminds everyone with a booking tomorrow:

  1. Schedule trigger runs daily at 17:00.
  2. Data Store, GET bookings for tomorrow, output variable bookings.
  3. Loop, Items expression state.bookings, Even pacing at 20 per second, Carry on, then report.
  4. On each item: Messaging sends a WhatsApp template to ${input.item.phone}.
  5. On done: Messaging sends the operations lead "Reminders sent: ${state.loopResultsSummary.succeeded}".

Tips and limits

  • The whole run has 180 seconds. Pacing spends that budget, it does not extend it. For long lists, lower Max iterations and run the automation more often, or split the list across runs.
  • Iterations run one after another, never at the same time.
  • Not allowed in the body: Wait, Approval, Collect Payment, Respond Webhook, Parallel, or another Loop. The body must not connect back to the loop or into the done branch. Publishing fails with an error naming the node if it does.
  • The Items expression is JavaScript, not a template: write state.contacts, not {{state.contacts}}.
  • input.item stays readable after a node in the body replaces the flowing data (an API response, for example), so later body nodes can still reach the current item.
Last reviewed 24 September 2026

On this page