For developers
Real-time email verification API
One HTTP call per address, at signup, checkout or in a lead form. A verdict with its reason, or an honest unknown that costs nothing, inside the timeout you set.
- Free key, no card
- Unknowns are never billed
- Verifying email since 2019
What you get back
One call. One verdict, one reason, and the evidence if you want it.
Deliverable. The mailbox answered. One credit.
Unknown. The server wouldn't say. No charge, and you can see exactly why.
The promise
We don't guess.
Three rules, and what each one looks like in the response.
Unknown is a real answer.
When a server won't confirm a mailbox, we say so and don't charge you. We never upgrade a maybe to a yes.
"verdict": "unknown",
"reason": "greylisted",
"billed": falseEvery verdict has a reason.
A code you can write policy on, not a score you have to take on trust. Every one is defined on the result codes page.
- mailbox_exists
- domain_catch_all
- mailbox_full
- greylisted
- timeout
- no_mail_server
Evidence, one flag away.
Add evidence=true and get the SMTP exchange, the MX host and the timings. When a user says "your form rejected my email", you'll know why in thirty seconds.
?evidence=true
rcpt_to_random 550 5.1.1
rcpt_to 250 2.1.5 OK
The reasoning behind the promise: why we don't guess.
Built for the form
Someone is waiting. The API is built around that.
Your timeout, not ours.
Pass timeout in milliseconds. Anything that runs out comes back unknown, unbilled, so your form never waits on a slow mail server.
timeout=1500Typos caught.
did_you_mean suggests gmail.com for gmial.com before you lose the signup.
"did_you_mean": "gmail.com"A safe default for every result.
suggested_action maps each verdict to accept, accept-and-confirm or reject, so your first integration is already correct.
"suggested_action": "accept_and_confirm"Disposable, role and free-provider flags.
On every response, for free-trial abuse and B2B lead quality.
"flags": { "disposable": true }Quickstart
One request. Plain HTTP.
No SDK. Send the address, read the verdict.
curl -s https://api.verimail.io/v3/verify \
-H "Authorization: Bearer $VERIMAIL_KEY" \
-d "email=emma.wilson@acme-corp.com"Then the switch on the four verdicts, and the result codes when you want to go one level down.
Pricing
Priced so you can leave it on.
100
verifications a month on the free key.
No card. The same verdicts and evidence as a paid plan.
- No minimum purchase. Buy 1,000 credits or a million.
- Credits never expire.
- Unknowns are never billed.
- From $4 per 1,000 credits, down to $0.30 per 1,000 at a million a month.
- Plans and packs are on the pricing page. Side-by-side comparisons with other verification APIs are on the comparison pages.
Facts
Who handles the addresses you send, and how
- 2019
- The year we started verifying email
- Verimail Ltd, a UK company, on our own infrastructure. The fields the API answered then are still in every response, unchanged.
- 30 days
- Then request logs are gone
- Addresses sent to the API are not stored beyond the request log, which is kept for 30 days. Uploaded files and their results are deleted 30 days after upload.
- POST
- Keeps addresses out of URLs
- Send the address in the request body rather than the query string, and it never lands in a URL log.
- GDPR
- DPA on request
- Email support and we send you the data processing agreement for your records.
FAQ
Questions developers ask before they sign up
Do you resolve catch-all domains?
No, and we're upfront about it. A catch-all server accepts every address, so no verifier can confirm that a specific mailbox exists on it. We return risky with the reason domain_catch_all and suggest accepting the user and confirming by email. It is charged, because it was verified: we test a random address and yours, so a full or explicitly dead mailbox on a catch-all domain still gets its own verdict. What we don't do is upgrade the rest to valid. Vendors who return "valid" for catch-all addresses are estimating, not verifying.
Why do I sometimes get unknown?
Because the receiving server declined to answer: a "come back later", rate limiting, or a deliberate anti-probing response. We could guess. We don't. You get the server's actual reply in the evidence, you pay nothing, and suggested_action gives you the safe default.
Should I just send a confirmation email instead?
If your flow can wait for a click, do both. Confirmation proves a human controls the address; Verimail stops typos, disposable addresses and fakes before the email is ever sent, and covers the flows that can't wait: lead forms, checkout, newsletter capture.
What should my code do with each verdict?
deliverable: accept. undeliverable: reject, and show the reason in plain words ("that domain can't receive email"). risky: accept and confirm by email. unknown: accept and confirm by email, or retry later. Every response includes suggested_action with exactly this mapping; a disposable address is the one exception and comes back reject.
How long does a verification take?
Half of all calls answer within 0.6 s. The slowest 5% take more than 6 s, because some mail servers stall on first contact (3,000 calls). Set your own timeout; anything that runs out returns unknown and is not billed.
Do you offer bulk verification?
Yes. Same engine, same rules: upload a list and unknowns are free. See file verification.
We don't guess. You don't lose real users.
100 verifications a month on the free key, with the same verdicts and evidence as a paid plan. No card.