// email verification
Find out if an email address is real before you send to it.
pingutil asks the recipient’s own mail server whether the mailbox exists, without sending a message. Every address comes back valid, invalid, risky or unknown, with the reason.
Have a list? Open the dashboard to upload a CSV of up to 50 addresses and download the results.
how it works
Five checks, cheapest first
The first check that gives a definite answer wins, so a typo or a throwaway domain never costs a network round trip.
- 01syntax
Is it a well-formed address? Catches typos like a missing @ or double dots.
- 02lists
Is the domain a disposable inbox service? Checked against about 9,900 known domains.
- 03dns
Does the domain exist, and does it publish a mail server (MX record)?
- 04smtp
Connect to that mail server and ask whether it would accept mail for this address. Hang up before sending anything.
- 05catch-all
Ask about a random address on the same domain. If that is accepted too, the server accepts everything and the answer can’t be trusted.
results
What each status means
e.g. mailbox_exists: The mail server confirmed this mailbox exists.
e.g. mailbox_not_found: The mail server says this mailbox does not exist.
e.g. accept_all: The domain accepts mail for any address (catch-all), so this one can’t be confirmed.
e.g. greylisted: The mail server asked us to try again later (greylisting).
Full list of reasons in the API reference.
api
One call per address, or 50 at once
Use POST /v1/verify in a signup form, or /v1/verify/batch to clean a list. Same API key as domain lookups. Each account can check 300 addresses a day, API and CSV uploads combined.
No code? Sign in and upload a CSV of up to 50 rows from the dashboard. You get your file back with the result columns added.
curl -X POST https://pingutil.com/v1/verify \
-H "Authorization: Bearer $PINGUTIL_KEY" \
-H "Content-Type: application/json" \
-d '{"email":"jane@stripe.com"}'{
"status": "valid",
"reason": "mailbox_exists",
"score": 95,
"checks": { "mailbox": "exists", "catch_all": false, ... }
}faq
Questions
Does verifying an address send it an email?
No. pingutil connects to the domain’s mail server and asks about the address with the SMTP RCPT TO command, then disconnects before any message is sent. The person behind the address never sees anything.
How accurate is it?
When the mail server gives a clear answer, the result is right the vast majority of the time. That covers the valid and invalid statuses. Some servers accept every address (catch-all) or refuse to answer, and those come back as risky or unknown rather than a guess. Treat valid and invalid as decisions and risky or unknown as “needs a second look”.
Why is a Yahoo or catch-all address “risky” and not “valid”?
Those servers say yes to every address during the SMTP conversation, including ones that don’t exist, and only bounce later. A yes from them tells you nothing about the specific mailbox, so pingutil reports accept_all instead of claiming it is valid.
What happens to the addresses I upload?
Results are cached for 30 days under a keyed SHA-256 hash (HMAC) of the address, so the cache never holds the plain email. CSV uploads in the dashboard keep your rows for 30 days so you can download them again, and you can delete an upload at any time.
How many addresses can I check?
The demo on this page allows 3 checks a minute per IP. Signed-in users can upload CSVs of up to 50 rows. With an API key, POST /v1/verify checks one address and POST /v1/verify/batch checks up to 50 per call, at 60 requests a minute per account. Each account gets 300 addresses a day, API and CSV uploads combined.