Automation Blog

How to Loop Through Line Items and Aggregate Results in Zapier

How to configure Looping by Zapier to iterate over an array of line items one at a time, run actions inside each iteration, and then collect the output from every iteration into a single aggregated result after the loop ends — useful for order processing, batch record creation, and multi-item notifications.

ZapierLine ItemsLooping

By Troy Tessalone · · 6 minutes

Automation Guide

A practical field guide from Automation Ace.

How to Loop Through Line Items and Aggregate Results in Zapier

Looping by Zapier solves the core problem of dynamic-count arrays: instead of trying to process all items at once in a single step, the loop runs a set of Zap steps once per item, adapting automatically to whatever count arrives in the trigger data. After the loop ends, Zapier provides aggregated output — a collected list of all values produced by each iteration — which you can use in subsequent steps that run once after the loop completes. This guide covers both sides: setting up the loop and using the aggregated results.

What Looping by Zapier Does

Looping by Zapier is a native Zapier action that takes parallel line item arrays as input and executes a defined set of steps once per item. Think of it as a for-each loop inside a Zap:

  • Before the loop — trigger and any pre-processing steps run once
  • Inside the loop — one or more action steps run once per line item
  • After the loop — steps that run once after all iterations complete, with access to aggregated loop output

Setting Up the Loop: Mapping Line Items as Input

Add a Looping by Zapier step after your trigger (or any pre-processing Code step). In the loop's configuration:

  1. Under Values to Loop Over, add one row per property you want available inside the loop
  2. For each row, give it a key name (e.g., name, price, quantity) and map the corresponding line item field from the trigger
  3. When you select a line item field as the value, Zapier automatically uses all numbered instances (Name 1, Name 2, Name 3, etc.) as the loop source — you don't need to select each numbered field individually

Inside the loop, each step has access to the current iteration's values via the loop's output fields: Loop Name, Loop Price, Loop Quantity — whatever keys you defined. These hold the single item's value for the current iteration.

Steps Inside the Loop

Add whatever actions you need inside the loop — they run once per item:

  • Create a record in Airtable, Notion, or a Google Sheet row for each line item
  • Look up an item in an inventory system by SKU
  • Send a per-product notification
  • Run a Code step that transforms the current item's data

Any output produced by steps inside the loop is collected by Zapier's aggregation — more on this below.

Ending the Loop

Add a Looping by Zapier — End Loop step as the final step inside the loop block. This signals where the loop body ends. Steps placed after the End Loop run once, after all iterations complete.

Aggregating Loop Output

After the loop ends, Zapier provides aggregated output from the Looping step itself. These aggregated fields collect a value from every iteration into a single comma-separated list. For example, if a Code step inside the loop outputs record_id on each iteration, the aggregated output Loop Record Id after the loop contains all the IDs joined together: "rec123,rec456,rec789".

Access the aggregated output by mapping fields from the Looping by Zapier step (not the End Loop step) in downstream steps after the loop.

Using Aggregated Results in a Post-Loop Code Step

The aggregated output is a comma-separated string. To work with it after the loop:

// inputData.record_ids = "rec123,rec456,rec789" (aggregated from loop)
// inputData.names = "Widget A,Widget B,Widget C"
// inputData.statuses = "created,created,skipped"

const recordIds = inputData.record_ids.split(',').map(s => s.trim()).filter(Boolean);
const names = inputData.names.split(',').map(s => s.trim()).filter(Boolean);
const statuses = inputData.statuses.split(',').map(s => s.trim());

const created = statuses.filter(s => s === 'created').length;
const skipped = statuses.filter(s => s === 'skipped').length;

const summary = names.map((name, i) => `${name}: ${statuses[i]}`).join('\n');

output = {
  total_items: String(recordIds.length),
  created_count: String(created),
  skipped_count: String(skipped),
  record_ids_joined: recordIds.join(','),
  summary
};

This pattern is useful for sending a single post-loop notification with a summary of what happened across all iterations — e.g., "3 records created, 1 skipped" — rather than sending one notification per item.

Aggregation Pattern: Collecting IDs Created Inside the Loop

A common need: create a record in one app per line item, then after the loop, update the original record with all the created IDs. The flow is:

  1. Trigger receives an order with N line items
  2. Loop creates a fulfillment record per item → each iteration outputs a record_id
  3. After the loop, the aggregated Loop Record Id contains all N IDs as a comma-separated string
  4. A post-loop step updates the original order record with the full list of fulfillment IDs

When the Loop Produces No Output to Aggregate

If the steps inside the loop don't produce any field you want to aggregate, the aggregated output from the loop will be empty or contain only the original loop input values. To collect a custom value from each iteration, add a Code step inside the loop that outputs the value you want to aggregate:

// Code step inside the loop — run this as the last step in each iteration
// Output whatever you want collected per-iteration

const lineTotal = parseFloat(inputData.price) * parseInt(inputData.quantity, 10);

output = {
  line_total: lineTotal.toFixed(2),
  item_label: `${inputData.name} (${inputData.quantity})`
};

After the loop, Loop Line Total and Loop Item Label hold all per-iteration values.

Nesting Consideration: One Loop per Zap

Zapier does not support nested loops (a loop inside a loop). If your data has two levels of nesting — orders, each with multiple line items, each with multiple tax entries — flatten the data before looping, or handle the inner array in a Code step inside the outer loop using JavaScript array methods.

Loop vs. Code Step: When to Use Each

  • Use a loop when each item needs its own discrete action (create a record, send a message, call an API endpoint)
  • Use a Code step when you're computing across all items at once (sum totals, build a formatted list, filter items) — no per-item action needed
  • Use both when you need per-item actions AND a post-loop aggregation step
Looping by Zapier handles dynamic-count arrays correctly because the loop body runs once per item regardless of how many arrive. The aggregation output — collected automatically from every iteration — makes it possible to build a summary or pass all created IDs to a single post-loop action. Design the loop input fields to include every property each iteration needs, and add a Code step as the last loop step when you want precise control over what gets aggregated.

For a foundational explanation of how line items work in Zapier, see handling line items and arrays in Zapier Zaps. For JavaScript array operations on aggregated output, see JavaScript array methods in Zapier Code steps. For help building a looping workflow for order or batch processing, talk to Automation Ace.

ZapierLine ItemsLooping

Disclaimer: This article may include links to apps, products, or services. Some links may be affiliate links, which means Automation Ace may earn a commission at no extra cost to you.

Build Better Systems

Ready to automate with confidence?

Share your tools, process, and goals. Automation Ace can design the workflow, integration, AI assist, or code bridge that fits your business.

Start a Project