Email validation API
Email validation API for signup, CRM, and backend workflows
Validate addresses before they enter your product, campaign tools, or customer database. BounceNot returns deliverability signals through a simple JSON API and uses one credit per successful validation.
Validate a single email
Send a GET request with the email address in the path and your API key in the Authorization: Bearer header (or X-API-Key). The legacy api_key query parameter still works, but headers keep keys out of logs.
curl 'https://bouncenot.oddbench.co/api/v1/validate/support@example.com' \
-H 'Authorization: Bearer YOUR_API_KEY'
Validate a batch
Send multiple addresses in one JSON request. Each email requires one available credit.
curl -X POST 'https://bouncenot.oddbench.co/api/v1/validate' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"emails": ["support@example.com", "sales@example.com"]
}'
Authentication
Create an account, open private API access, and use your generated API key on server-side requests.
Credit usage
A successful validation consumes one credit. If an account has insufficient credits, the API returns a forbidden response.
Validation signals
Responses include reachability (yes, no or unknown), syntax, SMTP deliverability and catch-all, MX records, a typo suggestion, disposable, role and free-provider flags, and smtp_error (why a probe was inconclusive: greylisted, timeout, blocked…). List emails additionally carry a status and sub-status.
Example response
GET /api/v1/validate/support@example.com returns:
{
"email": "support@example.com",
"reachable": "yes",
"syntax": { "valid": true, "domain": "example.com", "username": "support" },
"smtp": {
"host_exists": true,
"deliverable": true,
"full_inbox": false,
"catch_all": false,
"disabled": false
},
"smtp_error": null,
"has_mx_records": true,
"disposable": false,
"role_account": true,
"free": false,
"suggestion": ""
}
Batch requests return {"results": [...]} with one such object per address.
Status codes
Every validated email in a list gets one status and, where there is more to say, a sub_status. They appear in the dashboard, the CSV export and the list emails API (GET /api/v1/lists/{id}/emails).
| status | Meaning | sub_status | Meaning |
|---|---|---|---|
Validvalid |
The mailbox accepted our check. Safe to send. | role_based |
A shared inbox such as info@ or sales@. It exists, but engagement is usually low and some providers treat mail to it as spam. |
Invalidinvalid |
Bad syntax, no mail servers, or the mailbox was refused. Will bounce; "Delete invalid" removes these. | failed_syntax_check |
The address is not well-formed. |
no_dns_entries |
The domain has no MX records, so nothing can receive mail for it. | ||
possible_typo |
The domain looks like a misspelling of a popular provider. | ||
mailbox_not_found |
The mail server said this mailbox does not exist. | ||
mailbox_quota_exceeded |
The mailbox is over quota and refuses new mail. | ||
mailbox_disabled |
The mail server reported the mailbox as disabled. | ||
Catch-allcatch_all |
The domain accepts any address, so the mailbox itself can't be confirmed. | role_based_catch_all |
A role address on a domain that accepts any recipient. |
Do not maildo_not_mail |
Deliverable or not, sending is a bad idea (disposable services). | disposable |
A throwaway address from a temporary-email service. |
Unknownunknown |
The mail server gave no definite answer. Not charged differently; revalidate later. | greylisted |
The server asked us to retry later (greylisting). Revalidating usually gives a definite answer. |
timeout_exceeded |
The mail server did not answer in time. | ||
antispam_system |
An anti-spam system refused to talk to us; the mailbox could not be checked. | ||
failed_smtp_connection |
The mail server refused the connection. | ||
mail_server_temporary_error |
The mail server returned a temporary error. | ||
smtp_inconclusive |
The mail server gave no definite answer about this mailbox. |
A valid or catch-all address without a sub-status has nothing to add. Role addresses stay valid (the mailbox exists); the "Safe to send" export excludes them.
Credit balance
Poll your balance from monitoring or before a big import.
curl 'https://bouncenot.oddbench.co/api/v1/credits' \
-H 'Authorization: Bearer YOUR_API_KEY'
# {"credits": 2500}
Usage
Validations per day, list job and API separately. Dates are UTC, inclusive, at most a year apart; the default is the last 30 days.
curl 'https://bouncenot.oddbench.co/api/v1/usage?start=2026-10-01&end=2026-10-31' \
-H 'Authorization: Bearer YOUR_API_KEY'
# {"start": "2026-10-01", "end": "2026-10-31", "total_validations": 1240,
# "list_validations": 1200, "api_validations": 40,
# "days": [{"date": "2026-10-03", "list_validations": 1200, "api_validations": 0}, ...]}
API FAQ
Each request uses an account API key generated inside BounceNot.
Yes. One successful API validation consumes one BounceNot credit.
A JSON object per address with reachability (yes, no or unknown), syntax, SMTP deliverability, MX records, and disposable, role and free-provider flags.