You can verify emails with Make (formerly Integromat) today, even though there is no branded Qualisend module in the app yet. The pattern is to build a scenario around the generic HTTP module: a trigger fires when a new address arrives, an HTTP request POSTs that address to the Qualisend API, and a Router or Filter reads the verdict and forks the flow — so only deliverable addresses continue on to your ESP or CRM, and risky or undeliverable ones get parked. This guide builds that scenario end to end.
The short answer#
There is no native app to install right now (it is on the roadmap), so the
supported pattern is a three-part scenario: a trigger (new form submission,
new row, or a custom webhook you point a form at), an HTTP → Make a request
module that calls the verification API with the email, and a Router with
per-route filters that read the returned status and decide what happens next.
When the response says the mailbox check is still pending, a short Sleep and a
GET on the returned job fetch the final verdict first. Keep your API key in the
module's headers — never in a public form field — and set
the HTTP module to keep running if the API ever errors, so a transient hiccup
never drops a real lead.
Two ways to verify emails with Make#
Before wiring anything up, pick the pattern that matches how fresh the data needs to be:
- Real-time, per-submission (a scenario). Every new address is verified the moment it arrives and routed on the spot. This is the main subject of this guide and the right choice when the verdict changes what happens next — gating a double opt-in email, tagging a lead, or skipping a fake signup.
- Batch, after the fact (a CSV). Let submissions pile up in a sheet or your ESP, export them periodically, and run them through a bulk verification job. Simpler, cheaper per address, and a better fit when you just need a clean list before a send rather than an instant decision.
Most teams end up doing both: a scenario on the live intake, plus a monthly list clean to catch addresses that have gone stale since they signed up.
Step 1: the trigger#
Start the scenario with whatever captures the address. Make has hundreds of trigger modules — "Watch Responses" in a forms app, "Watch Rows" in Google Sheets or Airtable, "New Lead" in a CRM. If your form tool has no dedicated Make module, drop in a Custom webhook as the first module and point your form's webhook URL at it; Make generates a unique URL and shows you the incoming data structure as soon as the first submission lands.
Whatever you pick, the important output is a field holding the email address, which
later modules reference as a mapped token — Make shows these as colored pills you
click into a field, drawn from the trigger's output bundle. In the examples below
that token is written as {{1.email}}, where 1 is the trigger module.
Step 2: POST the address with the HTTP module#
Add a module and choose HTTP → Make a request. This is the step that actually calls Qualisend. Configure it like this:
| Field | Value |
|---|---|
| URL | your verification endpoint — e.g. https://app.qualisend.com/api/v1/verify (check the API reference for the exact path) |
| Method | POST |
| Headers | Authorization: Bearer YOUR_API_KEY and Content-Type: application/json |
| Body type | Raw, with content type JSON (application/json) |
| Request content | JSON body with a single email key mapped to the trigger's email pill |
| Parse response | Yes — so later modules can map the returned fields directly |
Turn on Parse response so Make reads the JSON back into mappable fields instead of a raw string. In the Request content box, type the body and drop the trigger's email pill into it:
{ "email": "{{1.email}}" }
The request Make fires on your behalf looks like this — the placeholders are yours to fill in from the developer docs, which list the exact endpoint and show the request in several languages:
POST https://app.qualisend.com/api/v1/verify
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{ "email": "jane@example.com" }
Use a scoped key minted for this scenario rather than a full-access key, so if the scenario's execution history ever leaks the key can only verify addresses and read their results, nothing else. Never put the key in the form itself or any client-side field — it belongs only in the HTTP module's headers, which run server-side inside Make.
When you click Run once, Make shows the response bundle. You get back a
job_id and a result object holding a status, a reason code (null until the
mailbox check finishes), a 0–100 score, a set of sub_flags, and an smtp field
that says whether the mailbox check has finished. A fresh address that passes the
syntax and domain checks usually comes back roughly like this:
{
"job_id": "b7e4c2a0-1d3f-4e8a-9c6b-2f5a8d0e7c41",
"result": {
"status": "unknown",
"reason": null,
"score": 61,
"smtp": "pending",
"sub_flags": { "disposable": false, "role": false, "free_mail": false, "catch_all": false }
}
}
Those field names are what the next step branches on, so note how Make maps them —
you will reference result: status, result: score, and the individual
sub_flags in filters. For the full picture of what each status means and how the
pipeline arrives at it, see
how email verification works.
When the mailbox check is still pending#
smtp tells you whether result is final. cached or skipped means it is, so you
can route on it straight away. pending, the usual case for a fresh address, means
the SMTP mailbox check is still running and status is a provisional unknown.
Don't call /verify again for that address; fetch its job instead:
- Right after the HTTP module, add a Router with two routes: one filtered on
result: smtpequalspending, and a fallback route for everything else. - On the
pendingroute, add a Sleep module (under Tools) set to about 60 seconds. - Follow it with a second HTTP → Make a request module: method
GET, URLhttps://app.qualisend.com/api/v1/jobs/{{2.data.job_id}}?include=results(where2is the POST module), the sameAuthorizationheader, and Parse response turned on.
The job's own status reads completed once the check is done, and the final
verdict is the first item in its results array. For a deliverable address it looks
roughly like this:
{
"status": "completed",
"results": [
{
"email": "jane@example.com",
"status": "deliverable",
"reason": "accepted_email",
"score": 92,
"sub_flags": { "disposable": false, "role": false, "free_mail": false, "catch_all": false }
}
]
}
If the check is still running when the GET fires (a greylisting server can hold it
open for several minutes), the job and its item still read pending or processing;
the next step routes those to review instead of dropping them. Both routes from this
step end in the same verdict routes: on the pending route they read status from
the first item of the GET's results, on the fallback route from result: status on
the POST.
Step 3: branch on the verdict with a Router#
A verification result you do not act on is wasted credit. The whole point is to route addresses differently, and in Make that is the Router module.
Drop a Router at the end of each route from the previous step (after the GET on the
pending one) and it fans out into as many routes as you need. Each route gets its
own filter (click the wrench on the line leaving the Router) that tests the final
status:
| Route filter | What to do |
|---|---|
Status equals deliverable | Add the contact to your ESP or CRM and continue the funnel. |
Status equals risky or unknown | Add to a "needs review" list or tag it — don't hard-drop it. This bucket includes catch-all domains that can't be probed cleanly. |
Status equals undeliverable | Don't add it anywhere. Optionally log it to a sheet so you can spot a broken form field or a bad traffic source. |
Make evaluates routes left to right and, unless you mark a route as the fallback
(the route with no filter), every matching route runs — so keep your conditions
mutually exclusive on status to avoid a single address flowing down two branches.
Set the review route as the fallback rather than the undeliverable one, so an
address whose check is still pending or processing lands in review instead of
being dropped, and nothing slips through uncategorised.
You can branch on the sub-flags too. If your product is reputation-sensitive, add a
condition to the review route that also fires when sub_flags: disposable equals
true, even when the status is otherwise fine — the same call on disposable, role,
and free addresses that
the role, disposable, and free breakdown
walks through. A single Router filter accepts multiple AND/OR conditions, so you
can combine a status test and a sub_flags test on one route.
Don't let the HTTP module block a good lead#
One rule matters more than any branch: fail open. If the HTTP module errors —
the API is briefly slow, a plan limit is hit, a network blip — you do not want the
whole scenario to stop and silently swallow a real signup. Right-click each HTTP
module (the POST and the GET), choose Add error handler, and attach a Resume directive that
supplies a default bundle with status set to unknown. The scenario then keeps
running down a path that treats the address as "review later" rather than dropping
it. (You can also set the scenario's error handling to store incomplete
executions so failed runs queue for retry instead of vanishing.)
A verification API is a quality filter, not an authentication gate. Blocking a paying customer because of a transient outage is a far worse outcome than letting one questionable address through and catching it in your next list clean. The same fail-open principle underpins the serverless signup pattern, where a slow probe must never stall the form.
When a scenario is the wrong tool#
Make is glue, and glue has a cost: every verified address burns operations, and a per-submission HTTP call can add up at volume or feel like overkill when you do not need an instant decision. Reach for the batch route instead when:
- You are cleaning a list that already exists — thousands of historical contacts, not new intake. Export them and run a single bulk job.
- Your volume is high enough that per-operation pricing stings, and a nightly or weekly clean is fresh enough.
- You would rather not maintain a live scenario for a task that only needs to run occasionally.
For all three, skip the scenario: export the submissions to CSV from your form
tool, sheet, or ESP, and upload that file to Qualisend's bulk verifier. You get the
same status, score, and sub-flags per row, downloadable as a cleaned file you
can re-import. It is the lowest-effort way to keep a list healthy and your
bounce rate down without maintaining any
automation.
If you are weighing Make's HTTP approach against calling the API directly from your own backend, the API comparison lays out the trade-offs — a Make scenario wins on speed-to-set-up and needs no server, while a direct integration wins on cost and control at scale. The same HTTP module pattern also ports cleanly to a self-hosted n8n workflow if you outgrow Make's operations pricing.
Frequently asked questions
01Is there a native Qualisend module for Make?
Not right now. Qualisend's native platform integrations are being rebuilt, so there is no branded app to search for in Make's module list yet - it is on the roadmap. Until it ships, the supported way to verify emails with Make is the generic HTTP → Make a request module pointed at the Qualisend API, exactly as this guide describes. The HTTP approach is also more flexible: you control the request, the headers, and the routing logic.
02How many operations does the scenario use per email?
Roughly one operation per module that runs: the trigger, the HTTP request, and the Router's active route each count. So a single verified submission is a few operations, and 1,000 submissions is a few thousand - well within most paid Make plans. If your volume makes per-operation pricing sting, switch that traffic to the CSV export and bulk-verify route, which uses no operations at all.
03Which status should I let through to my email tool?
Only deliverable for a strict gate. If you want to keep more addresses, allow deliverable plus risky/unknown but route those into a separate, lower-priority segment rather than your main flow - many risky results are catch-all domains that may still deliver. Always reject undeliverable, and consider branching on the disposable sub-flag too if your product is reputation-sensitive.
04How do I test the scenario before turning it on?
Use Make's Run once button with a known-good address and a known-bad one, and watch the bubbles on the HTTP modules show the returned status. A known-good address usually comes back from the POST with smtp set to pending, so its final verdict shows on the GET after the Sleep. Then confirm each Router route lights up for the right input. For quick one-off spot checks outside Make, paste an address into the free email checker and compare the verdict to what your scenario returns.
Ready to build it? Grab a scoped key and the exact request shape from the developer docs, sanity-check any address in the free email checker, and start on the free plan — 100 credits are enough to wire the whole scenario up and watch a bad address get filtered before it ever reaches your list.



