SMTP Handshake Explained with Code Examples for Email Verification Developers
Learn how the SMTP handshake works with real code examples. Perfect for developers building email verification systems. Reduce bounces and improve.
What Is the SMTP Handshake and Why Does It Matter for Email Verification?
You’re sending a verification request to an email address — but how do you know the inbox even exists? A failed send often isn’t about the address format. It’s about whether the domain’s mail server will accept mail at all.
The SMTP handshake is that first, invisible test. It’s the real-time protocol exchange where your client asks a mail server, "Can I send mail to this address?" The server replies with a simple yes or no — based on its actual routing rules. Skip this step, and you’re guessing. Get it right, and you cut false positives by 30% or more.
For email verification developers, understanding the SMTP handshake isn’t theoretical. It’s how you build systems that don’t rely solely on third-party APIs, which can be slow, costly, or inconsistent. With code examples, we’ll walk through how this handshake works in practice — exactly as it happens between servers, without magic.
Key takeaways
- The SMTP handshake is the first protocol-level test of an email address’s technical validity, based on the domain’s actual mail server behavior.
- Implementing the handshake reduces false positives by validating domains in real time, not just against format rules or cached third-party data.
- Understanding the handshake enables developers to build verification systems that are less dependent on external APIs, improving control, speed, and cost efficiency.
How the SMTP Handshake Works: A Developer’s Step-by-Step Breakdown
You’re verifying an email address by simulating the full SMTP handshake—connecting to the recipient’s mail server, identifying yourself, checking if the sender is accepted, validating the recipient, and only then sending the full message if everything checks out. This sequence mimics a real send, ensuring you catch invalid, blocked, or catch-all addresses before wasting bandwidth. It’s the backbone of accurate email verification.
The TCP and SMTP Exchange Sequence
Every SMTP session starts with a TCP handshake on port 25, 587, or 465. Once the connection is open, the server responds with a 220 status, meaning it’s ready to accept commands.
- Connect to the server over TCP on a standard port (25 for plain, 587 for submission, 465 for SSL/TLS). This is the foundation. Without a stable TCP link, no SMTP conversation happens.
- Send HELO or EHLO. The client identifies itself with a domain name, like
EHLO mailtester.com. The server responds with250if it recognizes the domain, confirming it’s willing to proceed. - Send MAIL FROM with the sender’s address, e.g.,
MAIL FROM:<[email protected]>. The server replies250if the sender appears valid and allowed—this checks sender reputation and authentication. - Send RCPT TO with the recipient’s address, like
RCPT TO:<[email protected]>. The server evaluates it immediately:250means the address is valid and accepts it;550or551indicates a non-existent, blocked, or invalid mailbox. - Only if RCPT TO succeeded, send DATA. If the server rejected the recipient earlier, there’s no need to send the full message body. This early rejection saves time and reveals issues like invalid domains or blocked addresses.
Why This Matters for Verification Developers
Verifying via real SMTP is not just a test—it’s a live interaction with real mail infrastructure. Servers like those at Gmail or Outlook respond based on their own policies for delivery. You’re not guessing; you’re checking actual feedback from the receiving end. This is how you catch fake or disposable addresses, role accounts like info@, or addresses behind greylisting delays.
For example, if a server returns 550 to RCPT TO, even before you send DATA, the address is guaranteed invalid—no delivery ever happens. That’s a clear signal to mark the email as invalid during bulk verification.
Using an email list verification tool with real SMTP testing gives you this accuracy without managing your own server or handling timeouts. It mirrors what a real email send would experience.
The process is defined in RFC 5321, the standard for SMTP. It’s not a suggestion—it’s how email infrastructure works at scale.
SMTP Handshake Code Example in Python for Real-Time Verification
You can simulate a real-time email verification handshake using Python’s built-in smtplib by connecting to a domain’s SMTP server on port 587, sending EHLO, MAIL FROM, and RCPT TO commands in sequence, and checking the response code after RCPT TO. A 250 response means the address likely exists; 550, 551, or 553 indicates invalid or rejected mailboxes. We’ll use non-privileged ports like 8025 during testing to avoid triggering spam filters.
Setting Up the SMTP Connection
Start by importing smtplib and socket. Use socket.create_connection() to connect to the recipient’s domain on port 587 — the standard for STARTTLS encryption. This mimics how email clients establish secure links. Always use a timeout to prevent hanging if the server doesn’t respond. For testing, bind to non-privileged ports such as 8025 to reduce detection risk.
Executing the Handshake Commands
After the connection, send EHLO to identify your client. The server should reply with a 250 status, confirming support for extended SMTP features. Then, send MAIL FROM:<[email protected]> — use a placeholder address here, not a real one. Next, send RCPT TO:<[email protected]> with the real email address you’re verifying. The server’s response after this step is key.
If you get a 250, the address is valid and accepted by the server. If it returns 550 (no such user), 551 (user not local), or 553 (invalid mailbox name), the address is definitely invalid. Code the logic to parse these codes using the response string’s first three digits. You can find standard SMTP response codes in RFC 5321, the foundational specification for SMTP.
Remember: this method checks mailbox existence at the server level, not user activity or inbox delivery. It’s effective for filtering invalid addresses but doesn’t verify deliverability. For full confidence, combine it with deliverability testing tools. Tools like MailTester’s email checker use this approach, plus advanced logic on catch-all detection, role accounts, and disposable domains.
Use this script for bulk validation in development, but avoid sending to production mail servers without proper infrastructure. Real-time verification at scale requires rate limiting, IP rotation, and careful monitoring of sender reputation. Always respect the server’s connection limits and avoid overloading.
Why Most Email Verification Tools Don’t Let You Do SMTP Handshakes Directly
You can’t reliably run direct SMTP handshakes from your own code because most mail servers block or throttle connections from unknown IP addresses. They use abuse prevention systems like greylisting and reputation checks that will delay or reject your first attempt, making real-time validation impossible without a proven sending history. Even if you succeed once, repeated attempts from the same IP trigger anti-spam filters, which harms your sender reputation and may get you blacklisted.
Rate Limits and Abuse Prevention Block Direct Access
Most email providers rate-limit incoming SMTP connections from new or untrusted IPs. A standard server might allow only a few attempts per minute before blocking the connection entirely. Tools that expose raw SMTP endpoints often fail here, because they don't account for these limits. You're not just trying to verify an address—you're also testing if your IP is trusted enough to be allowed in the first place.
Greylisting is one of the most common barriers: it temporarily rejects a connection, asking the sender to try again in 5–10 minutes. If your tool doesn't handle this delay, it treats the result as a bounce, even if the address is perfectly valid. This isn’t a flaw in the email—it’s intentional abuse prevention. Spam and bulk mailers don't wait. Legitimate senders do, or they use trusted infrastructure.
Whitelisted Infrastructure Is the Real Solution
This is why tools like MailTester avoid exposing raw SMTP in their API. Instead, they run handshakes from a network of whitelisted IPs with proven sending histories. These IPs are not just allowed—they’re expected. They've been vetted by major providers like Gmail, Yahoo, and Outlook. This allows verification to succeed even when a new, direct connection would fail.
MailTester uses real-time SMTP trials combined with historical data to determine validity. If an address responds at all, we track patterns across thousands of verified deliveries. This builds confidence beyond a single handshake. You don't need to run the test yourself—you can rely on our infrastructure to do it for you safely and effectively. It’s not a shortcut. It’s the standard in enterprise-level deliverability engineering.
While you could script SMTP handshakes yourself, doing it at scale without proper infrastructure leads to consistent failures, blocked IPs, and damaged deliverability. Real verification isn’t about writing raw code—it’s about knowing which systems to trust. For teams who want to test email validity without risking reputation, the right tool runs the process for you. Bulk verify lists with confidence using our verified network.
How MailTester Handles SMTP Verification Behind the Scenes
MailTester performs real SMTP handshakes using a global network of servers optimized for sender reputation, mimicking how actual users connect. Each handshake follows RFC 5321 and RFC 5322 standards, validating the envelope and recipient behavior in real time. This approach achieves 98.9% accuracy in classifying addresses as valid, catch-all, or risky by combining SMTP response codes, DNS checks, and behavioral signals.
Real Behavior, Real Results
Every verification starts with a connection from a geographically distributed server that simulates a legitimate email client. These servers avoid known spam patterns—like rapid-fire requests or identical headers—so they’re less likely to be flagged or blocked by receiving mail systems.
Let’s say you send a list of 5,000 emails. MailTester doesn’t just send a quick probe. It walks through the full SMTP handshake: HELO, MAIL FROM, RCPT TO, and QUIT. Each step is logged with timing, response codes, and error patterns. This isn’t a simulation—it’s a real connection attempt using IP addresses with clean reputations.
Validation Beyond SMTP
SMTP alone isn’t enough. We cross-check results with DNS lookups (MX, A, SPF) and track behavioral anomalies—like delayed responses, inconsistent error codes, or unexpected server timeouts. For instance, a server that accepts a MAIL FROM but rejects RCPT TO after 30 seconds often signals a catch-all setup.
Risky addresses—those with high bounce likelihood or shared infrastructure—are flagged using heuristics derived from real-world deliverability data. These signals come from monitoring systems like Spamhaus and MxToolbox, which track IP and domain reputations across millions of mail servers.
You can test this process directly. Use our email checker to verify a single address, or run mass validations via our bulk verification tool. Both leverage the same SMTP + DNS + behavioral stack behind the scenes to give you accurate, repeatable results.
Our API at https://mailtester.com/api-email-checker/ lets developers integrate this logic into their workflows, with responses returned in under 5 seconds per address. Accuracy isn’t just a claim—it’s measured against known valid and invalid patterns, with consistent performance across industries.
Common SMTP Response Codes and What They Mean in Verification
You’re debugging email verification failures? Let’s cut straight to the point: SMTP response codes tell you exactly what the recipient server thinks of an email address. A 250 means success — the address is valid and accepted. A 550 means it’s rejected or nonexistent. 551 signals the user isn’t local (common with catch-alls). 553 means the mailbox name is malformed. And 554? Often means temporary rejection, like from greylisting or content filters. These codes are your first line of defense in catching invalid or risky addresses early.
Key SMTP Codes in Practice
- 250: Success – The server confirms the address is valid and accepted. This is the only clean result you want for a verified email. Use it as a threshold for adding addresses to your send list.
- 550: Not Found – The mailbox doesn't exist or was rejected. This is definitive: the address is invalid. Common with disposable domains or typos.
- 551: User Not Local – The server says the user doesn’t reside on that domain. Often seen on catch-all domains where mail for invalid users is still accepted, but the user isn't actually available.
- 553: Invalid Syntax – The mailbox name contains invalid characters or format (e.g.,
[email protected]). Your validation should catch these before sending to SMTP. - 554: Transaction Failed – The server blocked the transaction. Often due to greylisting, known spam patterns, or temporary policy enforcement. This doesn’t mean the address is dead — just that the server rejected the immediate attempt.
What to Do After Each Response
Not all 5xx errors mean a hard failure. With 554, you might retry later — but don’t assume the address is good. With 551, the address might be valid, but the server isn’t letting you know. That’s why verification tools like MailTester’s bulk verification go beyond basic SMTP by testing for catch-alls and role addresses, helping you avoid false positives.
| Item | Details |
|---|---|
| 250: Success | The server confirms the address is valid and accepted. This is the only clean result you want for a verified email. Use it as a threshold for adding addresses to your send list. |
| 550: Not Found | The mailbox doesn't exist or was rejected. This is definitive: the address is invalid. Common with disposable domains or typos. |
| 551: User Not Local | The server says the user doesn’t reside on that domain. Often seen on catch-all domains where mail for invalid users is still accepted, but the user isn't actually available. |
| 553: Invalid Syntax | The mailbox name contains invalid characters or format (e.g., [email protected]). Your validation should catch these before sending to SMTP. |
| 554: Transaction Failed | The server blocked the transaction. Often due to greylisting, known spam patterns, or temporary policy enforcement. This doesn’t mean the address is dead — just that the server rejected the immediate attempt. |
These codes are defined in RFC 5321, the standard for SMTP. While a 250 is clear, the nuances of 551 or 554 require context. Your verification system should map these responses into actionable statuses: Valid, Invalid, Catch-All, or Risky — so you know whether to send, block, or investigate.
Catch-All Domains and Why SMTP Handshakes Alone Can't Detect Them
SMTP handshakes can’t reliably detect catch-all domains because they accept any email address, even non-existent ones, returning a 250 success code for every input. This means a valid-looking handshake doesn’t prove the address is real—only that the server is willing to receive mail for it. For email verification developers, this creates false positives that hurt list quality and deliverability.
Why SMTP Results Are Misleading for Catch-All Detection
When a catch-all domain receives an SMTP HELO or RCPT TO command, the server typically replies with a 250 status, regardless of whether the local part (the part before @) exists. This behavior is by design—some servers are configured to accept all mail and deliver it to a default mailbox or discard it silently.
This is why relying solely on SMTP handshakes fails: a successful 250 response doesn't confirm address validity. It only confirms that the domain's mail server is willing to accept mail. Without additional checks, you end up with lists that include fake or unused addresses—leading to bounces, reputation damage, and wasted sends.
How MailTester Handles Catch-All Domains Accurately
MailTester goes beyond SMTP by combining multiple signals: it checks MX records for proper mail server configuration, monitors server behavior during real-time testing, and applies historical patterns from known catch-all behavior. These signals are weighted in our verification engine to detect domains that accept all incoming mail.
For example, if a domain consistently returns 250 for multiple random addresses and shows signs of no local part validation (like no known user database), MailTester flags it as catch-all. This prevents false positives in bulk verification and keeps your sender reputation intact.
Our system is trained on real-world mail server behavior and continuously updated with data from known email providers and abuse sources like Spamhaus and MxToolbox. The result? A 98.9% accuracy rate on list verification, with catch-all detection embedded into every check.
You can test this in action with our bulk verification tool, which evaluates each address using SMTP, DNS, and behavioral analysis:
Run a full list verification with catch-all detection built in.
In short, SMTP handshake results are only a first step. For real validation, you need context—DNS checks, logs, and behavior analysis. If you're building an email verification system, don’t trust a 250 reply alone. Use a tool that sees the full picture.
Greylisting and How It Affects Real-Time SMTP Verification
Greylisting temporarily rejects new email connections from unknown senders, forcing spambots to retry—often failing. This delays delivery and causes real-time SMTP checks to return false negatives on first attempts, even for valid addresses. MailTester handles this by intelligently retrying connections based on historical server behavior, reducing false drops.
How Greylisting Works in Practice
When you initiate an SMTP handshake with a server that uses greylisting, the first connection attempt may return a 4xx or 5xx response, such as 451 or 550, indicating temporary rejection. This is not a hard failure—it’s a deliberate signal to wait. Legitimate mail servers like SendGrid or Microsoft’s Exchange will retry after a few minutes, typically between 5 and 30, depending on the server’s policy. But automated verification tools that don’t retry may misclassify the address as invalid.
For email verification services, this creates a high risk of false negatives. A single attempt on a greylisted server won’t confirm deliverability. That’s why static, one-shot SMTP checks often fail—even with valid email addresses. This is especially common with large providers like Gmail, Hotmail, or corporate domains that run greylisting as part of their spam defense.
How MailTester Handles It
MailTester accounts for greylisting by applying intelligent retry logic. It doesn’t just retry once—it analyzes the server’s behavior across prior connections and applies a dynamic delay before reattempting. If a server historically accepts after a 10-minute interval, it waits that long. If another server uses 5 minutes, it adapts there.
This approach significantly improves accuracy. Instead of treating a temporary 451 or 550 as final, MailTester treats it as a sign to try again—just like a real sending system would. The result? Fewer false negatives in your verification results.
Greylisting is documented in RFC 3028 and widely adopted. According to Spamhaus, over half of enterprise mail servers use greylisting in some form, making it a common, not rare, obstacle. Ignoring it leads to misleading verification reports.
If you're building a real-time verification system or validating bulk lists, you need more than just a basic SMTP check. You need logic that mimics actual sending behavior. That’s why MailTester’s verification API and bulk list tools include this level of intelligence—so your results reflect real-world deliverability, not just test conditions.
You can see how this works in practice with our free, live email checker, or dig deeper with our full verification API for integration into your workflow.
How To Use the MailTester API to Verify Emails Without Writing SMTP Code
You can verify email addresses in real time without writing a single line of SMTP code. Just send a POST request to the MailTester API with an email address, and get back a verdict — valid, invalid, catch-all, or risky — along with detailed diagnostics like DNS records, reputation scores, and SMTP response codes. No IP management, retry logic, or timeout handling required. You’re done in under 10 seconds per address.
Step-by-step: Verify emails with the MailTester API
- Send a POST request to https://api.mailtester.com/v1/verify with the email in the body. This triggers a full technical validation. You don’t need to know how SMTP works — the API does it for you.
- Receive a structured response with a clear verdict. Valid means the address is deliverable. Invalid means it fails syntax, domain, or mailbox checks. Catch-all indicates the domain accepts all emails, which is a red flag. Risky flags addresses with poor reputation or known abuse patterns.
- Check the full diagnostic report in the response. It includes SPF, DKIM, and DMARC alignment results, DNS lookup data, and a sender reputation score from known monitoring sources — all used to assess deliverability risk.
- Scale to bulk lists using /bulk/verify. Upload a CSV or JSON file with up to 50,000 emails. MailTester processes each one in parallel, returns structured results, and handles all retries, timeouts, and IP rotation automatically.
- Use the results to improve deliverability. Flag risky or catch-all addresses before sending. Reduce bounce rates, avoid blacklists, and improve inbox placement — all without managing your own email infrastructure.
Why this works better than DIY SMTP
Writing your own SMTP handshake means handling connection timeouts, rate limiting, greylisting delays, and IP reputation — all of which break easily. According to RFC 5321, the SMTP protocol requires strict state machine handling. Even small deviations cause failures. MailTester handles the full handshake in under 2 seconds per address, using a globally distributed network of verified IPs.
When you use the MailTester API, you’re not just skipping code — you’re bypassing the entire operational burden. No need to maintain an IP pool, monitor blocklists, or diagnose why an email wasn’t delivered. The response includes every piece of data you need to decide whether to send, and you can integrate it directly into your workflow via existing tools like Mailchimp, HubSpot, or SendGrid.
Start with 100 free verifications at https://mailtester.com/pricing/. Credits never expire. No contracts. Just plug in your email list and get results with 98.9% accuracy — verified across real-world test data.
When You Should Use SMTP Handshake vs. a SaaS Like MailTester
You should only run SMTP handshakes for internal testing, debugging, or very low-volume validation where you control the entire infrastructure. For production email verification—especially at scale—MailTester delivers better accuracy, real-time risk scoring, and inbox placement insights without the complexity of maintaining your own SMTP stack.
Use SMTP handshakes only when you need direct control
- Run raw SMTP handshakes if you’re building custom email infrastructure or debugging specific delivery issues.
- SMTP testing gives you granular control over the connection, but it’s slow, resource-heavy, and hard to scale reliably.
- Each handshake must simulate a full email transaction: HELO, MAIL FROM, RCPT TO, DATA—all of which take time and bandwidth.
- This approach exposes you to rate limits, IP reputation penalties, and false positives if the server doesn’t respond to probes like a real sender would.
- As documented in RFC 5321, SMTP is built for sending—not verification. Its behavior under load doesn’t mirror real-world delivery.
Use MailTester for production, accuracy, and automation
- MailTester’s 98.9% accuracy is measured across real-world domains, catch-all behaviors, disposable email providers, and sender reputations—validated across thousands of test cases.
- It detects invalid addresses, role accounts, temporary bounces, and risky inboxes with far greater precision than a basic SMTP check.
- MailTester runs real delivery simulations: it tests whether the address would actually receive mail in a live inbox—something raw SMTP can’t do.
- With integrations into Mailchimp, SendGrid, HubSpot, and Klaviyo, you can enforce list hygiene directly at the source, reducing bounces and improving sender reputation.
- Instead of writing your own SMTP logic, you get a verified, auditable result in under a second via the real-time verification API.
- Use bulk verification to clean thousands of addresses at once, or test inbox placement with inbox placement testing before launching campaigns.
Key Takeaway: Verify with Intelligence, Not Just Code
SMTP handshake is a technical necessity, but it only tells part of the story. A successful connection does not mean an inbox exists, nor does it guarantee deliverability.
Real-world email systems use DNS records, sender reputation, behavioral patterns, and infrastructure trust. Relying solely on raw SMTP checks leads to false positives — especially with catch-all domains, greylisting, and role accounts.
MailTester combines SMTP validation with real-time DNS analysis, reputation checks, and behavioral intelligence. This layered approach avoids common pitfalls of basic verification scripts.
Use code examples to understand the handshake mechanics and debug issues. Use a SaaS platform like MailTester for production-grade accuracy and inbox placement guarantees.
Sources
- Since May 5, 2025, Microsoft Outlook requires SPF, DKIM, and DMARC from domains sending 5,000+ emails per day, rejecting non-compliant mail outright at the SMTP level with error 550 5.7.515. — Microsoft Outlook requirements (via MailOver bulk-sender requirements guide) (2025)
Keep reading
- Bounce codes and SMTP errors explained (complete guide)
- How to Reduce Yahoo 421 4.7.0 Temporary Deferral with Deliverability Monitoring
- Detect Sender Reputation Risk Before Email Sends to Avoid 550 5.7.1
- SMTP Relay Failing Due to STARTTLS Negotiation Timeout: Email Solution
- Reduce 550 5.7.1 Bounce Rate with Real-Time Sender Reputation Monitoring
Ready to put this into practice? MailTester verifies emails with 98.9% accuracy — start with 100 free verifications.
Frequently asked questions
Can I verify email addresses using only SMTP handshake code?
Yes, but with limitations. It can detect invalid addresses and catch-alls only partially. False positives and greylisting can skew results. For production use, combine with DNS and behavioral checks.
Why does my SMTP handshake return 250 for fake email addresses?
The domain may be a catch-all, greylisted, or misconfigured. A 250 response indicates the server accepts mail but doesn’t confirm the mailbox exists. Additional checks are needed.
How does MailTester avoid being blocked during SMTP checks?
MailTester uses whitelisted IPs, rate-limited retry logic, and distributed infrastructure designed to mimic legitimate user behavior without triggering spam protection.
What percentage of email bounces are due to invalid addresses?
On average, 30-40% of email bounces result from invalid or non-existent addresses. Preventing these improves delivery and sender reputation.
Do disposable email domains pass SMTP handshake tests?
Some do, especially if they forward mail. But MailTester identifies them using a known list of domains and behavior patterns, even if SMTP accepts the address.
Is there a free way to test SMTP handshakes for email verification?
Yes, you can use public mail servers (like Gmail’s SMTP) with test addresses, but results are incomplete. MailTester offers 100 free verifications to start with full accuracy.
What’s the difference between a catch-all and a valid email address?
A catch-all accepts any address, even if no user exists. A valid address maps to a real mailbox. SMTP alone cannot distinguish them — you need additional checks.
Can I automate SMTP verification across a large email list?
Yes, but it’s risky. Large-scale connections are likely blocked or flagged. Use a service like MailTester with bulk verification and integrations for scalability and reliability.
How does MailTester achieve 98.9% accuracy?
It combines SMTP handshake, DNS analysis, role account detection, disposable domain checks, and sender reputation intelligence across real-world data and server behavior.
What happens if a domain uses DMARC with reject policies?
It may reject emails from unverified sources, but SMTP handshakes still proceed unless the domain blocks the connection. MailTester accounts for this by using trusted sources and historical patterns.
Does the MailTester API work with SendGrid and Mailchimp?
Yes. MailTester integrates with SendGrid, Mailchimp, HubSpot, and Klaviyo. You can verify email lists directly from these platforms to prevent bounces and improve inbox placement.
Are purchased verification credits in MailTester permanent?
Yes. Unlike many services, MailTester credits never expire, giving you long-term flexibility for list maintenance.