Checking MX records is a first step. After that, you connect to the SMTP server at the addresses given by these records. Then:
You can send a RCPT TO: <mail_to_check>
command, and see if the response of the SMTP server.
- If the user exists, you'll get a
250 2.1.5 Recipient OK
.
- Or else, you'll get a
5.1.1 DSN
.
You can send a VRFY <mail_to_check>
command, however, per my experience, very few servers support this command.
Caveats
Please note that this method does not work 100% of the time. Here are some potential issues:
- some servers just plainly disable this feature, to avoid bots listing through their users.
- greylisting: some servers block 1st connection from an unknown IP, and allow subsequent ones.
- be aware of catch-call providers, which accept
*@mydomain.com
, but doesn't necessarily mean that the inbox actually belongs to someone.
- and if you send too many requests to one server from the same IP, there's a high chance this IP will get blacklisted.
Example Demo
Below is the output of such a flow taken from another SO thread. It finds the MX records of stackoverflow.com
, and uses telnet to connect to the SMTP server and send/parse SMTP commands.
C:\>nslookup -q=mx stackoverflow.com
Non-authoritative answer:
stackoverflow.com MX preference = 40, mail exchanger = STACKOVERFLOW.COM.S9B2.PSMTP.com
stackoverflow.com MX preference = 10, mail exchanger = STACKOVERFLOW.COM.S9A1.PSMTP.com
stackoverflow.com MX preference = 20, mail exchanger = STACKOVERFLOW.COM.S9A2.PSMTP.com
stackoverflow.com MX preference = 30, mail exchanger = STACKOVERFLOW.COM.S9B1.PSMTP.com
C:\>telnet STACKOVERFLOW.COM.S9A1.PSMTP.com 25
220 Postini ESMTP 213 y6_35_0c4 ready. CA Business and Professions Code Section 17538.45 forbids use of this system for unsolicited electronic mail advertisements.
helo hi
250 Postini says hello back
mail from: <me@myhost.com>
250 Ok
rcpt to: <fake@stackoverflow.com>
550-5.1.1 The email account that you tried to reach does not exist. Please try
550-5.1.1 double-checking the recipient's email address for typos or
550-5.1.1 unnecessary spaces. Learn more at
550 5.1.1 http://mail.google.com/support/bin/answer.py?answer=6596 w41si3198459wfd.71
Disclosure
I run Reacher, a real-time email verification API. My code is written in Rust, and is 100% open-source. Check it out if you want a more robust solution:
https://github.com/amaurymartiny/check-if-email-exists
Jumping through some hoops to overcome the above caveats, I manage to verify around 80% of the emails my customers check.