Back to blog
Validation··11 min read·WillItInbox Team

How to Validate Emails at Signup in Real Time (Stop Bad Addresses at the

Real time email validation at signup: API call patterns, latency budgets, fail-open design, verdict handling matrix, and code engineers can ship today.

real time email validationEmail deliverability

Real time email validation means calling a verification API the moment a user types their address into your signup form — before the account exists, before a single email is sent. It catches typos, disposable domains, and dead mailboxes in under a second, so bad addresses never enter your database. This guide covers the economics, the architecture, the verdict-handling logic, and production-ready code.

The Economics: A Bad Address Costs You Forever, Validation Costs Milliseconds

Here's the math most teams do too late.

A bad email address that slips through your signup form doesn't cost you once. It costs you repeatedly, for as long as it sits in your list:

  • Hard bounces. Gmail has enforced hard 5xx rejections for non-compliant bulk senders since November 2025. Microsoft followed in May 2025. Every bounce from a dead address you could have caught counts against your sender reputation.
  • Wasted ESP quota. You pay per send or per contact. Sending welcome emails, onboarding sequences, and newsletters to addresses that never existed is a direct waste of money. At 5% bad data on a 100k list at typical ESP pricing, that's thousands of dollars a year — for nothing.
  • Poisoned engagement metrics. Dead addresses never open, never click. They drag your engagement rate down, and mailbox providers read low engagement as "this sender's mail is unwanted." Your real users' inbox placement suffers because of ghosts in your database.
  • Fake accounts. Disposable email addresses are the standard tool for free-trial abuse, promo-code farming, and spam-account creation. Every one you accept is a support burden and a skewed MAU number.
  • The cleanup tax. Validating a list after the fact costs the same per address as validating at signup — except by then you've already paid the bounce, the quota, and the reputation damage.

Now the other side of the ledger: a real-time validation API call takes 50–300ms and costs fractions of a cent. WillItInbox's free tier gives you 150 credits a month; paid plans are non-expiring credits, so a Solo plan's 12,000 credits can cover a slow-growth signup flow for a very long time.

Catch it at the door or pay for it forever. That's the whole argument.

Why Client-Side Validation Isn't Enough

Every signup form already has some client-side validation. It's necessary — and completely insufficient.

What regex actually catches

A format check catches format. Nothing else:

js
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
EMAIL_RE.test("[email protected]");    // true — typo domain
EMAIL_RE.test("[email protected]"); // true — disposable
EMAIL_RE.test("[email protected]"); // true — no MX

All three sail through. All three are worthless addresses. Regex can't tell you whether the domain has MX records, whether the mailbox exists, whether it's a disposable provider, or whether the user fat-fingered gmail.com.

HTML5's type="email" is even weaker — it accepts anything with an @.

Client-side checks earn their keep for one reason: instant feedback on obvious garbage (missing @, spaces) without a network round trip. Keep them. Just don't confuse them with verification.

The Real-Time API Call Pattern

This is the architecture that works in production. There are three decisions to get right: when to fire, how long to wait, and what happens when the API is down.

When to fire: on blur, not on submit (usually)

You have three trigger options:

TriggerUXAPI callsVerdict
On every keystroke (debounced)Instant feedbackMany (wasteful)Only for "did you mean" suggestions, if ever
On blur (field loses focus)Fast feedback while user is still on the formOne per addressRecommended default
On submitFeedback comes late; user has to go backOne per attemptFine for low-traffic forms; combine with blur for best UX

On blur is the sweet spot. The user has finished typing, you fire one call, and if there's a problem they see it while the form is still in front of them — not after they've mentally moved on. Fire again on submit as a safety net (the user may have edited the field without re-blurring).

Add a short debounce (~300ms) even on blur, and only fire if the address changed since the last check. Cache the result client-side keyed by the normalized address.

Timeout strategy: 2–3 seconds max, then get out of the way

Validation involves DNS lookups and SMTP probes. P95 latency for a good API is under a second, but tails exist. Your form's responsiveness is more important than any single verdict.

  • Set a hard client-side timeout of 2–3 seconds.
  • On timeout, treat the result as unknown and let the signup proceed.
  • Never show a spinner that blocks the submit button.

Fail-open is not optional

This is the design principle engineers get wrong most often: validation must never be a single point of failure for signups. If your validation API times out, 500s, or your credits run dry, signups must continue. Log the failure, queue the address for async validation later, and move on.

A validation outage that blocks registrations costs you more than every fake signup combined ever will. Build the fail-open path first, then the validation.

js
async function validateEmail(email) {
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), 2500); // 2.5s hard cap
  try {
    const res = await fetch("/api/validate-email", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ email }),
      signal: controller.signal,
    });
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return await res.json(); // { verdict, suggestion, ... }
  } catch (err) {
    // FAIL OPEN: timeout, network error, API down → allow signup
    console.warn("email validation unavailable:", err.message);
    return { verdict: "unknown", validationSkipped: true };
  } finally {
    clearTimeout(timer);
  }
}

The Verdict Handling Matrix

A good validation API returns more than valid/invalid. WillItInbox's validator runs 12 layers — syntax, DNS, MX, SMTP, catch-all detection, disposable, role-based, provider identification, domain age, typo suggestion, suppression, spam trap — and gives you a verdict plus a confidence score. Here's how to handle each outcome at signup:

VerdictExampleSignup action
valid[email protected]Allow. Done.
invalid (syntax/no MX/dead mailbox)jane@gnail (no domain)Block. Show specific error.
typo[email protected]Allow after inline suggestion: "Did you mean [email protected]?"
disposable[email protected]Block or flag — depends on your abuse model (see below)
role-basedinfo@, support@Allow, but tag. Lower engagement expected; consider excluding from onboarding drip.
unknown / catch-all[email protected]Allow, but put double opt-in behind it as a safety net.
validation skipped (timeout)Allow. Queue for async re-check.

Typo handling: the highest-ROI UX in this entire post

Typos are the most common bad-address cause at signup — real users, real intent, one wrong character. gamil.com, gmal.com, hotmial.com, yaho.com. Blocking them loses a customer. Accepting them loses the customer and burns a bounce.

The fix is an inline suggestion. When the API returns a typo verdict with a suggestion, render it as a one-click correction:

html
<div class="email-hint" hidden>
  Did you mean <button type="button" id="suggestion">[email protected]</button>?
</div>
js
if (result.verdict === "typo" && result.suggestion) {
  hint.hidden = false;
  suggestionBtn.textContent = result.suggestion;
  suggestionBtn.onclick = () => {
    emailInput.value = result.suggestion;
    hint.hidden = true;
    emailInput.focus();
  };
}

One click, the user fixes it, everybody wins. Teams that add this pattern routinely see 1–3% of all signups get corrected — that's 1–3% of your list saved from guaranteed bounces.

Try it: paste gamil.com, a Mailinator address, and a real address into the free email validator and look at the verdicts. No signup needed.

Disposable addresses: block or flag?

Depends on your business model:

  • Free trial / freemium SaaS: block. Disposable addresses are overwhelmingly trial abuse and promo farming.
  • Content gate / newsletter: flag and allow, but route them to a separate segment. Some users legitimately value privacy; you can prune them later based on engagement.
  • Anything with paid conversion: block, with a polite message: "Please use a permanent email address."

Catch-all and unknown: allow, but don't trust blindly

Catch-all domains accept mail to any address, so SMTP-level verification can't confirm the mailbox exists. The verdict isn't "bad" — it's "unverifiable." The right move is to allow the signup and let double opt-in do the verification work: if they click the confirmation link, the address is real.

The nuance — when unknown is fine and when it's a risk signal — deserves its own read: Email Validation API: Risky, Catch-All, and Unknown Results Explained.

Server-Side Enforcement: Never Trust the Client Alone

Everything above runs in the browser, which means everything above can be bypassed with curl. Bots don't run your JavaScript. The client-side check is a UX feature; the server-side check is the actual gate.

Your signup endpoint must re-validate before creating the account:

js
// POST /signup — Node/Express
app.post("/signup", async (req, res) => {
  const { email, password } = req.body;

  const result = await validateServerSide(email); // same API, server key
  // validateServerSide itself fails open → returns { verdict: "unknown" } on error

  switch (result.verdict) {
    case "invalid":
      return res.status(422).json({ error: "That email address doesn't exist." });
    case "disposable":
      if (BLOCK_DISPOSABLE) {
        return res.status(422).json({ error: "Please use a permanent email address." });
      }
      // else: allow but tag
      break;
    case "typo":
      // Don't block — the client should have caught it. Return suggestion
      // in case a legit client missed it.
      return res.status(422).json({
        error: "Possible typo in your email.",
        suggestion: result.suggestion,
      });
    // valid, role-based, catch-all, unknown → proceed
  }

  const user = await createUser({ email, password, emailFlags: result });
  if (["catch-all", "unknown", "role-based"].includes(result.verdict)) {
    await sendDoubleOptIn(user); // safety net for unverifiable addresses
  }
  return res.status(201).json({ ok: true });
});

Server-side specifics that matter:

  1. Same fail-open rule. Wrap the validation call in a try/catch with a 2–3s timeout. Validation down ≠ signups down.
  2. Keep the API key server-side. Never ship it to the browser. The client hits your /api/validate-email endpoint, which proxies to the validation API with your key attached.
  3. Rate-limit your proxy endpoint. Otherwise someone uses your form as a free validation oracle. One call per email per session, plus IP-based throttling.
  4. Store the verdict. Persist the validation result on the user record. It's useful forever: segmenting role-based addresses out of drip campaigns, prioritizing re-verification, debugging deliverability later.
  5. Re-check asynchronously. Anything that failed open at signup goes into a queue for validation retry. If it comes back invalid, suppress before the first campaign goes out.

The full endpoint reference, response schema, and confidence-score semantics are in the email validation API docs. Free tier is 150 credits/month — enough to build and test the whole integration before you spend anything.

The Privacy Angle: GDPR and Data Minimization

Sending a user's email address to a third-party API during signup is processing personal data. It's legitimate — and under GDPR's legitimate-interest basis, typically lawful for fraud prevention and service delivery — but do it properly:

  • Data minimization. Send the email address and nothing else. No names, no IPs, no form metadata. The validator needs one string.
  • Check the processor's retention. WillItInbox deletes test/validation data within 24 hours and is GDPR compliant — confirm the same for any provider you evaluate. An API that builds a database of your users' addresses is a liability, not a vendor.
  • Get a DPA. If you're processing EU residents' data through any subprocessors, you need a Data Processing Agreement in place. Ask for it before you integrate, not after.
  • Update your privacy notice. One line: email addresses are verified via a third-party validation service at signup. Cheap transparency.
  • Don't log raw addresses in client-side analytics. The typo-suggestion UI means the address passes through DOM events — make sure your session-replay and analytics tooling masks it.

None of this blocks the integration. It's a day of legal hygiene that keeps a genuinely useful feature from becoming a compliance finding.

Don't Forget Deliverability on the Other Side

Validating signups keeps bad addresses out. But your confirmation and welcome emails still have to reach the good ones. If your signup confirmation lands in spam, double opt-in silently fails and your "verified" funnel leaks.

Before you ship: run your confirmation email through the deliverability tester — it checks your SPF/DKIM/DMARC, headers, content, and links against 70+ signals and gives you a prioritized fix list in about 15 seconds. And if you haven't audited your domain authentication lately, the SPF, DKIM, and DMARC explainer covers the setup that Gmail and Yahoo now hard-require for bulk senders.

Pre-Launch Checklist

  • [ ] Client-side regex for format, inline errors, no false confidence
  • [ ] Validation API fired on blur (debounced, change-detected) + again on submit
  • [ ] 2–3s hard timeout, both client and server
  • [ ] Fail-open on every error path — timeout, 5xx, credit exhaustion
  • [ ] Typo verdict → one-click "did you mean" suggestion
  • [ ] Disposable → block or flag, per your abuse model
  • [ ] Catch-all/unknown → allow + double opt-in
  • [ ] Server re-validates before account creation; API key never in the browser
  • [ ] Proxy endpoint rate-limited
  • [ ] Verdict stored on the user record; failed-open signups queued for async re-check
  • [ ] DPA signed, privacy notice updated, 24h-retention confirmed
  • [ ] Confirmation email tested for deliverability

Frequently asked questions

Sources reviewed

Factual review: June 13, 2026 by WillItInbox Editorial.

Keep reading