Valid Email Checker

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.

API access requires a paid purchase
Free 150-credit signups can use the dashboard verifier, bulk uploads, and integrations — but not the API. The API endpoint returns 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

PropertyValue
URLhttps://app.validemailchecker.com/api/verify-single
MethodPOST
Content-Typeapplication/json
AuthenticationBearer token in Authorization header
Credits1 per call (refunded if result is unknown)
Rate limit60 requests/minute, 10,000/day
Typical response time1–3 seconds

cURL

bash
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

javascript
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

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)

json
{
  "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

HTTPBody shapeCause
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

Past ~50 addresses, switch to bulk
If you are processing more than a handful of addresses at once, hit the bulk endpoint (/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