Email verification API
Verify email addresses through a REST API
Send an email address from your server to check its format, domain and mail routing. A full check can also gather evidence about the mailbox from the receiving mail server. The JSON response includes a status, a recommended action and the reasons for the result.
No email is sent during verification. When the check cannot determine whether the address can receive mail, Emvero returns an unknown result.
Server-side REST API · JSON results · Polling for pending checks
Make a request from your server
Create a bearer credential in your account and keep it on your server. Send it in the Authorization header with each request. The JSON body requires an email value.
The request below uses full, the default verification depth. It checks syntax, the domain and mail routing, and can probe the receiving server for mailbox evidence. To stop before the SMTP probe, include "variant":"domain" in the request body. Both depths use the same endpoint and response fields. A domain check cannot establish whether an individual mailbox exists.
curl -sS https://api.emvero.tech/v1/verifications \
-H "Authorization: Bearer emv_your_credential" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: signup-8f21c0" \
-d '{"email":"ada@example.com"}'
Reuse the same Idempotency-Key when retrying this request. Within the API’s replay window, this prevents a retry or duplicate submission from starting another verification.
The following HTTP 200 response is illustrative. Its address, identifier and evidence are fictional; they do not describe a live check of example.com:
{
"id": "5f0b6f3e-1a4c-4a1f-9d2e-8f7b3c2a1d90",
"email": "ada@example.com",
"normalized": { "domain": "example.com", "ascii_domain": "example.com" },
"status": "deliverable",
"confidence": 0.92,
"action": "allow",
"checks": {
"syntax": "valid",
"domain": "valid",
"mail_routing": "valid",
"smtp": "accepted",
"accept_all": "no",
"disposable": false,
"role_account": false,
"public_provider": false,
"smtp_utf8_required": false
},
"reason_codes": ["MX_FOUND", "SMTP_RCPT_ACCEPTED"]
}
HTTP 200 means the request succeeded, including when the address is undeliverable. Read the JSON result to find out what the check established about the address. HTTP errors describe a problem with the request or service.
Read the fields together
status describes the result. The four final values are deliverable, risky, undeliverable and unknown. pending means the check is still running.
| Status | Meaning | Recommended action |
|---|---|---|
| deliverable | The server accepted the recipient and no risk signals were found | allow |
| risky | A specific risk signal affects how the address should be handled | allow_with_email_confirmation / allow |
| undeliverable | The check found a permanent technical reason to reject the address | reject |
| unknown | The available evidence could not determine whether the address can receive mail | allow_with_email_confirmation |
| pending | The check is still running | Retrieve the result after retry_after_ms |
action recommends how to handle the address: accept it with allow, use a confirmation step with allow_with_email_confirmation, or turn it away with reject. Your application decides how to apply the recommendation. Read the returned field rather than inferring it from status: a risky result can carry either allow or allow_with_email_confirmation, depending on the evidence.
To understand the result, inspect checks for each stage’s outcome and any risk signals. reason_codes explains the findings with stable identifiers such as DISPOSABLE_DOMAIN or SMTP_RCPT_ACCEPTED. The single-address verification guide explains what syntax, routing and SMTP checks can establish.
confidence is an evidence score from 0 to 1. The example’s 0.92 is not a 92% probability of inbox delivery. A verification result also does not establish that a person controls the mailbox; use a separate email confirmation when that matters.
Poll when a full check is still running
A full check can return pending while it gathers mailbox evidence. The response includes the evidence collected so far, an id and retry_after_ms, the interval to wait before retrieving the result. This illustrative response shows only the fields needed for polling:
{
"id": "5f0b6f3e-1a4c-4a1f-9d2e-8f7b3c2a1d90",
"status": "pending",
"retry_after_ms": 2000
}
Wait for retry_after_ms milliseconds, then call GET /v1/verifications/{id} with the same bearer credential. Replace {id} with the identifier from the response. If the result is still pending, wait for the returned interval before polling again. Stop polling when you receive a final status or reach your application’s deadline. The API does not send a callback. The pending results documentation covers this process in detail.
Reaching your deadline does not mean the address is invalid. A completed check can also return unknown if a timeout or server restriction leaves too little evidence for a definite result. Keep unfinished work separate from a final unknown result in your application.
Handle request errors separately
An HTTP error does not tell you whether the address can receive mail. Handle it according to the response code:
400: correct the request.401: check the bearer credential.402: the account has insufficient credits.429: reduce the request rate and honourRetry-Afterwhen supplied.5xx: the service could not return a verification result. Do not treat this as an address rejection.
If you retry the same operation, preserve its idempotency key. The quickstart shows a basic integration, and the error reference explains the response codes.
For a form where someone is waiting, the real-time verification page explains how to set a wait deadline and handle the result. For an existing list, the bulk verification page explains how to run one request per address and store the results in your own system. There is no hosted CSV upload or separate batch endpoint.
Questions
Frequently asked.
What does an email verification API return?
The JSON response includes an id, a status describing the result and an action recommending how to handle the address. checks records the individual check results, reason_codes explains the findings with stable identifiers, and confidence scores the evidence. A check that is still running returns pending so you can retrieve the result later.
Is this an email validation API as well?
Yes. The API validates the address format, then checks the domain and its mail routing. A full check can also use SMTP to gather evidence about the mailbox. You can choose a domain check to stop before that SMTP probe, but it cannot establish whether the individual mailbox exists.
Does the API send a verification message?
No. An SMTP probe stops before DATA, the stage where message content would be sent. No subject or body is submitted. If you need to confirm that someone controls the mailbox, your application must send a separate confirmation email.
Can the API prove every mailbox exists?
No. A catch-all server may accept any recipient name, so acceptance alone cannot prove that a particular mailbox exists. Timeouts and server restrictions can also leave the check without enough evidence. These limits may lead to risky or unknown. Even a deliverable result does not guarantee future delivery or show who controls the mailbox.
Can I try the email verification API for free?
Yes. Create an account and confirm your email address to receive 1,000 credits without a card. They cover 100 full checks or up to 500 domain checks. Create a bearer credential in your account to use those credits through the API.
Compared side by side
Send your first request
Try the API with your account credits
Create an account and confirm your email address to receive 1,000 credits. No card is required. Use them for 100 full checks or up to 500 domain checks.