Email Verification API Documentation
Complete reference for the Mailvalid Email Verification API. Verify email addresses in real-time with syntax, domain, MX, and SMTP checks.
Fast & Reliable
Average response time under 500ms
95%+ Accuracy
Provider-optimized verification
Bulk Support
Up to 10,000 emails per request
https://mailvalid.io/api/v1
Authentication
All API requests require authentication using an API key. Include your
API key in the
X-API-Key
header.
Get your API key
Create a free account at mailvalid.io/register and generate an API key from your dashboard.
Step-by-Step Setup
-
1
Create an account
Sign up at mailvalid.io/register — 100 free credits included.
-
2
Generate an API key
Go to Dashboard → API Keys and click "Create New Key".
-
3
Add the header to your requests
Include
X-API-Key: mv_live_your_key_herein all API requests.
curl -X POST https://mailvalid.io/api/v1/verify/single \
-H "X-API-Key: mv_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'
Quickstart
Get started verifying emails in under 2 minutes. Choose your preferred language:
# Verify a single email
curl -X POST https://mailvalid.io/api/v1/verify/single \
-H "X-API-Key: mv_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'
import requests
API_KEY = "mv_live_your_key_here"
response = requests.post(
"https://mailvalid.io/api/v1/verify/single",
headers={"X-API-Key": API_KEY},
json={"email": "[email protected]"}
)
result = response.json()
print(f"Status: {result['result']['status']}") # valid, invalid, catch_all, unknown, do_not_mail
print(f"Valid: {result['result']['is_valid']}")
print(f"Confidence: {result['result']['confidence_score']}")
print(f"Reason: {result['result']['status_reason']}")
const API_KEY = "mv_live_your_key_here";
const response = await fetch(
"https://mailvalid.io/api/v1/verify/single",
{
method: "POST",
headers: {
"X-API-Key": API_KEY,
"Content-Type": "application/json"
},
body: JSON.stringify({ email: "[email protected]" })
}
);
const data = await response.json();
console.log(`Status: ${data.result.status}`); // valid, invalid, catch_all, unknown, do_not_mail
console.log(`Valid: ${data.result.is_valid}`);
console.log(`Confidence: ${data.result.confidence_score}`);
<?php
$apiKey = "mv_live_your_key_here";
$ch = curl_init("https://mailvalid.io/api/v1/verify/single");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
"X-API-Key: " . $apiKey,
"Content-Type: application/json"
],
CURLOPT_POSTFIELDS => json_encode(["email" => "[email protected]"])
]);
$result = json_decode(curl_exec($ch), true);
echo "Status: " . $result['result']['status']; // valid, invalid, catch_all, unknown, do_not_mail
echo "Valid: " . ($result['result']['is_valid'] ? 'Yes' : 'No');
echo "Confidence: " . $result['result']['confidence_score'];
?>
Single Email Verification
Verify a single email address in real-time. Returns comprehensive verification results including syntax, domain, MX records, and SMTP checks.
/api/v1/verify/single
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
email |
string | Required | The email address to verify |
Example Request
curl -X POST https://mailvalid.io/api/v1/verify/single \
-H "X-API-Key: mv_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'
Example Response
{
"success": true,
"credits_used": 1,
"result": {
"email": "[email protected]",
"status": "valid",
"is_valid": true,
"syntax_valid": true,
"domain": "company.com",
"domain_valid": true,
"has_mx": true,
"mx_records": [
{"priority": 10, "host": "mx1.company.com"}
],
"smtp_checked": true,
"smtp_response_code": 250,
"is_disposable": false,
"is_role_based": false,
"is_catch_all": false,
"is_free_provider": false,
"confidence_score": 95,
"status_reason": "mailbox_confirmed",
"provider": "corporate",
"verification_time_ms": 234,
"cached": false
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
status |
string | Verification status: valid, invalid, catch_all, unknown, do_not_mail |
is_valid |
boolean | Whether the email is safe to send to |
confidence_score |
integer | Confidence in the result (0–100) |
status_reason |
string | Machine-readable sub-status reason (see Status Values) |
provider |
string | Detected email provider (google, microsoft, yahoo, apple, corporate, etc.) |
is_disposable |
boolean | Whether the domain is a disposable/temporary email provider |
is_role_based |
boolean | Whether the address is role-based (info@, support@, admin@) |
is_catch_all |
boolean | Whether the domain accepts all email addresses |
is_free_provider |
boolean | Whether the domain is a free email provider (gmail.com, yahoo.com, etc.) |
cached |
boolean | Whether result was served from cache (cached results are free — 0 credits) |
Fair billing
unknown results (provider blocked verification) are free — 0 credits charged. Cached results are also free. You only pay for definitive results.
Bulk Email Verification
Verify up to 10,000 emails in a single request. Jobs are processed asynchronously. You can poll for status or receive a webhook notification when complete.
/api/v1/verify/bulk
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
emails |
array | Required | Array of email addresses (max 10,000) |
webhook_url |
string | Optional | URL to receive completion webhook |
Submit Bulk Job
curl -X POST https://mailvalid.io/api/v1/verify/bulk \
-H "X-API-Key: mv_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"emails": [
"[email protected]",
"[email protected]",
"[email protected]"
],
"webhook_url": "https://yourapp.com/webhooks/mailvalid"
}'
Response (Job Created)
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending",
"total_emails": 3,
"credits_reserved": 3,
"webhook_url": "https://yourapp.com/webhooks/mailvalid"
}
Check Job Status
curl https://mailvalid.io/api/v1/verify/bulk/550e8400-e29b-41d4-a716-446655440000 \
-H "X-API-Key: mv_live_your_key_here"
Completed Job Response
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"total_emails": 3,
"processed_emails": 3,
"valid_count": 2,
"invalid_count": 1,
"credits_used": 3,
"results": [
{
"email": "[email protected]",
"status": "valid",
"is_valid": true,
// ... full result for each email
}
]
}
Webhooks
Get notified when your bulk verification jobs complete instead of
polling. Provide a
webhook_url
when submitting a bulk job.
Verify webhook signatures
Always verify the
X-Mailvalid-Signature
header to ensure webhooks are from Mailvalid.
Webhook Payload
{
"event": "job.completed",
"timestamp": "2026-01-30T10:30:00Z",
"data": {
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"total_emails": 100,
"valid_count": 85,
"invalid_count": 15,
"credits_used": 100,
"results_summary": {
"total": 100,
"results_url": "/api/v1/verify/bulk/550e8400-e29b-41d4-a716-446655440000"
}
}
}
Webhook Headers
| Header | Description |
|---|---|
X-Mailvalid-Signature |
HMAC-SHA256 signature of the payload |
X-Mailvalid-Event |
Event type (job.completed, job.failed) |
Content-Type |
application/json |
Bounce Webhook
Feed delivery and bounce data back to Mailvalid to improve verification accuracy over time. This is especially valuable for providers that block SMTP verification (Microsoft, Apple) where we can't confirm mailboxes directly.
Improve accuracy automatically
The more bounce data you send, the more accurate future verifications become. Historical data is checked before SMTP verification, so known addresses return results instantly.
/api/v1/webhooks/bounce
API Key Required
Submit Bounce/Delivery Events
Send up to 1,000 bounce or delivery events per request. Hard bounces automatically invalidate cached verification results.
Event Types
| Event Type | Effect | Description |
|---|---|---|
delivered |
Marks valid | Email was successfully delivered to inbox |
hard_bounce |
Marks invalid | Permanent bounce — mailbox doesn't exist (550) |
soft_bounce |
Recorded | Temporary bounce — mailbox full, server down (452) |
complaint |
Marks do_not_mail | Recipient marked email as spam |
unsubscribe |
Recorded | Recipient unsubscribed from emails |
Request Body
{
"events": [
{
"email": "[email protected]",
"event_type": "hard_bounce",
"bounce_code": "550",
"bounce_message": "User unknown",
"timestamp": "2026-03-14T10:30:00Z"
},
{
"email": "[email protected]",
"event_type": "delivered"
}
]
}
Example
curl -X POST https://mailvalid.io/api/v1/webhooks/bounce \
-H "X-API-Key: mv_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"events": [
{"email": "[email protected]", "event_type": "hard_bounce", "bounce_code": "550"},
{"email": "[email protected]", "event_type": "delivered"}
]
}'
Response
{
"success": true,
"processed": 2,
"errors": 0,
"message": "Processed 2/2 events"
}
Job Management
List, download results from, and cancel your bulk verification jobs.
/api/v1/verify/bulk
List Your Jobs
Get a paginated list of all your bulk verification jobs.
| Parameter | Type | Default | Description |
|---|---|---|---|
page |
int | 1 | Page number |
page_size |
int | 20 | Items per page (max 100) |
status |
string | all | Filter by status |
curl "https://mailvalid.io/api/v1/verify/bulk?page=1&status=completed" \
-H "X-API-Key: mv_live_your_key_here"
/api/v1/verify/bulk/{job_id}/download
Download Results
Download verification results as JSON or CSV.
# Download as CSV
curl "https://mailvalid.io/api/v1/verify/bulk/{job_id}/download?format=csv" \
-H "X-API-Key: mv_live_your_key_here" \
-o results.csv
# Download as JSON
curl "https://mailvalid.io/api/v1/verify/bulk/{job_id}/download?format=json" \
-H "X-API-Key: mv_live_your_key_here" \
-o results.json
/api/v1/verify/bulk/{job_id}
Cancel a Job
Cancel a pending or processing job. Reserved credits will be refunded.
curl -X DELETE https://mailvalid.io/api/v1/verify/bulk/{job_id} \
-H "X-API-Key: mv_live_your_key_here"
HTTP Response Codes
| Code | Status | Description |
|---|---|---|
| 200 | OK | Request successful |
| 201 | Created | Resource created (bulk job submitted) |
| 400 | Bad Request | Invalid request format or parameters |
| 401 | Unauthorized | Missing or invalid API key |
| 402 | Payment Required | Insufficient credits |
| 404 | Not Found | Resource not found |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Server Error | Internal server error |
Email Status Values
Industry-standard status codes (same as ZeroBounce, NeverBounce). The
status
field indicates the verification result. The
status_reason
field gives the specific machine-readable reason.
Status Codes
| Status | is_valid | Description | Action |
|---|---|---|---|
valid |
true | SMTP confirmed mailbox exists. Safe to send. (<2% bounce rate) | Safe to send |
invalid |
false | Address will bounce — bad syntax, no domain, or mailbox not found | Do not send |
catch_all |
false | Domain accepts all addresses. Cannot confirm individual mailbox | Send with caution |
unknown |
false | Could not determine validity (provider blocked SMTP, timeout). Free — 0 credits charged | Retry later or use bounce webhook |
do_not_mail |
false | Address may work but is risky — disposable, role-based (info@, support@), or spam complaint | Do not send marketing |
Sub-Status Reasons
The status_reason
field gives the specific reason behind the status:
| status_reason | Status | Meaning |
|---|---|---|
mailbox_confirmed |
valid |
SMTP server confirmed the mailbox exists (250 response) |
historical_delivery_confirmed |
valid |
Email was previously delivered successfully (from bounce webhook data) |
mailbox_not_found |
invalid |
SMTP server rejected the recipient (550 response) |
failed_syntax_check |
invalid |
Email address format is invalid |
no_dns_entries |
invalid |
Domain does not exist (no DNS records) |
no_mx_records |
invalid |
Domain exists but has no MX records configured |
historical_hard_bounce |
invalid |
Email previously hard-bounced (from bounce webhook data) |
accept_all |
catch_all |
Domain accepts all addresses — individual mailbox cannot be confirmed |
failed_smtp_connection |
unknown |
Provider blocks SMTP verification (Microsoft, Apple) |
antispam_system |
unknown |
Anti-spam system blocked our verification attempt |
greylisted |
unknown |
Server uses greylisting — temporarily rejected |
mail_server_temporary_error |
unknown |
Mail server returned a temporary error |
disposable |
do_not_mail |
Disposable/temporary email domain (e.g. mailinator.com) |
role_based |
do_not_mail |
Role-based address (info@, support@, admin@) |
historical_complaint |
do_not_mail |
Recipient previously filed a spam complaint (from bounce webhook data) |
Confidence Score
Every result includes a
confidence_score
(0–100) indicating how confident we are in the result:
| Range | Meaning |
|---|---|
| 90–100 | Very high confidence — SMTP confirmed, historical hard bounce, or syntax/domain failure |
| 70–89 | High confidence — historical delivery data, trusted provider response |
| 40–69 | Medium confidence — catch-all domain, DNS-only verification |
| 0–39 | Low confidence — provider blocked verification, timeout |
Rate Limits
API requests are rate limited to ensure fair usage and platform stability.
| Limit Type | Value | Window |
|---|---|---|
| Per API Key | 100 requests | Per minute |
When rate limited, the API returns 429 Too Many Requests.
Back off and retry after the time specified in the Retry-After header.
Need higher limits? Contact us at [email protected] for custom rate limits on higher volume plans.
Rate Limit Headers
All responses include rate limit information:
| Header | Description |
|---|---|
X-RateLimit-Limit |
Maximum requests allowed in the current window |
X-RateLimit-Remaining |
Remaining requests in the current window |
Retry-After |
Seconds until rate limit resets (when limited) |
Error Responses
When an error occurs, the API returns a consistent error format:
{
"detail": "Error message describing what went wrong"
}
Common Errors
| Error | Code | Solution |
|---|---|---|
| Invalid API key | 401 | Check your API key is correct and active |
| Insufficient credits | 402 | Purchase more credits from your dashboard |
| Rate limit exceeded | 429 | Wait for the Retry-After period |
| Invalid email format | 422 | Check the email address format |
| Bulk job too large | 400 | Maximum 10,000 emails per request |
Need Help?
Can't find what you're looking for? Try our interactive API docs or get in touch.