API Documentation
Validate email addresses programmatically with our REST API, or embed our widget on your site.
Authentication
All API requests require authentication via your API key. Find your key in your dashboard under Team → API Keys.
Include the key in the Authorization header:
Authorization: Api-Key YOUR_API_KEY
Validate an Email
/api/validate/
Request Body
{
"email": "user@example.com"
}
Response
{
"id": 1234,
"email": "user@example.com",
"is_valid": true,
"is_blacklist": false,
"valid_format": true,
"valid_domain": true,
"valid_nameserver": true,
"dns_timeout": false,
"dns_config_error": false,
"no_mx": false,
"no_valid_mx": false,
"disposable": false,
"is_catch_all": false,
"is_role_account": false,
"is_free_email": false,
"processing": false,
"last_validated": "2026-03-11T12:00:00Z"
}
Response Fields
| Field | Type | Description |
|---|---|---|
is_valid | boolean | Whether the mailbox exists and accepts email (SMTP RCPT TO check) |
valid_format | boolean | Whether the email address syntax is valid (RFC 5322) |
valid_domain | boolean | Whether the domain exists in DNS |
valid_nameserver | boolean | Whether the domain has functioning nameservers |
disposable | boolean | Whether the email is from a known disposable/temporary provider |
is_catch_all | boolean | Whether the domain accepts all email addresses (catch-all) |
is_role_account | boolean | Whether the address is a role account (info@, admin@, support@, etc.) |
is_free_email | boolean | Whether the email is from a free provider (Gmail, Yahoo, Outlook, etc.) |
is_blacklist | boolean | Whether the domain appears on email blacklists |
no_mx | boolean | Whether the domain has no MX records |
dns_timeout | boolean | Whether the DNS lookup timed out |
processing | boolean | Whether the validation is still in progress (async) |
Example (cURL)
curl -X POST https://app.mailvalidation.io/api/validate/ \
-H "Authorization: Api-Key YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com"}'
Status Codes
201 | Success — email validated |
400 | Invalid request body |
401 | Missing or invalid API key |
402 | Validation limit reached — upgrade your plan |
429 | Rate limit exceeded (1,000 requests/hour per user) |
Embeddable Widget
Add real-time email validation to any website form with a single line of JavaScript. No backend changes needed.
Quick Start
1. Create a widget in your dashboard under Widgets.
2. Copy the embed code and paste it before the closing </body> tag on your site.
<script src="https://app.mailvalidation.io/static/mv/widget.js"
data-mv-key="YOUR_WIDGET_KEY"></script>
The widget automatically validates all <input type="email"> fields on the page.
Attributes
data-mv-key | Required. Your widget API key (from the dashboard). |
data-mv-validate | Add to any non-email input to opt it into validation. |
data-mv-skip | Add to any email input to skip validation. |
Widget API Endpoint
/api/widget/{widget_key}/validate/
This is the endpoint the widget JS calls. CORS-enabled, no authentication required — the widget key identifies your account.
// Request
POST /api/widget/a1b2c3d4-e5f6-7890-abcd-ef1234567890/validate/
Content-Type: application/json
{"email": "user@example.com"}
// Response
{
"valid": true,
"reason": "valid",
"message": "Email is valid.",
"branding": {
"text": "Protected by MailValidation.io",
"url": "https://mailvalidation.io"
}
}
Widget Response Reasons
valid | Email passed all checks |
invalid_format | Email syntax is invalid |
invalid_smtp | Mailbox could not be verified |
disposable | Disposable email blocked |
free_email | Free email provider blocked |
role_account | Role account (info@, admin@) blocked |
limit | Account validation limit reached |
Rate Limits
| Authenticated users | 1,000 requests / hour |
| Anonymous / unauthenticated | 100 requests / hour |
| Widget API | No separate rate limit (counts against your plan's monthly allowance) |
Webhooks
Configure webhook endpoints to receive notifications when events occur.
Events
bulk_complete | Fired when a bulk validation upload finishes processing |
widget_block | Fired when a widget blocks an email submission |
Payload Format
POST https://your-endpoint.com/webhook
Content-Type: application/json
X-MV-Signature: hmac_sha256_hex_digest (if signing secret is set)
{
"event": "bulk_complete",
"data": {
"bulk_upload_id": 42,
"filename": "contacts.csv",
"total": 500,
"valid": 420,
"invalid": 80,
"health_score": 84.0
}
}