Jotform is a fast way to put a form in front of people and collect their email addresses — and, like every form builder, it's better at capturing addresses than at telling you which ones are real. Its email field confirms an address looks right; it can't confirm the mailbox exists, isn't a throwaway, or won't hard-bounce your first reply. This guide shows two practical ways to verify emails from Jotform with Qualisend: in real time, with a webhook that fires the moment a submission lands, and in bulk, by exporting your submissions to a spreadsheet. Neither needs a native plugin — there isn't one yet — just Jotform's built-in webhooks or its export button.
The short answer#
Pick the path that matches when you need the answer:
- Real time — point a Jotform webhook at a small serverless function. On every submission Jotform POSTs the form data to your endpoint; the function reads the email, calls the Qualisend API, and acts on the verdict — tag the contact, route it to the right list, or hold the welcome email for a bad address.
- Bulk — export your existing submissions to CSV or Excel, run them through Qualisend's bulk verification, and suppress the undeliverables before your next send.
Why Jotform's email field isn't enough#
Jotform's email question type runs a format check in the browser — it makes sure
there's an @, a domain, and no obvious typos. That's the same class of check a
regex does, and it fails for the same reasons:
format is not deliverability.
jane@gmial.com passes the format check. So does test@mailinator.com, and so
does a real-looking address at a domain that quietly went dark last year.
None of those are caught until you send — and by then a dead address is a hard bounce that chips at your bounce rate and sender reputation. Real verification adds the layers Jotform can't: a DNS/MX lookup and an SMTP mailbox probe, plus flags for disposable, role, and catch-all addresses. If that pipeline is new to you, what email verification actually checks is the primer.
Two ways to verify emails from Jotform#
The important constraint first: Jotform can't reliably block a bad email mid-form. There's no supported way, across every plan, to call an external API between fields and stop someone from submitting, so real-time verification runs just after submit, in a webhook — not as an inline gate. That shapes both paths.
| Path | When it runs | Best for |
|---|---|---|
| Real-time webhook | Instantly, per submission | Live funnels — tag, route, or hold follow-up before it sends |
| Bulk export | On demand, in batches | Existing submission backlogs and periodic list hygiene |
Path 1: real-time with a Jotform webhook#
Jotform can send every submission to a URL you control. Open your form and go to Settings → Integrations, search for Webhooks, and paste in your endpoint URL. Unlike some form tools that gate webhooks behind their top tiers, Jotform's Webhooks integration is available broadly, including on the free plan — your monthly submission count is what's capped by tier, not access to the webhook itself.
One Jotform-specific quirk shapes the code: Jotform doesn't POST clean JSON. It
sends the submission as form-encoded fields, where each answer is named after
its question — an email field usually arrives as something like q3_email. There's
also a rawRequest field holding a JSON string of the whole submission if you
prefer to parse that. Either way, your endpoint reads the form body, not
req.json().
Your endpoint is a serverless function that holds the API key and turns the verdict into an action. The pattern is the same one in the verify-at-signup guide: the key stays server-side, and you act on the result. Here it is as a Next.js Route Handler (check the developer docs for the exact endpoint path and request shape):
// app/api/jotform-webhook/route.ts
import { NextResponse } from "next/server";
// Placeholder — confirm the real path in /developers.
const QUALISEND_ENDPOINT = "https://api.qualisend.com/v1/verify";
export async function POST(req: Request) {
// Jotform POSTs form-encoded fields, not JSON.
const form = await req.formData();
// Jotform names email fields like q3_email — check yours in the builder.
const email = form.get("q3_email")?.toString();
if (!email) return NextResponse.json({ ok: true }); // nothing to verify
const res = await fetch(QUALISEND_ENDPOINT, {
method: "POST",
headers: {
// Store YOUR_API_KEY server-side, never in the browser.
Authorization: `Bearer ${process.env.QUALISEND_API_KEY!}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ email }),
signal: AbortSignal.timeout(4000),
});
if (!res.ok) return NextResponse.json({ ok: true, degraded: true }); // fail open
const { result } = await res.json();
// The submission already landed — route on the verdict instead of blocking.
if (result.status === "undeliverable" || result.sub_flags?.disposable) {
// Skip the welcome email, tag the contact for review, keep it off the main list.
}
return NextResponse.json({ ok: true, status: result.status });
}
Three things make this robust. Respond fast: Jotform expects a 2xx quickly,
so keep the handler lean and return promptly. Fail open: if the API times out
or errors, don't lose the lead — accept it and re-check later, which is why the
!res.ok branch still returns ok: true. And guard the endpoint: Jotform
doesn't sign its webhooks with a shared secret the way some tools do, so protect
the URL another way — keep it unguessable, and reject anything whose formID
doesn't match the form you expect before you spend a verification credit.
If your form has more than one email question, don't just grab the first one you
find — read the specific field name (q7_email, q12_workEmail, whatever the
builder assigned) so the right address is always the one you verify. You can see
each field's name in the Jotform builder or by inspecting a test submission's
payload once.
Downstream, the verdict is just a branch. A deliverable result flows straight
into your CRM or email tool; an undeliverable or disposable one gets tagged,
held back from the welcome sequence, or dropped into a review queue — whatever
your process needs. The webhook is the plumbing; the routing is yours.
The verification logic itself is language-agnostic; the same call works from a Python or PHP function if that's your stack, and the same webhook approach applies to any form tool — see verify emails from Typeform for a near-identical setup where the only real difference is how the payload is parsed. Only that parsing step is Jotform-specific; the verify-and-route half is the same everywhere.
Path 2: bulk-verify a CSV or Excel export#
If you already have a pile of submissions, or you'd rather clean on a schedule than wire up a webhook, go in batches. In Jotform, open your form's Submissions table (or Reports → Excel/CSV) and download the data. You'll get one row per submission with the email in its own column.
Then:
- Upload the file to Qualisend's bulk verification and let it run the full pipeline — MX, SMTP, and the disposable/role/catch-all flags — across every row.
- Download the annotated file. Each address comes back with a
status, areasoncode, and a 0-100score. - Suppress the undeliverables in whatever tool you actually mail from, and handle the risky rows with care. The end-to-end routine, including where each status belongs, is in how to clean an email list.
Bulk is the right tool for a backlog, but it's cleanup, not prevention: an address you catch here has usually already been sitting in your list. Pair a periodic bulk pass with the real-time webhook so new bad addresses are flagged the moment they arrive.
Acting on the verdict#
Whichever path delivers the result, the shape is the same — a status, a
reason, a score, and the sub_flags. Map each to an action:
| Result | What to do |
|---|---|
deliverable | Accept — add to your list and send normally. |
undeliverable | Suppress. Don't send; check the reason to see whether it's
a bad domain or a dead mailbox. |
disposable flag | Reject or tag, depending on how strict your funnel is — see role, disposable & free addresses. |
risky / catch-all | Accept but segment. A catch-all domain accepts every address at the MX layer, so it can't confirm the individual mailbox — send cautiously. |
unknown | Accept and re-check later — the infrastructure didn't answer, so never drop a real lead over it. |
Frequently asked questions#
Can Jotform verify email addresses on its own?#
Only the format. Jotform's email field confirms an address is well-formed — it
has an @ and a domain — but it doesn't resolve MX records or probe the mailbox,
so a typo'd or disposable address that looks valid still gets through. Real
verification needs the DNS and SMTP layers a service like Qualisend adds on top,
which is what turns "looks valid" into "will actually deliver."
Do I need a paid Jotform plan to verify emails in real time?#
Not necessarily. Jotform's Webhooks integration is available across its plans, including the free tier, so you can wire up the real-time path without upgrading — what changes by plan is your monthly submission allowance, not access to webhooks. If you'd rather not run an endpoint at all, use the bulk path instead: export submissions to CSV or Excel and verify them in batches on any plan that lets you download results.
Can I block a bad email before the user finishes the form?#
Not reliably. Jotform has no supported way, across all plans, to call an external API mid-form and stop someone from submitting, so real-time verification runs just after submit, in the webhook. In practice that's fine: you verify within seconds and act before the address ever receives a message — you hold the welcome email, tag the contact, or route it to review rather than blocking the form itself.
Should I use the real-time webhook or the bulk export?#
Use the webhook when the timing matters — you want to greet, route, or suppress per submission as entries come in. Use bulk when you're cleaning a backlog or running periodic hygiene. Most teams do both: the webhook keeps new submissions clean, and an occasional bulk pass catches anything that slipped through or aged out since it was collected.
Ready to wire it up? Grab a scoped key and the exact request format in the developer docs, sanity-check a single address in the free email checker, or start with the 100 free credits on every plan to test the flow end to end.