How to Verify an Email Address Exists (2026 Guide)

Use AI to summarize this article and ask questions

Grant Ammons
Grant Ammons – Founder May 19, 2026

How to Verify an Email Address Exists (2026 Guide)

The complete guide to verifying whether an email address exists. How mailbox checks work, what verification services do, and how to pick one for your stack.

TL;DR: Verifying that an email address exists — that the specific mailbox is real, not just that the domain accepts mail — requires talking to the mail server directly via SMTP. You can do this yourself with surprising difficulty, or call a verification API that handles the operational pain. This guide explains how mailbox checks work and how to pick a service.

You can verify that an email address looks valid in microseconds — regex covers that. You can verify that the domain exists with a DNS lookup. But verifying that the specific mailbox exists is a fundamentally different problem. It requires connecting to the recipient’s mail server and asking, politely, whether the address is real.

That conversation is the SMTP probe. This guide explains what’s happening under the hood, why most people use a verification API rather than rolling their own, and what to evaluate when picking one.

What it means for an email address to “exist”

Before talking about mechanics, it’s worth being precise about the question. “Does this email exist?” can mean several things:

  • Syntactically validbob@gmail.com follows email format rules
  • Domain has MX recordsgmail.com is configured to receive mail
  • Mailbox is realbob@gmail.com specifically routes to an inbox someone could read
  • Mailbox is active — that inbox is currently monitored, not abandoned
  • Mailbox is safe to email — not a disposable, role-based, or spam-trap address

The first two are answered by regex and DNS in milliseconds. The third requires an SMTP probe. The fourth is essentially impossible to verify externally (Gmail won’t tell you whether someone logs in). The fifth requires a maintained list of disposable domains, role patterns, and known traps.

When most people say “check if email exists,” they mean a combination of #1, #2, #3, and #5. That’s what a good verification service delivers.

How an SMTP mailbox check works

The mechanics, simplified:

  1. Lookup the domain’s MX record. This tells you which mail server handles that domain.
  2. Open a TCP connection to port 25 on the mail server.
  3. Issue SMTP commands as if you were going to send mail: HELO, MAIL FROM, RCPT TO.
  4. Watch the RCPT TO response. If the server returns 250, the mailbox exists. If 550, it doesn’t.
  5. Close the connection without actually sending any message.

The actual transcript looks like this:

S: 220 mx.example.com ESMTP ready
C: HELO yourcompany.com
S: 250 mx.example.com Hello
C: MAIL FROM: <verifier@yourcompany.com>
S: 250 OK
C: RCPT TO: <bob@example.com>
S: 250 OK            ← mailbox exists
C: QUIT
S: 221 Bye

If bob@example.com doesn’t exist, the server replies 550 No such user (or similar) to the RCPT TO command. You close the connection and you have your answer.

Why this is harder than it sounds

The naive version of an SMTP probe is roughly twenty lines of Python or Node. In production, the problems compound:

Servers don’t trust strangers

Mailbox providers know that SMTP probes are how spammers harvest valid addresses. Send a few probes from your IP and most large providers (Gmail, Outlook, Yahoo) will start refusing connections, slow-responding, or actively blocklisting you. Once your sender IP is dirty, every other email you send gets degraded delivery.

Catch-all servers lie

Many corporate domains are configured as catch-alls: they accept mail for any local part and decide later what to do with it. A 250 response from a catch-all is meaningless — it would say 250 to random-string-of-letters@theirdomain.com too. To detect this, you have to probe two or three random-looking addresses at the same domain and see if they all come back valid. If they do, you’ve found a catch-all and you can’t confirm individual mailbox existence.

The mechanics, in practice: after 250 OK on the real address, you immediately issue a second RCPT TO for a high-entropy string like zx9k7q-mhf2-3wpb@theirdomain.com. If that also returns 250, the server accepts anything for that domain — the address gets flagged accept_all rather than ok. This is common across Microsoft 365 tenants, Google Workspace catch-all aliases, and security gateways like Mimecast or Proofpoint that swallow all inbound traffic before forwarding. Treat accept_all addresses as deliverable-but-risky: fine for signup, skip for cold outreach.

Yahoo and the deliberate 250

Some providers refuse to play the SMTP probe game at all. Yahoo’s SMTP servers return 250 for every RCPT TO, valid or not, as a privacy-preserving anti-harvesting measure. Mail.com and a handful of European providers do the same. For these domains, no probe-based service can confirm mailbox existence — the protocol literally does not give you that information. A good verifier returns accept_all or unknown for these rather than pretending the synthetic 250 means the inbox is real.

This matters more since the Gmail and Yahoo bulk sender requirements took effect in February 2024. Senders over 5,000 messages per day must keep spam complaint rates under 0.3% with SPF/DKIM/DMARC properly configured, or their mail gets throttled. Cold campaigns sending to unverified Yahoo addresses now pay a real deliverability tax.

Greylisting

A common anti-spam technique: the server temporarily rejects the first probe with a 450 code and asks you to retry in a few minutes. If you don’t retry, you get no answer. If you retry too fast, you trigger more anti-spam heuristics.

Timeouts and partial failures

Probes that should complete in a few hundred milliseconds can take 30+ seconds when the server is overloaded or applying delays. Your code needs explicit timeouts, retry logic, and graceful degradation.

The combination is why most production signup flows delegate this to a verification service. The service maintains a pool of clean IPs, applies the right anti-greylisting backoff, batches probes by domain to avoid rate limits, and absorbs every operational headache so your application doesn’t have to.

What a good verification service does

Beyond the SMTP probe itself, a verification API is worth using because it adds the other layers most signup flows need:

  • Syntax + MX check — fast pre-screening before the SMTP probe is attempted
  • Disposable domain detection — Mailinator, Guerrilla Mail, 10minutemail, and the dozens of others have valid MX records and respond to SMTP. You need a maintained list to flag them.
  • Role-based account detectioninfo@, support@, noreply@, admin@. These pass SMTP but rarely have a human reading them.

Disposable domain detection — how the list is built

Disposable domains aren’t static. New ones spin up weekly — Temp-Mail clones, throwaway domains seeded into reCAPTCHA-busting tools, anonymizers. A good verifier maintains its list using three stacked signals: a curated registry of known services (Mailinator, Guerrilla Mail, 10minutemail, YOPmail, sharklasers.com, trbvm.com, and several hundred others), MX-record fingerprinting (many disposables route through the same mail backends), and pattern matching on newly-registered domains sharing infrastructure with known disposables.

Apple’s privacy relay (@privaterelay.appleid.com) and Firefox Relay (@mozmail.com) are a separate category — forwarding services, not disposables. They deliver mail reliably, so most verifiers flag them as risky rather than email_invalid. Fine for signup, but a hard “do not contact” for cold outreach since the user opted into the relay specifically to avoid being marketed to.

Role-based account list

The role-based prefixes flagged by most verifiers (RFC 2142 specifies many) fall into three buckets:

  • Generic inboxes: info, contact, hello, mail, enquiries
  • Function-specific: support, help, sales, marketing, billing, hr, careers, press
  • Technical: admin, webmaster, postmaster, abuse, security, noreply, no-reply

A role-based address passes SMTP because the mailbox is real — but it’s almost always a shared inbox or redirect, not a person. Flag and reject on signup unless your product specifically serves teams.

  • Spam-trap matching — addresses seeded by mailbox providers and security services to catch lazy senders. Emailing one usually kills your sender reputation for weeks. A good API matches against aggregated trap databases.
  • Catch-all detection — explicit flagging when SMTP probes can’t confirm individual mailbox existence.

Truelist’s verify_inline endpoint runs all of these in a single network call:

curl -X POST 
  -H "Authorization: Bearer YOUR_API_KEY" 
  "https://api.truelist.io/api/v1/verify_inline?email=bob@example.com"

Response:

{
  "emails": [
    {
      "address": "bob@example.com",
      "email_state": "ok",
      "email_sub_state": "email_ok"
    }
  ]
}

email_state is the headline result (ok, email_invalid, risky, accept_all, unknown); email_sub_state is the reason behind it (is_disposable, is_role, failed_mx_check, failed_smtp_check, etc.). See the email validation API guide for the full schema.

Picking a verification service

A short checklist when evaluating providers:

  • Pricing model. Per-credit pricing gets expensive fast on signup flows. Flat-rate pricing is friendlier when you’re integrating into something you’ll call thousands of times a month.
  • Latency. A full SMTP probe takes hundreds of milliseconds. For signup forms, look for a fast path that skips SMTP (Truelist exposes this via checks=syntax,mx,disposable,role, returning in under 200ms).
  • Bulk endpoint. Validating one address inline is one shape of need. Validating a CSV of 10,000 contacts is another. Make sure both paths exist.
  • Response detail. A good API tells you why an address failed, not just that it did. That’s how you write useful error messages back to the user.
  • Free tier. A meaningful free tier (100+ validations) lets you wire up the integration and test it end-to-end before committing.

Truelist offers all of the above with unlimited validations on a flat monthly rate. The 100-call free tier is enough to integrate into a signup flow and test it.

How the major providers compare in 2026

All major providers do syntax, MX, SMTP, disposable, role, and catch-all checks — the differences are pricing model, latency, and reporting honesty.

  • Truelist — Flat monthly pricing with unlimited validations on most plans. Sub-200ms fast path via checks=syntax,mx,disposable,role. 100-validation free tier.
  • ZeroBounce — Per-credit pricing, AI deliverability scoring, 100/month free tier. Per-credit cost compounds quickly on high-traffic signup flows.
  • NeverBounce — Per-credit with discounted bulk tiers. Solid bulk flow, smaller free tier.
  • Kickbox — Per-credit with a “Sendex” deliverability score. Known for honest catch-all reporting rather than inflating deliverability rates.
  • Bouncer — Per-credit and subscription plans. European-based, GDPR-positioned.
  • MillionVerifier — Lowest per-credit cost in the category, thinner API. Useful for one-time list cleaning, harder as a per-signup verifier.

Per-credit pricing wins when cleaning a static list once a quarter; flat-rate wins when verification is wired into every signup, password reset, and contact form. See also free email validation tools and bulk email verifier options.

How to use it in your stack

The minimum production-grade pattern is two checks: syntax on the client (instant feedback), verification API on the server (catches everything else).

// Server-side, on form submit
async function onSignup(email) {
  // 1. Fast verification (sub-200ms, no SMTP)
  const url = new URL('https://api.truelist.io/api/v1/verify_inline')
  url.searchParams.set('email', email)
  url.searchParams.set('checks', 'syntax,mx,disposable,role')

  const response = await fetch(url, {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${process.env.TRUELIST_API_KEY}` },
  })
  const { email_state, email_sub_state } = (await response.json()).emails[0]

  if (email_state === 'email_invalid') return reject('Invalid email address.')
  if (email_sub_state === 'is_disposable') return reject('Disposable email not allowed.')

  // 2. Create the user. Queue the full SMTP probe as a background job.
  const user = await createUser(email)
  await queue.add('verify-email-full', { userId: user.id, email })
  return { ok: true, userId: user.id }
}

The same call from Python with requests:

import os
import requests

def verify_email(email: str) -> dict:
    response = requests.post(
        "https://api.truelist.io/api/v1/verify_inline",
        params={"email": email, "checks": "syntax,mx,disposable,role"},
        headers={"Authorization": f"Bearer {os.environ['TRUELIST_API_KEY']}"},
        timeout=5,
    )
    response.raise_for_status()
    return response.json()["emails"][0]

result = verify_email("bob@example.com")
if result["email_state"] == "email_invalid":
    raise ValueError("Invalid email address")
if result["email_sub_state"] == "is_disposable":
    raise ValueError("Disposable email not allowed")

Or from the command line for a quick smoke test:

curl -X POST 
  -H "Authorization: Bearer $TRUELIST_API_KEY" 
  "https://api.truelist.io/api/v1/verify_inline?email=bob@example.com&checks=syntax,mx,disposable,role"

For language-specific implementations, see JavaScript email validation, Python email validation, and PHP email verification. For the full API response schema, see email validation API. For a sister guide on validating addresses (rather than confirming mailbox existence), see how to see if an email address is valid.

Related concepts worth knowing

Mailbox existence is one slice of email hygiene. Adjacent topics: MX record lookup for the DNS layer underneath, why emails bounce back and the email bounce checker for what happens when verification is skipped, email sender reputation score for the long-term cost of bad addresses, email blacklist removal if your IP ends up on a blocklist, what is SMTP authentication for the protocol mechanics, email list cleaning services for the bulk workflow, and format of an email address for the syntax layer.

FAQ

Can I tell if an email exists without sending to it? Yes, for most domains. An SMTP probe issues RCPT TO without ever sending a DATA payload, so no message is delivered. The exception is providers like Yahoo that return 250 for every address regardless of mailbox status — for those, no probe-based method can confirm existence externally.

What does accept_all mean in a verification response? The domain is configured as a catch-all: it accepts mail for any local part and decides later what to do with it. The verifier could not confirm whether the specific mailbox is real. Treat as deliverable-but-risky: fine for signup, skip for cold outreach.

How accurate are email verification services? For domains that respond honestly, 95–98% accuracy is the realistic ceiling. The remaining gap is catch-all domains, Yahoo-style anti-harvesting responses, and inboxes that exist but are abandoned. Any vendor claiming 99%+ across all providers is either cherry-picking the test set or counting catch-all responses as confirmed-valid.

Will running SMTP probes from my own server hurt my deliverability? Yes, eventually. Mailbox providers track which IPs send probes and may degrade or refuse mail from them. This is the main reason teams use a verification API — the service maintains a separate pool of IPs for probing, isolated from your sending reputation.

How often should I re-verify addresses on my list? For active marketing lists, every 3–6 months. Mailboxes go dormant, employees change jobs, domains migrate to new providers. Re-verifying before a major campaign is cheaper than the deliverability hit from bouncing a few hundred dead addresses at once.

Ready to put Truelist
to the test?

Find out if Truelist is right for you in under 10 minutes.

Free plan available. No credit card required.