How do I verify a single email with the API?
Single-email verification is one POST request. Send the address, get a JSON result back. The full endpoint URL is https://app.validemailchecker.com/api/verify-single — note the API lives on the main app. domain, not on a separate api. subdomain.
401 Invalid or inactive API key for accounts that have not yet purchased credits. See how do I get an API key for the unlock path.Endpoint reference
| Property | Value |
|---|---|
| URL | https://app.validemailchecker.com/api/verify-single |
| Method | POST |
| Content-Type | application/json |
| Authentication | Bearer token in Authorization header |
| Credits | 1 per call (refunded if result is unknown) |
| Rate limit | 60 requests/minute, 10,000/day |
| Typical response time | 1–3 seconds |
cURL
curl -X POST https://app.validemailchecker.com/api/verify-single \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "john@example.com"}'JavaScript / Node.js
const response = await fetch(
'https://app.validemailchecker.com/api/verify-single',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.VEC_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ email: 'john@example.com' }),
}
);
const result = await response.json();
console.log(result.status); // 'safe', 'invalid', 'disposable', etc.Python
import os
import requests
response = requests.post(
'https://app.validemailchecker.com/api/verify-single',
headers={
'Authorization': f"Bearer {os.environ['VEC_API_KEY']}",
'Content-Type': 'application/json',
},
json={'email': 'john@example.com'},
)
result = response.json()
print(result['status'])What you get back (200 OK)
{
"email": "john@example.com",
"status": "safe",
"is_valid": true,
"is_disposable": false,
"is_role_account": false,
"is_catch_all": false,
"is_free_email": false,
"mx_found": true,
"domain": "example.com",
"risk_score": 5,
"deliverability": "high",
"credits_used": 1,
"verified_at": "2026-05-19T14:23:11Z",
"reason": "Valid mailbox"
}The status field is the canonical result from the 11-step verification engine: safe, risky, invalid, disposable, catch_all, role_account, spamtrap, disabled, inbox_full, or unknown. The risk_score is 0–100 (higher = riskier — inverse of the dashboard confidence score). The other boolean flags give you finer-grained signals so you can make per-application policy decisions.
Typical patterns
Signup form
Call /verify-single inline before allowing the account to be created. If status is disposable or invalid, reject with an error. If catch_all or role_account, allow but flag in your CRM for lower-priority follow-up.
Lead enrichment
Call asynchronously after a lead lands in your CRM. Store the status alongside the lead record. Filter campaigns on the stored status, not at send time — verification is point-in-time and addresses can decay between when you check and when you send.
CRM hygiene
Nightly job that re-verifies stale records. Addresses go bad over time, especially work emails after job changes. Re-verifying contacts on a rolling 30–60 day schedule keeps your list health steady.
Common errors
| HTTP | Body shape | Cause |
|---|---|---|
| 400 | { "error": "Email is required" } | Missing email field |
| 401 | { "error": "Missing or invalid Authorization header. Use: Authorization: Bearer VEC..." } | No Bearer token |
| 401 | { "error": "Invalid or inactive API key" } | Wrong key, or key was deleted/disabled, or account hasn't purchased credits yet |
| 402 | { "error": "Insufficient credits", "current_balance": 0 } | Zero credits available |
| 403 | { "error": "API key is suspended" } | Key was suspended (by you or by abuse-protection) |
| 429 | { "error": "Rate limit exceeded", "retry_after_seconds": 45 } | 60+ requests in the last minute |
| 500 | { "error": "Internal server error" } | Issue on our side — retry |
See API rate limits and error handling for the full error matrix and backoff patterns.
For lists, use bulk
/api/verify-bulk) instead of looping single-verify. Bulk is one request for the entire list, generates a task_id you poll once it completes, and is much more rate-limit-friendly. See bulk verification endpoint for the full async flow.Next steps
Related questions
Still stuck? Email support