# Make

> The visual, operations-priced automation tool (formerly Integromat): build scenarios from modules, map and transform arrays, and handle errors deliberately.


---

# Make

Make is a tool for wiring apps together so work happens without you. You draw a flow on a canvas - "when a form is submitted, create a row in a sheet, then send a Slack message" - and Make runs it. It used to be called Integromat, and you'll still see that name in old tutorials and forum posts; it's the same product, renamed in 2022.

What sets Make apart from the other big name in this space, Zapier, is that it shows you the wires. Most automation tools hide the plumbing behind a friendly checklist. Make hands you a visual map of circles connected by lines, and lets you see the actual data flowing between each step. That's more to look at up front, and it's the reason people who outgrow simpler tools come here: you get loops, branching, data reshaping, and real error handling that the checklist-style tools either can't do or bury.

This guide is for founders, ops people, and analysts who have a real workflow to automate and have hit a wall - either with a simpler tool, or with the manual copy-paste version of the job. You don't need to write code. You do need to be willing to think about your data as it moves: where it comes from, what shape it's in, and what should happen when a step fails. Phase 1 covers the canvas and how a scenario actually runs - the mental model everything else rests on. Phase 2 is the part that trips everyone up: mapping fields between steps, transforming text and dates, and handling lists of things with iterators, aggregators, and routers. Phase 3 covers the unglamorous but money-relevant parts - error handlers, scheduling, and Make's pricing model, which is counted in "operations" and surprises almost everyone the first time they read the bill.


---

# Scenarios & Modules

A **scenario** is one automation. It has a start, a sequence of steps, and an end. If you've ever written down "when X happens, do Y, then Z," that's a scenario. In Make, you build it on a canvas - a blank space where you drop steps and connect them with lines.

Each step is a **module**. A module is one action in one app: "Watch new rows in Google Sheets," "Create a contact in HubSpot," "Send a message in Slack." Modules look like circles on the canvas, each branded with the app's logo, joined left-to-right by curved lines. Data flows along those lines in the direction of the arrows.

## The trigger comes first

The first module in a scenario is the **trigger** - the thing that kicks everything off. Triggers come in two flavors, and the difference matters more than it sounds.

A **polling trigger** checks an app on a schedule. "Watch new emails" doesn't know the instant an email arrives; it wakes up every few minutes, asks Gmail "anything new since last time?", and processes whatever it finds. You set how often it wakes up.

An **instant trigger** (Make calls these webhooks, or labels the module "instant") fires the moment something happens, because the other app pushes the news to Make. "Watch responses (instant)" in a form tool reacts within a second of submission. Instant is faster but only available where the source app supports pushing.

Most triggers process one item at a time. If your "watch new rows" trigger finds five new rows since it last ran, it runs the whole scenario five times - once per row. Hold that thought; it comes back when we talk about cost.

## Bundles: the data between modules

Here's the concept that unlocks Make. When a module runs, it hands the next module a **bundle** - a packet of data with named fields. A "Watch new rows" module outputs a bundle like:

```json
{
  "name": "Ada Lovelace",
  "email": "ada@example.com",
  "signed_up": "2026-06-30"
}
```

The next module reaches into that bundle and pulls out the fields it needs. When you set up a "Send email" module, you don't type the address - you click the email field, and a panel pops up showing every field from every earlier module. You pick `email` from the bundle, and Make wires it in. That picking-and-wiring is called **mapping**, and it's the whole job of building a scenario. Phase 2 is dedicated to it.

After a run, Make shows you the actual bundles that flowed through - click the little bubble above any module and you see exactly what data went in and came out. This is the single best thing about debugging in Make: you're never guessing what a step received.

## How a run unfolds

A scenario run is one pass through the modules, left to right. The trigger produces one or more bundles. Each bundle travels down the chain; each module does its job and passes a (possibly changed) bundle onward. When the last module finishes for the last bundle, the run is over.

```mermaid
flowchart LR
  A[Trigger: new row] --> B[Find customer]
  B --> C[Update CRM]
  C --> D[Send Slack message]
```

If a trigger emits multiple bundles in one run, Make doesn't run four separate scenarios - it pushes each bundle through the chain in turn, within the same run. Each module "executes" once per bundle. Those executions are the unit Make charges for. (Again, phase 3.)

## How this differs from Zapier

If you've used Zapier, the mental shift is worth naming.

| | Zapier | Make |
|---|---|---|
| Layout | Vertical checklist of steps | Visual canvas with wires |
| Branching | Limited; "Paths" feel bolted on | Routers split the flow natively |
| Loops over lists | Awkward; needs sub-Zaps or line items | Iterators and aggregators built in |
| Seeing the data | Test one step at a time | Inspect every bundle after a run |
| Pricing unit | Tasks (per action) | Operations (per module execution) |
| Learning curve | Gentle | Steeper, more control |

The trade is real. Zapier gets you to "it works" faster for a straight line of three steps. Make is where you go when the job has branches ("if the deal is over $10k, notify sales; otherwise log it"), loops ("for each line item on the invoice…"), or data that needs reshaping before the next app will accept it. The visual canvas is more to learn, but when something breaks at 2am, being able to see every wire and every bundle is the difference between a five-minute fix and an hour of guessing.

One practical note: Make scenarios are saved as you build, but they don't run until you turn the scenario **ON** with the toggle in the bottom-left. A scenario you built and tested but forgot to switch on is the most common "why isn't my automation working" question on the forums. Build it, test it with **Run once**, then flip it on.

In the next phase, we get into the part that separates people who can build anything in Make from people who get stuck: mapping fields, transforming values, and handling lists.


---

# Data Mapping, Arrays & Iterators

Building a scenario is mostly one activity: telling each module which data to use. That's mapping. Master mapping and the lists-of-things problem, and there's almost nothing in Make you can't build.

## Mapping a single field

When you open a module - say "Create a Trello card" - its fields are blank. Click into a field and Make drops down a panel showing every field from every earlier module, grouped by module. You click `email` from the trigger, and a colored token appears in the field. That token is a reference: "put the email value from step 1 here, at run time."

You can mix tokens with literal text. A subject line might read:

```text
New signup: {{name}} ({{email}})
```

Each `{{...}}` is a mapped token; the rest is typed. At run time Make substitutes the real values. If `name` is empty for a given bundle, the token resolves to nothing - Make doesn't error, it leaves a gap. That silent emptiness is a frequent source of "why is my message blank" confusion, so check your test runs.

## Functions: reshaping values inline

Often the raw value isn't in the shape the next app wants. The mapping panel has a second tab full of **functions** - small transformations you wrap around a token.

A few you'll reach for constantly:

```text
upper(name)                  → "ADA LOVELACE"
formatDate(signed_up; "MMMM D, YYYY")  → "June 30, 2026"
trim(notes)                  → strips leading/trailing spaces
if(amount > 1000; "big"; "small")      → conditional value
substring(phone; 0; 3)       → first three characters
```

Functions nest, so you can `upper(trim(name))`. The big three categories are **text** (case, trim, split, replace), **date/time** (parse and format - and dates are where most beginners get stuck, because a string from one app rarely matches what the next app expects), and **math/logic** (`if`, comparisons, rounding). You don't memorize these; you open the functions tab and skim.

## Routers: sending bundles down different paths

A **router** is a module that splits the flow into branches. Each branch can have a **filter** - a condition on the line. The bundle takes every branch whose filter passes.

```mermaid
flowchart LR
  T[New order] --> R{Router}
  R -->|amount > 1000| S[Notify sales]
  R -->|amount <= 1000| L[Just log it]
```

Filters are how you say "only continue if." You set them by clicking the wrench on the line between two modules. A filter that fails stops that bundle on that path - quietly, not as an error. Routers are Make's answer to "if this, do that; otherwise do this other thing," and they're far cleaner than the bolt-on branching in checklist tools.

## The list problem: arrays

Real data is full of lists. An invoice has many line items. An API returns many search results. A single bundle field can itself hold an **array** - a list of items, each with its own fields.

Here's the catch: a normal module processes one item. If you map an array directly into "Create a row," you'll get unpredictable behavior, because the module expected one value and got a list. Make gives you two tools for the gap between "one thing" and "many things," and knowing which to use is the core skill of this phase.

### Iterator: split one bundle into many

An **Iterator** takes an array and breaks it into separate bundles - one per item. Feed it an array of three line items, and every module *after* the iterator runs three times, once per item.

```text
Before iterator:  1 bundle  { items: [A, B, C] }
After iterator:   3 bundles  {A}  {B}  {C}
```

Use an iterator when you have a list and want to *do something with each item* - create a row per line item, send a message per recipient.

### Array Aggregator: collapse many bundles into one

The **Array Aggregator** is the mirror image. It takes many bundles and merges them back into a single bundle holding one array.

```text
Before aggregator:  3 bundles  {A}  {B}  {C}
After aggregator:   1 bundle  { collected: [A, B, C] }
```

Use an aggregator when downstream you want *one* of something built from many - one summary email listing all items, one API call with all records attached. There's also a **Text Aggregator** for stitching many bundles into one block of text (great for "build a list and put it in one message").

The classic pattern is the pair: **iterator → process each → aggregator**. Split a list apart, do work on each piece, then gather the results back into one. When a scenario "runs too many times" or "only does the last item," the fix is almost always a missing or misplaced iterator/aggregator.

```mermaid
flowchart LR
  A[Get invoice] --> B[Iterator: line items]
  B --> C[Lookup product]
  C --> D[Array aggregator]
  D --> E[One summary record]
```

## A worked picture

Say a webhook delivers an order with three line items, and you want one Slack message summarizing them, but only for orders over $50.

1. Webhook receives the order → verify: bundle shows the `items` array.
2. Filter on the line: `total > 50` → verify: small orders stop here.
3. Iterator over `items` → verify: downstream runs once per item.
4. (Optional lookup per item) → verify: each item gets enriched.
5. Text Aggregator joins items into one block → verify: one bundle out.
6. Slack module sends the joined text → verify: one message, all items listed.

Notice the rhythm: split, work, gather. Once that pattern is in your hands, the rest of Make is picking the right module and mapping the right field. The next phase covers what happens when a step fails mid-run - and the operations cost that all this iterating quietly racks up.


---

# Error Handling, Scheduling & Operations Cost

A scenario that works in a clean test and a scenario that survives the real world are two different things. The real world hands you a missing field, a rate-limited API, a malformed date. This phase is about the parts that keep automations alive - and the pricing model that decides what they cost.

## What happens when a module fails

By default, if a module errors, the whole run stops. The bundle that was in flight is abandoned, the scenario logs the failure, and - if it keeps happening - Make eventually deactivates the scenario and emails you. That last part bites people: a scenario you thought was running has been silently off for a week because of repeated errors.

You override the default by attaching an **error handler** to a module. Right-click a module, add an error handler, and you get a small branch that only runs *when that module fails*. On that branch you place a **directive** that tells Make what to do instead of stopping.

The directives, in plain terms:

| Directive | What it does | When to use |
|---|---|---|
| **Resume** | Substitute a value and carry on | A lookup failed but you have a sensible default |
| **Ignore** | Drop this bundle, keep the run going | One bad item shouldn't kill a batch |
| **Rollback** | Stop and undo this run's changes | Default; safest when steps must be all-or-nothing |
| **Commit** | Stop but keep what's been done | You want partial work preserved |
| **Break** | Park the bundle, retry it later | Transient failures (rate limits, brief outages) |

**Break** is the one worth knowing well. It saves the failed bundle into an **incomplete executions** queue and retries it on a schedule you set. So when an API is briefly down, you don't lose the data - Make holds it and tries again. You can also open the queue and re-run items by hand after you've fixed whatever was wrong.

A word on **rollback**: Make can undo changes within a run for apps that support transactions, but it can't un-send an email or un-post a Slack message - those leave the building immediately. Rollback protects database-style steps, not actions that touch the outside world. Order your modules with that in mind: do the reversible, internal work first, and the irreversible "tell someone" steps last.

```mermaid
flowchart LR
  A[Create record] --> B[Charge customer]
  B -->|fails| E[Error handler: Break]
  E --> Q[(Retry queue)]
  B -->|ok| C[Send receipt]
```

## Scheduling: when does it run

Every scenario has a schedule, set with the clock icon on the trigger. The main choices:

- **Immediately** - for instant/webhook triggers, runs the moment data arrives.
- **At regular intervals** - every N minutes. The floor depends on your plan; lower-tier plans can't go below a 15-minute interval, paid plans go tighter.
- **Specific days/times** - "weekdays at 9am," "the 1st of every month."

Interval is where cost and freshness trade off. A scenario polling every minute is sixty checks an hour whether or not anything changed - and every check that wakes up costs at least something. Most "watch for new X" jobs are fine at 15 minutes. Reserve tight intervals for things that genuinely need to be near-real-time, and prefer an instant webhook trigger over fast polling whenever the source app offers one.

## The operations model - read this before you build big

Make charges in **operations**. One operation is one module executing once. Not one scenario run - one *module*, one *execution*.

This is the number that surprises people, so make it concrete. A 5-module scenario that runs once uses roughly 5 operations. Fine. Now add an iterator that splits an array of 100 items, with 3 modules after it. Each of those 3 modules runs 100 times. That single run is 300+ operations. Run it hourly and you're at 200,000+ operations a month from one scenario.

```text
Scenario: webhook → iterator(100 items) → lookup → format → create
Per run:  1 + 1 + 100 + 100 + 100  ≈ 302 operations
```

The trap is that operations scale with your *data*, not with how many scenarios you have. People build a tidy little flow, test it on 3 rows, and ship it. Then real traffic arrives with 3,000 rows and the operation count explodes. Plans come with a monthly operations allowance; blow through it and the scenario stops until you top up or the month resets.

Things that quietly multiply operations:

- **Iterators** over large arrays - the single biggest cause.
- **Polling triggers** on tight intervals - they cost even when there's nothing new.
- **Routers** - each branch a bundle takes runs its own modules.
- **Loops and repeated lookups** - one API call per item adds up fast.

How to keep it sane:

- Filter **early**. A filter right after the trigger drops bundles before they run through (and pay for) the rest of the chain.
- Aggregate when you can. One bulk "create many records" call beats 100 single creates - both in operations and in API rate limits.
- Widen polling intervals to the slowest your use case tolerates, and switch to webhooks where possible.
- Watch the operations log. Make shows operations per run; if one scenario is eating your allowance, that's where to optimize.

The mental model to leave with: **a scenario's cost is its module count times how many bundles flow through it.** Keep the bundle count down (filter early, aggregate, sane intervals) and the module count lean, and Make stays cheap. Let an iterator run wild on production-sized data and the bill - or the hard stop when you hit your allowance - will find you. Build the error handling so failures retry instead of dying, schedule no faster than you need, and watch the operations count the way you'd watch any meter that bills by the unit.
