How to Use Iterator and Aggregator in Make for HR Data Transformation

By Published On: August 19, 2025

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 drill-down into one of the most important mechanics in any HR data pipeline build. If you’ve hit the wall where a bulk module return breaks your downstream logic, this is the structural fix. For context on the broader data layer this sits inside, read 11 HR data mapping mistakes to avoid for seamless workflows.

What You Need Before You Build

Iterator and Aggregator are intermediate Make mechanics. Before you place either module, confirm everything below is 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. Read how Make’s key features handle HR data structures if you’re unsure of the difference before continuing.
  • 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-plus 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:

  1. Click the + button after your source module and search for Flow Control > Iterator.
  2. 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.
  3. 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.

Expert Take

The single most common reason an HR Iterator build fails on the first run is array-level mismatch – the builder maps the parent object instead of the nested array field. Before saving the Iterator configuration, expand the bundle inspector to the deepest level and verify the field you’re mapping contains square brackets, not curly braces. Five seconds of inspection prevents a full rebuild.

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 collects all the individual bundle outputs from the Iterator loop and combines 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):

  1. Click the + button after your last processing module and search for Flow Control > Array Aggregator.
  2. In the Source Module field, select the Iterator you configured in Step 2. This tells the Aggregator which loop it’s closing.
  3. 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.
  4. 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 a single notification with the total count – not one notification per employee.

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-plus operations per run. If the scenario runs daily, that’s 60,000-plus 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 onerror handler (Break with retry: 3 attempts, 60-second interval) to every API call and write module inside the Iterator.

Expert Take

The operations cost trap hits HR teams the hardest at scale. A scenario that processes 50 records in testing looks manageable – then scales to 500 in production on a daily schedule and burns through the month’s operation budget in a week. Calculate worst-case record count multiplied by module count multiplied by daily run frequency before you publish any Iterator scenario to production. Build that number into your Make plan review before go-live, not after.

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. Read 10 real examples of why clean processes must come before any HR automation if you’re building without a structured discovery step first. If you’re ready to see what Make brings to the full HR stack, 11 Make scenarios elevating HR recruiting with strategic automation covers the broader pattern set.

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.

Frequently Asked Questions

What is the difference between Iterator and Aggregator in Make?

The Iterator splits an array into individual bundles so each record gets processed separately by downstream modules. The Aggregator closes that loop by collecting all individual bundle outputs back into a single result – one array, text block, or number – for the next module in the scenario. They always work as a pair when you need both per-record processing and a consolidated final output.

Can you use an Iterator without an Aggregator in Make?

Yes – and it’s the right call when every action inside the loop is self-contained. Writing a row, sending an email, and creating a task are all valid Iterator-only patterns. Add the Aggregator only when a downstream module needs a consolidated output built from all the individual records processed inside the loop.

How do Iterator operations affect my Make plan limit?

Each bundle an Iterator emits consumes at least one operation per module inside the loop. A loop over 100 records with three processing modules costs 300-plus operations minimum, not counting the source trigger or the Aggregator itself. Multiply worst-case record count by module count by daily run frequency before publishing to production – that calculation determines whether your current plan supports the scenario at scale.

What causes an Iterator to fail on an HR dataset?

The two most common causes are mapping the parent object instead of the nested array field, and running without an error handler on modules inside the loop. A single failed record with no break handler halts the entire loop and skips all remaining records. Both are preventable: inspect the bundle at every nesting level before mapping, and add an onerror handler to every API call inside the Iterator.

Free OpsMap™️ Quick Audit

One page. Five minutes. Pinpoint where your business is leaking time to broken processes.

Free Recruiting Workbook

Stop drowning in admin. Build a recruiting engine that runs while you sleep.

Ready to run the map on your business?

The OpsMap audit is free. You walk out with a written map either way.