Verifying that an email exists without sending anything sounds like magic, but it is just abusing the SMTP protocol as RFC 5321 designed it 20 years ago. The destination domain's server is required to tell us whether it accepts or rejects a recipient before we send the message body. We leave before sending anything.
The handshake, step by step
When a mail server wants to deliver a message to maria@company.com, it does exactly these steps:
- Resolves DNS/MX of
company.comto find the mail server. - Opens a TCP connection to port 25 (or 587) of that server.
- Reads the banner (
220 mail.company.com ESMTP). - Sends
EHLOand receives supported extensions. - Sends
MAIL FROM:<noreply@byebouncer.com>and the server accepts. - Sends
RCPT TO:<maria@company.com>. This is the key: the server replies whether that mailbox exists and accepts mail. - Normally it would continue with
DATAand the message body. We cut off withQUIT.
The server never saw a message, never stored it in the mailbox, never flagged it as spam. For it, this was a connection that closed before starting. For us, its reply to RCPT TO was all the information we needed.
Replies that matter
SMTP codes are 3 digits. What we read on RCPT TO:
250: accepted. Mailbox exists (or the domain is catch-all; see below).550: rejected. Mailbox does not exist or was deleted.452: mailbox full. Exists but cannot receive more now.450: greylisting. Asks to retry later.421: temporary server limit. Retry later.
The traps
The protocol assumes an ideal world; reality has nuance.
Catch-all
Many domains configure their server to accept any address and then, internally, decide what to do. A 250 on a catch-all does not mean the mailbox exists — it means the server will not tell you whether it exists. We detect it by probing a random address from the same domain first: if it is also accepted, the domain is catch-all and we mark the result as unknown.
Big providers that will not cooperate
Yahoo, for example, accepted any RCPT TO for years and did real validation during DATAto avoid leaking information to scrapers. Microsoft has similar rules with reputation-based blocks. When this happens, we return provider_blocked as a neutral signal: not evidence that the email is invalid, just evidence that the provider did not cooperate.
Greylisting and timeouts
A server with greylisting active replies 450 the first time and accepts on retry, filtering spam that does not retry. We do not retry infinitely — we return unknown with the greylistingsignal. In production that lets you decide whether to treat as review or retry later.
Per-domain rate-limiting
If you query 10,000 gmail.com emails in 30 seconds, Google bans your IP. We throttle the queries we send to each domain to protect our IP reputation (which is shared among all our customers). When the limit kicks in we return smtp_domain_rate_limited and the result relies on previous layers (syntax, MX, domain classification).
Why this matters for your bounces
Sending to a mailbox you already tested with SMTP probing and that returned 550 is the fastest way to ruin your domain reputation. ESPs like SendGrid, Postmark or Resend measure your bounce rate and may suspend accounts above 5%. Verifying before sending brings that number to 0 even on old lists.