Rendex
Recipe

Render a List to Images and Send One Email With Every Attachment

Point Make at a list — rows, records, line items — and get back a single email with a rendered PNG for each one. An Iterator runs the Rendex render per item and an Array Aggregator recombines them, so nobody gets four separate emails: they get one, with four attachments.

Last updated 2026-07-21

The Problem

You have a batch to render — a badge per attendee, a card per product, a certificate per row — and you want the whole set to arrive together, not as one email per item. The naive automation loops and sends inside the loop, so the recipient's inbox fills with N near-identical messages. Worse, most no-code tools can split a list but can't merge the results back: they render each item fine, then have no way to gather the outputs into a single downstream action, so 'one email with everything attached' quietly becomes impossible.

The Solution

This is exactly what Make's Iterator and Array Aggregator are for, and it's the pattern that sets Make apart from Zapier. The Iterator (a built-in flow-control module) splits the incoming array into one bundle per item; the Rendex HTTP module renders each item's HTML to a PNG; then the Array Aggregator gathers every per-item binary back into a single collection. One Email module downstream maps that collection into its attachments, so a four-row list produces one email with four PNGs — not four emails. The render itself is a plain single-source POST to /v1/screenshot with the item's fields merged into an HTML template via data{}, and it all runs on the free tier.

How the Workflow Runs

List trigger

A Search Rows, data store, or webhook module produces an array of items to render.

Iterator

Make's Iterator splits the array into one bundle per item so the next module runs once each.

Rendex HTTP module

POST /v1/screenshot renders each item's HTML to a PNG and returns the binary Data.

Array Aggregator

Collects every per-item PNG back into one array, so the whole batch lands in a single downstream bundle.

One email

A single Email module attaches the aggregated collection — one message, every render attached.

Input → Rendered Output

Left: a Make scenario — a Search Rows module feeding an Iterator, a Rendex HTTP module, and an Array Aggregator that flows into one Email module, annotated 'render each row, then aggregate BACK into one message'. Right: a single email preview titled 'Your 4 badges are ready' with four rendered PNG attachment chips.

Rendered by Rendex

What You Need

  • A Rendex API key — the free tier includes 100 renders/month with no card required.
  • A Make account on any plan (Iterator, Array Aggregator, and the HTTP module ship on every plan).
  • A trigger or module that produces an array — a Search Rows (Sheets), a data store, or a webhook payload with a list.
  • A downstream Email module (or Drive/Dropbox) to receive the aggregated attachments.

What This Recipe Uses

Iterator fans the list out

Make's built-in Iterator splits the incoming array into one bundle per item, so the Rendex module runs exactly once for each record with no loop code.

Array Aggregator fans it back in

The aggregate-back step — the thing Zapier can't do. It collects every per-item PNG into one collection so the whole batch lands in a single downstream module.

One render call per item

POST /v1/screenshot renders each item's HTML to a PNG and returns the binary directly — no hosted page, no headless browser inside Make.

One message, every attachment

The Email module maps the aggregated collection into its attachments array, so the recipient gets a single email with all the renders — not one per row.

Build It

make-iterator-aggregator-setup.txt
# Build the scenario as five modules in a row:

1. Source        (e.g. Google Sheets > Search Rows)  -> yields an array
2. Iterator      (Flow Control > Iterator)
     Array = {{1.array}}          # the rows/records from step 1
3. HTTP          (HTTP > Make a request)             # the Rendex render
     -> see the JSON body below; map {{2.<field>}} from the Iterator
4. Array agg.    (Flow Control > Array aggregator)
     Source module   = 2 (Iterator)   # what it collects over
     Aggregated field = 3. Data        # the Rendex binary PNG
5. Email         (Email > Send an email)
     Attachments -> map {{4.array}}    # the aggregated collection

# The Iterator makes #3 run once per item; the Array aggregator gathers
# every render back into ONE bundle so #5 sends a single email.
body-render-per-item.json
{
  "html": "<div style='width:600px;padding:48px;font-family:system-ui;text-align:center'><h1 style='color:#ea580c'>{{name}}</h1><p style='font-size:20px;color:#475569'>{{role}}</p></div>",
  "data": {
    "name": "{{2.name}}",
    "role": "{{2.role}}"
  },
  "format": "png"
}
// {{2.name}} / {{2.role}} come from the Iterator (module 2), so each
// iteration renders that item. Exactly ONE source field (html) — never
// add a url or markdown alongside it, or the call returns a 400.
aggregator-config.txt
Module:            Flow Control > Array aggregator
Source module:     Iterator (module 2)     # REQUIRED — sets the loop boundary
Target structure:  Custom
Aggregated fields: Data   (the HTTP module's binary output, module 3)

# Result mapped downstream as {{4.array}} — an array of the per-item PNGs.
# In the Email module, add one attachment row and map its Data to the
# collection, or use "Map" to attach the whole array at once.
render-one-item.sh
# Make's HTTP module sends exactly this once per iteration. Run it once in a
# terminal to confirm your key renders before wiring the Iterator. Response = PNG.
curl -X POST https://api.rendex.dev/v1/screenshot \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  --output badge.png \
  -d '{
    "html": "<div style=\"width:600px;padding:48px;text-align:center\"><h1>Giulia Rossi</h1><p>Speaker</p></div>",
    "format": "png"
  }'

100 free API calls/month — no credit card required. Get your API key and start building.

Reach for this whenever a batch should arrive as one deliverable: a set of event badges to a coordinator, a sheet of product cards to a marketer, a run of certificates to an admin. The render is the easy half — the Rendex HTTP module takes exactly one source field and fills a template from each item's data{} — but the part that trips up other tools is putting the batch back together. In Make you frame it as three built-in modules in a row: Iterator to fan out, the Rendex call in the middle, Array Aggregator to fan back in. The aggregator's Target is the Iterator (so it knows what to collect) and its aggregated field is the Rendex module's binary Data; downstream, one Email module reads that collection as its attachment array. Because the aggregation happens in Make's own flow-control, there's no code and no second scenario. Keep parseResponse off so the render comes back as raw bytes the aggregator and the email attach without decoding, and keep the HTML template's placeholders as {{item.field}} filled by data{} so each render is personalized. It's all free-tier — PNG output, HTML input, and data{} Mustache templating — so you can prove the batch before touching billing, then swap the Email module for Drive, Dropbox, or a zip step if you'd rather store the set than send it.

Frequently Asked Questions

Related Resources