Integrate email verification
in under 10 minutes
JSON REST API. Bearer token authentication. Latency <200 ms. 100% Verification run in France, GDPR compliant.
Base URL
https://api.mailcheck.fr/v1All requests are over HTTPS. Insecure HTTP calls are rejected with a 400 code.
Authentication
All requests require a Bearer token in the Authorization header.
Your API key is available in the dashboard, under Settings > API Key.
Authorization: Bearer mc_live_xxxxxxxxxxxxxxxxxxxx MAILCHECK_API_KEY).
POST /v1/verify, verifying an address
Verifies a single email address. Returns the status, the score and the verification details.
Request
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | The email address to verify |
options.catch_all | boolean | No | Enables catch-all detection (default: true) |
{
"email": "[email protected]",
"options": {
"catch_all": true
}
} Response format
The response is a JSON object with the following fields:
| Field | Type | Description |
|---|---|---|
email | string | The verified address (normalized to lowercase) |
status | string | valid / invalid / risky / catch_all / disqualifie |
score | integer | Confidence score 0–100 (≥80 = reliable) |
checks.syntax | boolean | Valid RFC 5322 syntax |
checks.dns | boolean | Domain resolved in DNS |
checks.mx | boolean | MX records present and active |
checks.smtp | boolean | Mailbox confirmed via SMTP |
checks.disposable | boolean | Disposable address detected |
checks.catch_all | boolean | Catch-all (wildcard) server detected |
confidence | string | high / medium / low |
{
"email": "[email protected]",
"status": "valid",
"score": 97,
"checks": {
"syntax": true,
"dns": true,
"mx": true,
"smtp": true,
"disposable": false,
"catch_all": false
},
"confidence": "high"
} Returned statuses
| Status | Meaning | Recommended action |
|---|---|---|
| valid | Mailbox confirmed via SMTP, active domain, not disposable | Include in your sends |
| risky | Valid syntax and DNS but ambiguous SMTP or catch-all detected | Send with caution or segment separately |
| catch_all | Server accepts all incoming email (wildcard) | Decide based on your risk tolerance |
| invalid | Nonexistent mailbox confirmed by the server, invalid domain or incorrect syntax | Remove from the list immediately |
| disqualifie | Disposable address (domain in our blocklist) | Remove, never any purchase intent |
cURL example
# Verify an email address
curl -X POST https://api.mailcheck.fr/v1/verify \
-H "Authorization: Bearer mc_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","options":{"catch_all":true}}' Python example
import os
import requests
API_KEY = os.environ["MAILCHECK_API_KEY"]
def verify_email(email: str) -> dict:
response = requests.post(
"https://api.mailcheck.fr/v1/verify",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"email": email,
"options": {"catch_all": True}
},
timeout=5
)
response.raise_for_status()
return response.json()
# Usage example
result = verify_email("[email protected]")
if result["status"] == "valid":
print(f"✓ Valid email · Score: {result['score']}")
else:
print(f"✗ Status: {result['status']}") Node.js example
const API_KEY = process.env.MAILCHECK_API_KEY;
async function verifyEmail(email) {
const res = await fetch("https://api.mailcheck.fr/v1/verify", {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
email,
options: { catch_all: true }
})
});
if (!res.ok) {
throw new Error(`API error: ${res.status}`);
}
return res.json();
}
// Usage example
verifyEmail("[email protected]")
.then(data => {
console.log(`Status: ${data.status} · Score: ${data.score}`);
})
.catch(console.error); Rate limits
Limits apply per API key over a sliding window of 1 second.
| Plan | Requests / second | Verifications / month |
|---|---|---|
| Starter | 10 req/s | 5,000 |
| Growth | 50 req/s | 50,000 |
| Pro | 200 req/s | 200,000 |
| Agency | 200 req/s | 1,000,000 |
When exceeded, the API returns a 429 Too Many Requests with a
Retry-After header indicating the wait time in seconds.
Error codes
| HTTP code | Error code | Description |
|---|---|---|
| 400 | invalid_request | Invalid request body or missing email field |
| 401 | unauthorized | Missing or invalid API key |
| 402 | insufficient_credits | Monthly quota exhausted, top up your plan |
| 429 | rate_limit_exceeded | Too many requests, see the Retry-After header |
| 500 | server_error | Internal error, retry in a few seconds |
{
"error": "insufficient_credits",
"message": "Your monthly quota is exhausted. Upgrade your plan.",
"credits_remaining": 0
} Ready to integrate?
Create your account for free and get your API key in under a minute. 2 free verifications.