Verify an email address before you send
The expensive part of emailing a bad address is not the send. It is what the send teaches the receiving provider. Hard bounces, spam-trap hits and dead mailboxes accumulate against your domain, and after enough of them the same message that landed in the inbox last month starts landing in spam for the addresses that were always good. That is why list hygiene is a reputation problem wearing a data-quality costume.
So the API now answers the question that precedes a campaign:is this address worth sending to? The same key and the same credit balance you use for scraping serve POST /api/v1/email/verify, and the same capability is exposed to agents as the MCP tool verify_email. One credit per address, up to ten addresses per call.
What it actually checks
Four layers, cheapest first, and each one can end the enquiry early:
Syntax and shape. The address has to be a well-formed mailbox rather than a typo with an @ in it. Then a gibberish test for keyboard mash and randomly-generated local parts, because those are the signatures of scraped lists that were never qualified.
Domain quality. Disposable domains (the mailboxes that expire in ten minutes) and webmail domains (where a catch-all is normal) are classified separately, because they change what you should do with the answer rather than whether the address exists.
MX records. Whether the domain can receive mail at all, resolved over DNS-over-HTTPS. A domain with no MX record is a guaranteed bounce and needs no socket to prove it.
A real SMTP handshake. For domains that can receive, the verifier opens a session to the mail exchanger and issues RCPT TO for the specific mailbox. No message is ever sent. This is the only step that can tell a live mailbox from a suspended one on a domain that looks perfectly healthy.
Four verdicts, and one rule
Every answer carries status, and the mapping to action is the whole point:
valid — deliverable. Send. invalid — the mailbox does not exist, or the domain cannot receive mail. Remove it, and remove it permanently; this is the only verdict that justifies a delete. risky — the domain accepts everything (a catch-all), so the mailbox may or may not exist and only a send could tell you. Route those somewhere cautious rather than into the main campaign. unknown — the check could not be completed, usually because the receiving provider rate-limits the probe rather than answering it.
The rule that keeps a list clean: only invalid is a delete. Treating unknown as invalid silently drops addresses that were never disproven — the largest consumer providers answer probes inconsistently, so the same address can come back unknown today and valid tomorrow. Retryunknown; never delete it.
curl -s https://fastcrawl.net/api/v1/email/verify \
-H "Authorization: Bearer $FASTCRAWL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]"}'The response reports the verdict with the evidence behind it — score,mx_records, smtp_check, accept_all,disposable, webmail — so a downstream system can apply its own threshold instead of inheriting ours:
{
"status": "invalid",
"score": 0,
"gibberish": false,
"disposable": false,
"webmail": true,
"mx_records": ["gmail-smtp-in.l.google.com"],
"smtp_check": true,
"accept_all": false
}Verifying a list, not an address
Real lists arrive as hundreds of addresses scraped out of contact pages, and one request per address is the wrong shape. Send up to ten addresses in a single call and the batch is answered together, one verdict each, still one credit per address:
curl -s https://fastcrawl.net/api/v1/email/verify \
-H "Authorization: Bearer $FASTCRAWL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"emails":["[email protected]","[email protected]","[email protected]"]}'The pattern that earns its keep is scrape → extract → verify → send. A scraping job pulls the contact page, an extraction schema returns the addresses it found, and the verifier decides which of them survive contact with your sending domain. The verifier is also where a scraping agent should stop and check itself: an LLM asked to extract an email address will happily return one it invented, and that invented address looks exactly like a real one until it bounces.
What it does not do
It never sends mail, so it cannot prove that a message will be delivered — only that the mailbox accepts the recipient. Catch-all domains stay risky for that reason, and no verifier on the market resolves them without sending.
It also cannot promise an answer for every address. The largest consumer providers rate-limit SMTP probes from any single origin, so some proportion of addresses will returnunknown on a first pass. That is a truthful answer rather than a failure, and a second pass later usually resolves it. A verifier that returned valid for everything it could not reach would be more pleasant to read and worse than useless.
Credits follow the same rule as the rest of the API: you pay for the answer, including aninvalid one, because a disproof is exactly what you bought. Requests that fail before verdict — a malformed body, more than ten addresses, a bad key — are not charged.
Email verification is included in the free tier — 1 credit per address. Start free · Read the docs