# How to validate email in Make (formerly Integromat)

_2026-10-16 · Boundstone (https://boundstone.io/blog/validate-email-make)_


Make (the automation platform formerly called Integromat) runs your scenarios on its own servers, which makes it a sound place to check an email address before it reaches your CRM, your mailing list, or a downstream webhook. The catch: there is no native Boundstone module in Make. Not yet — a native integration is planned. Until then you call the API the same way you call any REST service in Make: through the built-in HTTP module. This walks through the whole thing, including the one filter that does most of the work.

## Check whether you need an API call at all

Before you add a module, be honest about the job. If you are validating a single address by hand, use the free keyless [email validator](/tools/email-validator) — no key, no scenario, no credits. If you only need to reject text that isn't shaped like an email, Make's built-in Text parser (Match pattern) with a simple regex will catch `not-an-email` before you spend anything.

Those cover syntax. What they can't tell you is whether the domain actually accepts mail, whether it's a throwaway disposable address, or whether it's a `role_account` like `info@` or `support@`. That is the layer the API adds, and it is the reason to make the call.

## There is no Boundstone module — use HTTP "Make a request"

In your scenario, add the module named **HTTP > Make a request**. This is Make's generic HTTP client, and it is what every service without a dedicated app gets wired through, Boundstone included. Configure it like this:

- **URL** — `https://api.boundstone.io/v1/verify/email`
- **Method** — `POST`
- **Headers** — add one: name `Authorization`, value `Bearer bs_live_YOUR_KEY`
- **Body type** — `Raw`
- **Content type** — `application/json`
- **Request content** — the JSON below, with the address mapped from an earlier module

```json
{ "email": "{{1.email}}" }
```

`{{1.email}}` is Make's mapping syntax — swap it for whichever field carries the address (a form submission, a new CRM row, a spreadsheet cell). Finally, set **Parse response** to **Yes** so Make turns the JSON reply into fields you can map in later modules.

## Keep the key in the module, not in the open

Your `bs_live_` key is a server-side secret. Make scenarios run server-side, so pasting it into the module header keeps it off the browser — good. Keep it that way: don't map the key into a field that gets written back to a form, logged to a public channel, or returned in a webhook response. If you call the API from more than one module, store the key once in a Make connection or keychain and reference it, rather than copying the string around.

## Read the response and filter on disposable

A verified address comes back like this:

```json
{
  "valid_syntax": true,
  "domain": "example.com",
  "mx_found": true,
  "disposable": false,
  "role_account": false,
  "free_provider": false,
  "checks": {
    "performed": ["syntax", "mx", "disposable_list", "role_list"],
    "not_performed": ["smtp_mailbox", "catch_all"]
  }
}
```

Now add a **Filter** on the link leaving the HTTP module (or a **Router** if you want to send good and bad addresses down separate paths). The condition that stops most junk:

- **Label** — `Deliverable, not disposable`
- **Condition** — `{{2.disposable}}` `Equal to` `false`
- add a second, ANDed condition: `{{2.mx_found}}` `Equal to` `true`

Anything failing the filter never reaches the modules downstream. If you'd rather sort than block, a Router with two routes — one where `disposable` is `true`, one where it's `false` — lets you log throwaways separately instead of dropping them. The `free_provider` flag is there too if you want to treat Gmail and Outlook addresses differently; note it is a returned flag, not one of the checks Boundstone ran.

## What "valid" actually means here

The `checks` object is the point of the whole exercise, so read it before you trust a green result. `performed` lists exactly what was done: `["syntax", "mx", "disposable_list", "role_list"]`. `not_performed` lists what was not: `["smtp_mailbox", "catch_all"]`.

That second array is the honest part. Boundstone does not open an SMTP session to knock on the mailbox, and it does not probe for catch-all domains — so it will never tell you a specific inbox exists. It tells you the address is well-formed, the domain accepts mail, and it isn't a known disposable or role address. For gating a signup or cleaning a list, that is usually the decision you needed. When you want more, the not_performed list is your map of what still has to be checked by other means.

## The short version

- There is no native Boundstone app in Make (planned); use **HTTP > Make a request**.
- `POST https://api.boundstone.io/v1/verify/email`, header `Authorization: Bearer bs_live_...`, body Raw / `application/json`, `{"email": "{{mapped}}"}`, Parse response **Yes**.
- Filter on `disposable = false` (and `mx_found = true`); use a Router to sort instead of block.
- Keep the `bs_live_` key in the module or a connection — never in a client-facing field.
- Read `checks.not_performed` — `["smtp_mailbox", "catch_all"]` — so "valid" means what you think it means.

The same generic-HTTP pattern works in other tools; if you're on a different stack, the [n8n walkthrough](/blog/validate-data-n8n) does this with the HTTP Request node. The full field reference, bulk CSV, and the phone and IP endpoints are in the [docs](/docs). The free tier is 250 credits a month, no card, and the credits don't expire — enough to wire this up and run it against a real list before you decide anything.
