- 500 validations/month
- 15 requests/minute
- Full DNS records check
- Disposable email detection
- Role-based detection
Email Validator API
Real-time email verification with a live SMTP handshake, catch-all detection, MX/SPF/DMARC checks, and disposable, role-based & free-provider detection. One request, one direct JSON result — no queue, no waiting.
Everything you need to verify an email
From syntax to a live conversation with the recipient's mail server — all in a single API call.
Live SMTP Handshake
Connects to the recipient's mail server and asks if the mailbox exists — without sending any email.
Catch-all Detection
Flags accept-all domains that take every address, so you know when a mailbox can't be individually confirmed.
DNS Verification
Checks MX, SPF and DMARC records to confirm the domain is set up to receive mail.
Disposable Detection
Detects 149,000+ disposable and temporary email providers from a live, continuously updated database.
Role-Based Detection
Identifies generic addresses like info@, support@, admin@ that usually aren't a single person.
Free Provider Detection
Recognises Gmail, Outlook, Yahoo and other free/webmail providers for smarter lead scoring.
Confidence Score
Every result includes a 0-1 confidence score so you can set your own accept/review threshold.
Fast & Direct
Synchronous JSON response — no polling, no webhooks, no queue. Cached DNS keeps repeat checks instant.
Where teams use it
Stop fake signups, protect deliverability, and keep your data clean.
Signup & Registration Protection
Block disposable and fake emails at sign-up in real time, before a fake account is ever created.
Lead Quality & Scoring
Verify leads from forms and ads instantly — separate real business emails from junk and free providers.
List Cleaning & Bounce Reduction
Scrub existing lists before a campaign to cut hard bounces and protect your sender reputation.
E-commerce Checkout
Catch mistyped emails at checkout so order confirmations and receipts actually reach the customer.
Fraud & Abuse Prevention
Flag high-risk disposable and catch-all addresses used for trial abuse, spam and chargebacks.
CRM & Marketing Hygiene
Keep your CRM accurate — validate on import and enrich records with deliverability signals.
Simple, transparent pricing
Start free and scale as you grow. No hidden fees.
- 5,000 validations/month
- 30 requests/minute
- Full DNS records check
- Disposable email detection
- Role-based detection
- Email support
- 15,000 validations/month
- 60 requests/minute
- Full DNS records check
- Disposable email detection
- Role-based detection
- Accelerated processing
- Priority support
- 50,000 validations/month
- 90 requests/minute
- Full DNS records check
- Disposable email detection
- Role-based detection
- Accelerated processing
- Dedicated support
- Unlimited validations
- Custom rate limits
- Full DNS records check
- Disposable email detection
- Role-based detection
- 24/7 priority support
API reference
Everything you need to integrate the Email Validator API.
Authentication
All API requests require authentication using your API key. Send it in the X-API-Key header with every request.
X-API-Key: your_api_key_here Get your API key. Sign up at dash.corenexis.com to get your API key instantly.
API endpoint
POSTGEThttps://api.corenexis.com/email-validator/v1
The API accepts both GET and POST requests. For POST, send the email as a JSON body or as form data. A single call runs the full pipeline: syntax → DNS → disposable/role/free lookup → live SMTP handshake → catch-all probe.
Request parameters
| Parameter | Type | Description |
|---|---|---|
X-API-Key Header |
String | Your API key (required, sent in request headers) |
email Required |
String | The email address to validate |
Code examples
Basic validation (POST)
curl -X POST https://api.corenexis.com/email-validator/v1 \
-H "X-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{"email": "john.doe@company.com"}' const response = await fetch('https://api.corenexis.com/email-validator/v1', {
method: 'POST',
headers: {
'X-API-Key': 'your_api_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({ email: 'john.doe@company.com' })
});
const result = await response.json();
if (result.success) {
const d = result.data;
console.log('Status:', d.status); // deliverable | risky | undeliverable | unknown | invalid
console.log('Confidence:', d.confidence); // 0.0 - 1.0
console.log('Mailbox accepted:', d.smtp.deliverable);
console.log('Catch-all:', d.smtp.catch_all);
} import requests
url = "https://api.corenexis.com/email-validator/v1"
headers = {
"X-API-Key": "your_api_key",
"Content-Type": "application/json"
}
data = {"email": "john.doe@company.com"}
result = requests.post(url, headers=headers, json=data).json()
if result["success"]:
d = result["data"]
print("Status:", d["status"])
print("Confidence:", d["confidence"])
print("Mailbox accepted:", d["smtp"]["deliverable"])
print("Catch-all:", d["smtp"]["catch_all"]) $ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => "https://api.corenexis.com/email-validator/v1",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
"X-API-Key: your_api_key",
"Content-Type: application/json"
],
CURLOPT_POSTFIELDS => json_encode([
"email" => "john.doe@company.com"
])
]);
$data = json_decode(curl_exec($ch), true);
if ($data["success"]) {
echo "Status: " . $data["data"]["status"] . "\n";
echo "Confidence: " . $data["data"]["confidence"] . "\n";
echo "Catch-all: " . ($data["data"]["smtp"]["catch_all"] ? "Yes" : "No") . "\n";
} GET request
curl "https://api.corenexis.com/email-validator/v1?email=john.doe@company.com" \
-H "X-API-Key: your_api_key" const email = encodeURIComponent('john.doe@company.com');
const response = await fetch(`https://api.corenexis.com/email-validator/v1?email=${email}`, {
method: 'GET',
headers: { 'X-API-Key': 'your_api_key' }
});
const data = await response.json();
console.log(data); Form data (POST)
# Send email as form data instead of JSON
curl -X POST https://api.corenexis.com/email-validator/v1 \
-H "X-API-Key: your_api_key" \
-d "email=john.doe@company.com" const formData = new FormData();
formData.append('email', 'john.doe@company.com');
const response = await fetch('https://api.corenexis.com/email-validator/v1', {
method: 'POST',
headers: { 'X-API-Key': 'your_api_key' },
body: formData
});
const data = await response.json();
console.log(data.data.status); Response format
Success response
{
"success": true,
"plan": "starter",
"data": {
"email": "john.doe@company.com",
"status": "deliverable",
"confidence": 0.95,
"syntax_valid": true,
"domain_exists": true,
"mx_found": true,
"spf_found": true,
"dmarc_found": true,
"dns_records": {
"mx": [
{ "host": "mx1.company.com", "priority": 10 },
{ "host": "mx2.company.com", "priority": 20 }
],
"spf": "v=spf1 include:_spf.company.com -all",
"dmarc": "v=DMARC1; p=reject; rua=mailto:dmarc@company.com"
},
"is_disposable": false,
"is_role_based": false,
"is_free_provider": false,
"smtp": {
"checked": true,
"deliverable": true,
"catch_all": false,
"code": 250,
"reason": "mailbox_exists",
"mx_host": "mx1.company.com"
}
},
"usage": {
"remaining": 4850,
"rate_limit": 30,
"monthly_limit": 5000
}
} Response fields
| Field | Type | Description |
|---|---|---|
email |
String | The email address that was validated |
status |
String | Overall verdict: deliverable, risky, undeliverable, unknown, invalid |
confidence |
Float | Confidence score from 0.0 to 1.0 (see the Status section) |
syntax_valid |
Boolean | Whether the email has a valid syntax format |
domain_exists |
Boolean | Whether the domain resolves in DNS |
mx_found |
Boolean | Whether MX records exist (domain can receive email) |
spf_found |
Boolean | Whether an SPF record exists |
dmarc_found |
Boolean | Whether a DMARC record exists |
dns_records |
Object | Contains mx, spf and dmarc when found |
dns_records.mx |
Array | MX records, each with host and priority |
is_disposable |
Boolean | Domain is a disposable/temporary email provider |
is_role_based |
Boolean | Address is role-based (info@, support@, admin@, …) |
is_free_provider |
Boolean | Domain is a free/webmail provider (Gmail, Outlook, Yahoo, …) |
smtp New |
Object | Live SMTP handshake result — see the SMTP check section |
smtp.checked |
Boolean | Whether an SMTP probe was performed |
smtp.deliverable |
Boolean / null | true = mailbox accepted, false = rejected, null = undetermined |
smtp.catch_all |
Boolean | Domain accepts every address (accept-all) |
smtp.code |
Integer / null | Raw SMTP reply code (e.g. 250, 550) |
smtp.reason |
String | Human-readable verdict (see reasons table) |
smtp.mx_host |
String / null | The MX host that was probed |
usage.remaining |
Integer | Remaining validations for this billing period |
usage.rate_limit |
Integer | Maximum requests allowed per minute |
usage.monthly_limit |
Integer | Maximum validations allowed per month |
SMTP verification & catch-all
Beyond DNS, the API opens a real connection to the recipient domain’s mail server (its highest-priority MX) and performs an SMTP handshake up to the RCPT TO stage to ask whether the mailbox exists. It then sends a second RCPT TO for a random address to detect catch-all domains.
- No email is ever sent — the probe stops before the
DATAstage, so nothing is delivered to the address you check. - Catch-all / accept-all — some domains reply
250to every recipient. A real and a fake mailbox get the identical answer, so the exact mailbox can’t be individually confirmed — the API returnsstatus: "risky"withcatch_all: true. - Free providers (Gmail, Outlook, Yahoo, …) are trusted and not probed; you still get a positive
smtp.deliverable: truewithreason: "trusted_provider".
{
"status": "risky",
"confidence": 0.5,
"is_free_provider": false,
"smtp": {
"checked": true,
"deliverable": null,
"catch_all": true,
"code": 250,
"reason": "accept_all",
"mx_host": "aspmx.l.google.com"
}
} {
"status": "deliverable",
"confidence": 0.8,
"is_free_provider": true,
"smtp": {
"checked": false,
"deliverable": true,
"catch_all": false,
"code": null,
"reason": "trusted_provider",
"mx_host": "gmail-smtp-in.l.google.com"
}
} smtp.reason values
| reason | deliverable | Meaning |
|---|---|---|
mailbox_exists |
true | Server confirmed this exact mailbox (250, not catch-all) |
trusted_provider |
true | Free/webmail provider — deliverable, not probed |
rejected |
false | Server rejected the mailbox (550) — it does not exist |
no_mx |
false | Domain has no mail server |
accept_all |
null | Domain accepts every address (catch-all) — can’t confirm this one |
provider_unverifiable |
null | Google Workspace / Microsoft 365 returned an unreliable 550 |
greylisted |
null | Temporary defer (4xx) — try again shortly |
no_response |
null | Connect/timeout/no greeting — couldn’t complete the probe |
Provider limitation (by design, not a bug). Google Workspace and Microsoft 365 accept every recipient at the SMTP stage to prevent address harvesting, so mailboxes hosted there cannot be individually confirmed by any provider. Those results come back risky (catch-all) or unknown — never a false deliverable. Use confidence + catch_all to apply your own policy.
Email status & confidence
The status field is the single verdict you’ll usually act on:
| Status | Meaning | Recommended action |
|---|---|---|
deliverable |
Mailbox confirmed to accept mail (SMTP 250), or a trusted free provider | Safe to accept / send |
risky |
Disposable domain, or a catch-all/accept-all domain where the exact mailbox can’t be confirmed | Accept with caution or send to manual review |
undeliverable |
The server rejected the mailbox (550), or the domain has no MX | Do not send — reject |
unknown |
Couldn’t determine right now — greylisting, no response, or a provider that hides mailbox existence | Retry later or review |
invalid |
Bad syntax or the domain doesn’t exist | Reject the email |
Confidence score
Every result carries a confidence from 0.0 to 1.0 so you can set a threshold that fits your risk tolerance. Typical values:
| Confidence | Typical case |
|---|---|
| 0.95 | Mailbox individually confirmed (SMTP 250, not catch-all) |
| 0.80 | Trusted free provider (Gmail, Outlook, Yahoo, …) |
| 0.50 | Catch-all domain, or an unverifiable/greylisted provider |
| 0.30 | Disposable / temporary domain |
| 0.02 | Mailbox explicitly rejected (SMTP 550) |
| 0.00 – 0.10 | Invalid syntax, or domain / MX missing |
Pro tip. Accept deliverable. Treat risky (check catch_all + is_disposable) per your own tolerance. Reject undeliverable and invalid. Retry unknown a little later. A simple rule: accept when confidence ≥ 0.7, review 0.4–0.7.
Error codes
Errors return success: false with either an error message or a machine-readable code.
| HTTP | Code | Description |
|---|---|---|
| 200 | OK | Validation succeeded — see the data object |
| 400 | Bad Request | Missing email parameter in the request |
| 401 | Missing API Key | The X-API-Key header is not present |
| 401 | INVALID_KEY |
API key is invalid, expired, or not found |
| 402 | NO_SUBSCRIPTION |
The Email Validator API is not enabled for your account. Subscribe to a plan first. |
| 402 | SUBSCRIPTION_EXPIRED |
Your subscription has expired. Please renew to continue. |
| 402 | SUBSCRIPTION_CANCELLED |
Your subscription was cancelled and the access period ended. |
| 403 | KEY_DISABLED |
Your API key has been disabled. Generate a new key from the dashboard. |
| 403 | ACCOUNT_SUSPENDED |
Your account has been suspended. Contact support. |
| 403 | EMAIL_NOT_VERIFIED |
Verify your account email before using the API. |
| 405 | Method Not Allowed | Only GET and POST are accepted |
| 429 | RATE_LIMIT_EXCEEDED |
Too many requests per minute. Wait and try again. |
| 429 | QUOTA_EXCEEDED |
Monthly quota reached. Upgrade your plan for more. |
| 500 | Server Error | Internal server error. Try again later. |
| 502 | Upstream Error | The validation engine returned an unexpected response. Retry. |
| 503 | Service Unavailable | Validation service temporarily unavailable. Retry shortly. |
Error response examples
// 401 — Invalid API Key
{
"success": false,
"code": "INVALID_KEY",
"message": "The provided API key is invalid or has been revoked."
} // 400 — Missing Email Parameter
{
"success": false,
"error": "Email is required."
} // 429 — Rate Limit Exceeded
{
"success": false,
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests. Please wait before making another request."
} // 429 — Monthly Quota Exceeded
{
"success": false,
"code": "QUOTA_EXCEEDED",
"message": "Monthly validation quota exceeded. Upgrade your plan for more."
} Rate limiting. Rate limits are applied per minute. If you receive a 429, wait 60 seconds before retrying. Consider upgrading your plan for higher limits.
Ready to get started?
Create your free account and start validating emails in minutes. No credit card required.