
Post: How to Use Iterator and Aggregator in Make for HR Data Transformation
Make’s Iterator splits a bulk array into individual bundles so every record gets processed separately. Its paired module, the Aggregator, reassembles those individual outputs into one consolidated result. Together they solve the two most common HR data pipeline problems: processing 50 employee records one at a time and delivering a single report from 40 individual résumé scans.
This is a direct drill-down into one of the most important mechanics covered in the parent guide on data filtering and mapping in Make for HR automation. If you’ve hit the wall where a bulk module return breaks your downstream logic, this is the fix.
What You Need Before You Build
Iterator and Aggregator are intermediate Make mechanics. Before you place either module, confirm you have everything below in place.
- An active Make account with at least one live scenario and a configured trigger.
- Access to your HR data source — the ATS, HRIS, inbox, or spreadsheet that generates the bulk records you want to process.
- Array confirmation. Iterator only works on arrays. If your source module outputs a single object instead of a collection, Iterator has nothing to split. If you’re unsure of the difference, read JSON arrays and objects in Make HR automation first.
- A test dataset. Running an Iterator loop against a live production system without testing first triggers duplicate writes, notification floods, or API rate-limit errors. Use a sandboxed or sample dataset for every first build.
- Operations budget awareness. Each bundle the Iterator emits consumes at least one Make operation. A loop over 100 records with three modules inside costs 300+ operations minimum. Check your plan’s monthly operation cap before scaling.
Allow 60–90 minutes for a first build. Once the pattern is familiar, 20–30 minutes is typical.
Step 1 — Confirm Your Source Module Outputs an Array
Run the scenario manually and open the bundle inspector on the source module’s output. Look for square brackets surrounding the data. If you see [ { }, { }, { } ], you have an array. If you see a single { } object, the Iterator has nothing to split — you’ll need to restructure upstream first.
Common HR bulk data sources that output arrays:
- ATS API endpoints returning all candidates for a given job posting
- HRIS report exports returning all active employees
- Email trigger modules returning all file attachments on a single message
- Spreadsheet modules reading all rows from an onboarding tracker
- Survey platforms returning all responses for a performance review cycle
Once you’ve confirmed your array, note the exact field name that contains it. You’ll map this field into the Iterator in the next step. Flat-mapping a 50-record array into a single downstream field is the most common pipeline failure point in HR scenario audits — Iterator is the correct structural fix.
Step 2 — Insert and Configure the Iterator Module
Place the Iterator immediately after the module that outputs your array. Do not place any processing modules between the source and the Iterator — they won’t have access to the individual records yet.
Configuration steps:
- Click the + button after your source module and search for Flow Control > Iterator.
- In the Iterator’s Array field, map the array field from your source module. This is the field containing the square-bracket collection you identified in Step 1. Do not map a nested sub-field here — map the top-level array.
- Save the module. Make will display a note showing the expected item structure derived from your array. Review this to confirm the field names you’ll reference in downstream modules.
What the Iterator does after configuration: it reads the array and emits one bundle per item. If your source returned 50 employee records in one bundle, the Iterator outputs 50 individual bundles — one for each record. Every module placed after the Iterator in the scenario receives those bundles sequentially and processes each record independently.
Common mistake: Mapping the wrong level of the array. If your ATS returns a response object with a nested candidates array, you must map candidates specifically — not the top-level response object. Open the bundle inspector, expand every level, and map the field that contains the [ ] collection.
Step 3 — Build Your Processing Modules Inside the Iterator Loop
Every module you place after the Iterator and before the Aggregator operates inside the loop. Each one runs once per bundle — once per employee record, once per résumé, once per row.
Typical HR processing modules inside an Iterator loop:
- Conditional filter (Router or Filter module): Exclude records that don’t meet criteria — active employees only, candidates past a certain stage, rows with non-empty required fields.
- Data transformation (Tools > Set Variable or Text Parser): Normalize field values — format dates, trim whitespace, concatenate first and last name fields.
- API write module: Push each individual record to a downstream system — create a task in your project manager, write a row to a Google Sheet, update a CRM contact.
- AI module: Pass each résumé or survey response to an AI analysis module individually so it receives one document at a time instead of a concatenated blob.
Name every module clearly. “HTTP” and “Module 7” are not acceptable names on any production scenario. Name each module what it does: “Filter: Active Employees Only,” “Write: Create Onboarding Task,” “AI: Score Résumé.”
Operations note: Each module inside the loop multiplies your operation count by the number of records. Three modules processing 100 records = 300 operations minimum, plus the source module and aggregator. Budget accordingly before you deploy.
Step 4 — Insert and Configure the Aggregator
Place the Aggregator after the last processing module in your loop. The Aggregator’s job is to collect all the individual bundle outputs from the Iterator loop and combine them into a single bundle for the next stage of your scenario.
Make includes several Aggregator types. The correct choice depends on what you’re collecting:
- Array Aggregator: Collects all bundle outputs into a new array. Use this when the next module needs a collection — for example, feeding a list of processed employee IDs into a batch API call or building a JSON payload with multiple records.
- Text Aggregator: Concatenates text values from each bundle into a single string. Use this when you’re building a plain-text or HTML report from individual record outputs — candidate summaries, employee status reports, résumé scoring results formatted for email delivery.
- Numeric Aggregator: Performs sum, average, minimum, maximum, or count across numeric values from each bundle. Use this for payroll totals, headcount counts, or aggregate performance scores across a review cycle.
- Table Aggregator: Builds a formatted table from individual records. Use this when the output is an HTML report with rows.
Configuration steps for Array Aggregator (the most common HR use case):
- Click the + button after your last processing module and search for Flow Control > Array Aggregator.
- In the Source Module field, select the Iterator you configured in Step 2. This tells the Aggregator which loop it’s closing.
- In the Aggregated fields section, map the fields from your processing modules that you want included in the final array. Map only the fields the downstream module needs — don’t include every field by default.
- Save the module. Make will display the expected output structure. Confirm the array field name you’ll reference in the next step.
Common mistake: Selecting the wrong Source Module. If your scenario has multiple Iterator loops, selecting the wrong source module in the Aggregator breaks the loop closure. Always verify the Source Module field matches the specific Iterator that opened this loop.
Step 5 — Connect the Aggregated Output to Your Final Destination
After the Aggregator, your scenario is back to single-bundle processing. The Aggregator emits one bundle containing the collected result — one array, one text block, one number, or one table — and every module after it receives that single bundle once.
Typical final-destination modules for HR aggregation:
- Email module: Send a consolidated candidate status report or onboarding completion summary to the hiring manager or HR director.
- Google Sheets or Airtable write: Write the full processed dataset to a tracker in one operation instead of triggering a row-write for every record.
- HTTP POST to HRIS or ATS: Submit a batch update payload when the platform’s API accepts array input.
- Slack or Teams notification: Post a summary message with headcount totals, score averages, or a formatted list of completed onboarding tasks.
- Document generation module: Feed the aggregated text block into a PDF or DOCX template for a formatted HR report.
Every outbound module — email, Slack, HTTP POST — should include a footer with {{var.scenario.executionUrl}} so every delivery is traceable back to the specific scenario run that produced it.
Iterator and Aggregator in Practice: Three HR Pipeline Patterns
Pattern 1: Bulk Candidate Scoring
Your ATS returns an array of 30 candidate records when a job posting closes. Each record needs individual AI scoring before the hiring manager sees results.
Structure: ATS trigger → Iterator → AI Score Module → Array Aggregator → Email to Hiring Manager
The Iterator splits the 30-record array into 30 individual bundles. The AI module receives one résumé at a time and returns a score and summary. The Array Aggregator collects all 30 scored records into a single array. The email module sends one message with a formatted scorecard table — not 30 individual emails.
Pattern 2: Onboarding Task Creation Across Systems
An HRIS report returns all employees starting next Monday. Each employee needs a task created in your project manager, a row added to the onboarding tracker, and a welcome email triggered.
Structure: Scheduled trigger → HRIS module → Iterator → [Task Create + Sheet Write + Email] → Numeric Aggregator → Slack Summary
The Iterator processes each employee individually so no record is skipped. The Numeric Aggregator counts completed task creates. The Slack module posts “14 onboarding tasks created for Monday start date” — one notification, not 14.
Pattern 3: Benefits Enrollment Validation
A Google Sheet contains 200 rows of open enrollment submissions. Each row needs validation against carrier eligibility rules before submission. Invalid rows need to be flagged without stopping the rest of the loop.
Structure: Sheet module → Iterator → Router (valid/invalid paths) → [Submit to carrier API OR Write to error log] → Text Aggregator → Email report
The Router inside the loop sends valid records to the carrier API and invalid records to an error log — both paths run inside the Iterator loop. The Text Aggregator builds a plain-text summary: valid submissions, error count, list of flagged employee IDs. The email delivers one structured report to the benefits administrator.
Mistakes That Break Iterator/Aggregator Builds
- Not testing with a capped dataset first. Run your first test against 3–5 records, not 200. Confirm field mapping is correct before scaling. A mapping error across 200 records means 200 failed writes or corrupt outputs.
- Mapping the array at the wrong nesting level. The Iterator needs the actual array field, not the parent object containing the array. Expand every level in the bundle inspector before mapping.
- Placing transformation modules before the Iterator. Any module placed before the Iterator operates on the full array as one bundle. Move transformation logic inside the loop where it operates record-by-record.
- Selecting the wrong Source Module in the Aggregator. In scenarios with nested or sequential Iterator loops, the Source Module field is where loops get crossed. Verify it explicitly every build.
- Ignoring operations cost before deployment. An Iterator loop over 500 records with four modules each = 2,000+ operations per run. If the scenario runs daily, that’s 60,000+ operations per month. Know your plan cap before you go live.
- No error handler on modules inside the loop. If one record fails mid-loop without a break handler, the scenario halts and all remaining records are skipped. Add an
onerrorhandler (Break with retry: 3 attempts, 60-second interval) to every API call and write module inside the Iterator.
When You Don’t Need an Aggregator
Not every Iterator loop needs an Aggregator. If your scenario’s goal is to perform an individual action for every record — create a task, send an email, write a row — and there is no downstream step that needs a consolidated result, you can end the scenario after the last loop module. The Aggregator only earns its place when the step after the loop needs all records combined into a single output.
If you’re unsure whether your use case needs an Aggregator, ask: “Does the next step need one thing built from all the records, or does it just need each record acted on?” One consolidated thing = add the Aggregator. Individual actions on each record = the Iterator loop alone is enough.
How This Fits the Larger HR Automation Stack
Iterator and Aggregator solve a structural data problem — collection-to-individual and individual-to-collection conversion. They are not the entry point for HR automation. The entry point is understanding which processes are safe to automate, in what order, and what data quality requirements must be met before any scenario goes live.
The OpsMap™ audit is how we map that before a single module gets built. It surfaces the broken handoffs, the missing validations, and the data structure gaps — like the one Iterator and Aggregator fix — before they become production failures. If you’re building HR automation without a structured discovery step, Iterator configurations are not where the risk lives.
For a broader look at how HR teams are using Make to handle the full data transformation stack — not just array processing — read how a non-technical HR team started building their own automations with Make + AI and 6 ways the Make MCP changes automation work for HR teams.
The OpsMesh™ framework that structures every 4Spot engagement — OpsMap™ discovery, OpsSprint™ rapid build cycles, OpsBuild™ scenario development, and OpsCare™ ongoing support — is designed so HR teams are never handed a live scenario without understanding the data structures it depends on. Iterator and Aggregator are not advanced features. They’re fundamental mechanics. Build them right once, and the rest of the pipeline holds.

