Stage one: parse the syntax
The first check never touches the network. The address is split at the last @ into a local part and a domain. The local part must be 64 characters or fewer and contain only permitted characters, and the domain must be a sequence of valid DNS labels. Addresses that fail here get the reason invalid_syntax and the pipeline stops.
This stage also normalizes the input: whitespace is trimmed and the domain is lowercased. The local part is left as entered because some servers treat it as case sensitive, even though almost none do in practice.
Stage two: resolve the domain and its MX records
Next the verifier queries DNS for MX records on the domain. An MX record names a mail server and a priority, and a domain can publish several. If the domain does not resolve at all, the reason is invalid_domain. If it resolves but publishes no MX records and no fallback A record, the reason is no_mx_record and the address is undeliverable.
The verifier also classifies the domain at this stage. Known disposable providers, free providers such as Gmail and Outlook, and domains observed to accept every address are flagged here, since those labels depend on the domain rather than the mailbox.
Stage three: ask the mail server about the mailbox
The verifier connects to the highest priority MX host on port 25 and runs the opening of a normal SMTP session. It sends EHLO, then MAIL FROM with a sender address, then RCPT TO with the address under test. The server's reply to RCPT TO is the signal. A 250 means the mailbox is accepted. A 550 means it does not exist. The verifier then sends QUIT without ever issuing DATA, so no message is transmitted.
> EHLO verifier.example
< 250-mx1.acme.com Hello
> MAIL FROM:<probe@verifier.example>
< 250 2.1.0 Ok
> RCPT TO:<ghost@acme.com>
< 550 5.1.1 The email account does not exist
> QUIT
< 221 2.0.0 ByeWhere the pipeline cannot give a definitive answer
Three situations stop the SMTP stage from producing a clean yes or no. Greylisting servers reply with a temporary 4xx code to any unfamiliar sender and expect a retry later. Some providers block port 25 probes entirely or time out. And catch-all domains return 250 for every RCPT TO, so acceptance proves nothing about the individual mailbox.
A well designed service reports these honestly instead of guessing. VeriDock returns unknown with reasons timeout, greylisted, or unavailable_smtp for the first two cases and risky with reason catch_all for the third. Unknown results are never billed, and re-checking the same address within 30 days is free, so retrying later costs nothing.
- 250 to RCPT TO: mailbox accepted, status deliverable.
- 550 or 551 to RCPT TO: mailbox rejected, status undeliverable.
- 452 or 552 mentioning quota: status undeliverable with reason mailbox_full.
- 450 or 451: greylisted or temporarily unavailable, status unknown.
- 250 for a random local part too: catch-all domain, status risky.
Key takeaways
0/4Try it on a real address
Run syntax, DNS, MX, disposable, and role checks on any address. No signup needed.
Frequently asked questions
Verify addresses with one API call
250 free checks every month, recurring. Unknown results are never billed.