Loading your dashboard…
EmailVerify Pro
Admin
Dashboard
Your email verification activity over the last 30 days.
Verifications · last 30 days
Monthly Quota
/
Valid
Invalid
Catch-all
Unknown

Daily verifications

Last 30 days

Top domains

By count
Loading…

Recent verifications

EmailStatusScoreProviderVerified
Loading…
API Keys
Create and manage keys for the EmailVerify Pro API.
Loading keys…
API Reference
Everything you need to integrate EmailVerify Pro into your stack.
Getting Started
Verification
Response Format
Tools

Authentication

Every request needs your API key. Create one on the .
Header (recommended)
X-API-Key: evp_live_your_key
Query parameter
?api_key=evp_live_your_key
Base URL http://52.87.60.126:8000

Quick Start

Verify your first email in under a minute. The /validate/checks endpoint is the one call you need — it returns 45+ normalized signals in a consistent format perfect for database storage.
curl "http://52.87.60.126:8000/validate/checks?email=brandon@seamlessai.com" \
  -H "X-API-Key: evp_live_your_key_here"
import requests

API_KEY = "evp_live_your_key_here"
BASE    = "http://52.87.60.126:8000"

def verify(email):
    r = requests.get(
        f"{BASE}/validate/checks",
        params={"email": email},
        headers={"X-API-Key": API_KEY}
    )
    return r.json()

result = verify("brandon@seamlessai.com")
print(result["summary"]["status"])   # "valid"
print(result["summary"]["score"])    # 91
print(result["summary"]["grade"])    # "A"
print(result["checks"]["smtp"])      # "valid"
print(result["checks"]["microsoft_365"])  # "exists"
const verify = async (email) => {
  const res = await fetch(
    `http://52.87.60.126:8000/validate/checks?email=${encodeURIComponent(email)}`,
    { headers: { "X-API-Key": "evp_live_your_key_here" } }
  );
  return res.json();
};

const result = await verify("brandon@seamlessai.com");
console.log(result.summary.status);  // "valid"
console.log(result.summary.score);   // 91

Single Email Verification

Four endpoints depending on how much you need and how fast you need it.
GET /validate/checks 45+ normalized signals — best for DB insert
Recommended. Returns consistent string values (valid, not_found, not_checked) — no type-juggling, drop straight into your database.
ParamTypeRequiredDescription
emailstringYESEmail address to verify
smtpbooldefault: trueRun SMTP probe (most accurate, ~1-2s)
rblbooldefault: trueCheck MX IP against blacklists
breachbooldefault: falseHIBP breach lookup (costs 1 extra credit)
curl "http://52.87.60.126:8000/validate/checks?email=john@stripe.com" \
  -H "X-API-Key: evp_live_your_key_here"
GET /validate Full raw verification — all fields, no normalization

Returns the full unprocessed result object. Use /validate/checks instead unless you need raw fields. Same parameters as /validate/checks.

POST /validate
{
  "email": "john@stripe.com",
  "smtp": true,
  "breach": false,
  "webhook_url": "https://your-site.com/webhook"
}
GET /validate/quick Syntax + DNS only — no SMTP, <100ms

Skips SMTP. Good for real-time form validation. Catches invalid syntax, missing MX, disposable emails, and typos instantly.

curl "http://52.87.60.126:8000/validate/quick?email=user@company.com" \
  -H "X-API-Key: evp_live_your_key_here"
GET /validate/fast Cache-only — sub-50ms if previously verified

Returns 404 if no cached result — call /validate/checks to do a fresh verification first. TTLs: valid/invalid = 7 days, catch-all = 12 months, unknown = 24h.

curl "http://52.87.60.126:8000/validate/fast?email=user@company.com" \
  -H "X-API-Key: evp_live_your_key_here"

Bulk Verification

Three modes — pick based on list size and whether you need results synchronously.
POST /validate/bulk/turbo Best bulk option — cache-first, 50× concurrency, up to 5,000
Recommended for most bulk use cases. Cache hits return in ~50ms. Groups misses by domain to avoid hammering the same MX. Synchronous — waits for all results.
POST /validate/bulk/turbo
{
  "emails": ["alice@company.com", "bob@other.com", ...],
  "smtp": true,
  "deduplicate": true
}
{
  "results": [ ... ],          // array of /validate responses
  "stats": {
    "total": 500,
    "cache_hits": 312,
    "fresh_verified": 188,
    "elapsed_seconds": 8.4,
    "emails_per_second": 59.5
  }
}
POST /validate/bulk/async Fire and forget — for lists > 5,000 emails

Returns a job_id immediately. Poll GET /jobs/{job_id} every few seconds until status = "complete".

# 1. Submit
curl -X POST "http://52.87.60.126:8000/validate/bulk/async" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: evp_live_your_key_here" \
  -d '{"emails": ["a@co.com", ...], "smtp": true}'
# → {"job_id": "abc123", "status": "queued", "total": 50000}

# 2. Poll
curl "http://52.87.60.126:8000/jobs/abc123" \
  -H "X-API-Key: evp_live_your_key_here"
# → {"status": "complete", "results": [...], "pct_complete": 100}
POST /validate/bulk Sync bulk — up to 100 emails, waits for all results

Same as turbo but without the cache-first optimization. Limit 100 emails per call. Use turbo for better performance.

Async Jobs

Manage long-running bulk jobs submitted via /validate/bulk/async.
GET /jobs/{job_id} Poll job status and results
{
  "job_id": "abc123",
  "status": "complete",   // queued | running | complete | failed
  "total": 5000,
  "progress": 5000,
  "pct_complete": 100.0,
  "results": [ ... ]      // only present when status = "complete"
}
POST /jobs/{job_id}/retry-dead-letter Re-queue emails that failed all retries

Creates a child job with just the failed emails. Returns a new job_id to poll.

Full Response Format

What /validate returns — every field explained. For a cleaner version, use /validate/checks (next section).
{
  // ── Identity ──────────────────────────────────────────────────
  "email": "john.smith@stripe.com",
  "status": "valid",             // valid | invalid | accept_all | unknown | invalid_syntax
  "sub_status": null,            // m365_confirmed | greylisted | known_catchall_domain | ...
  "confidence_score": 94,        // 0–100

  // ── Deliverability score ──────────────────────────────────────
  "deliverability_score": {
    "score": 91,                 // 0–100
    "grade": "A",                // A | B | C | D | F
    "can_send": true,            // should you email this address?
    "primary_risk": null,        // what's stopping a higher score
    "breakdown": { ... }         // per-signal score contributions
  },

  // ── DNS ───────────────────────────────────────────────────────
  "mx_found": true,
  "mx_records": [{"priority": 10, "host": "aspmx.l.google.com"}],
  "spf_record": "v=spf1 include:...",
  "dmarc_record": "v=DMARC1; p=quarantine",
  "domain_age_days": 4521,
  "domain_age_risk": "low",

  // ── SMTP ──────────────────────────────────────────────────────
  "smtp_response_code": 250,     // 250=valid, 550=invalid, 450=greylisted
  "smtp_provider": "google",     // microsoft | google | yahoo | generic
  "smtp_provider_name": "Google Workspace",
  "supports_tls": true,
  "catch_all": false,
  "is_greylisted": false,

  // ── Provider directories ──────────────────────────────────────
  "ms_account_exists": null,     // Microsoft 365 directory check
  "google_ws_exists": true,      // Google Workspace directory check
  "google_ws_full_name": "John Smith",

  // ── Email type ────────────────────────────────────────────────
  "role_email": false,           // info@, support@, noreply@ etc.
  "free_email": false,           // gmail.com, yahoo.com, hotmail.com
  "disposable_email": false,     // temp/throwaway domains
  "spam_trap_indicator": false,

  // ── Pattern / ML ──────────────────────────────────────────────
  "pattern_score": 85,           // human-likeness 0–100
  "pattern_type": "first.last",  // email format pattern detected
  "is_name_pattern": true,
  "is_random_string": false,

  // ── Breach / identity ─────────────────────────────────────────
  "found_in_breach": null,       // null = not checked (breach=false)
  "breach_count": 0,
  "gravatar_exists": false,

  // ── Reputation ────────────────────────────────────────────────
  "mx_blacklisted": false,
  "mx_blacklists": [],
  "mx_reputation_score": 98,
  "tld_risk": "low"
}

Checks Format (/validate/checks)

The normalized response — 45 signals as consistent strings. Designed for direct INSERT into a verification_results database table.
{
  "email": "john.smith@stripe.com",

  "summary": {
    "status":       "valid",     // valid | invalid | accept_all | unknown
    "sub_status":   null,
    "can_send":     true,
    "score":        91,          // 0–100
    "grade":        "A",         // A B C D F
    "primary_risk": null,
    "confidence":   94
  },

  "checks": {
    // Syntax
    "syntax":             "valid",          // valid | invalid
    "idn_domain":         "no",
    "unicode_local_part": "no",

    // DNS
    "mx":     "found",                      // found | not_found
    "spf":    "configured",                 // configured | missing
    "dmarc":  "configured",
    "dkim":   "configured",                 // configured | missing | not_checked

    // SMTP
    "smtp":          "valid",               // valid | invalid | greylisted | code_NNN | not_checked
    "smtp_provider": "google",              // microsoft | google | yahoo | generic
    "tls_supported": "yes",                 // yes | no | not_checked
    "catch_all":     "no",                  // no | yes_resolved | yes_unresolved
    "greylisted":    "no",

    // Provider directories
    "microsoft_365":    "not_found",        // exists | not_found | exists_suspended | not_checked
    "google_workspace": "exists",
    "gmail":            "not_checked",
    "yahoo_mail":       "not_checked",
    "apple_icloud":     "not_checked",
    "protonmail":       "not_found",

    // Reputation
    "mx_blacklisted":      "no",            // no | yes_N_listings
    "domain_age":          "mature",        // very_new | new | established | mature
    "tld_risk":            "low",
    "mx_reputation_score": 98,

    // Email type flags
    "role_email":       "no",               // yes | no
    "free_email":       "no",
    "disposable_email": "no",
    "spam_trap":        "no",

    // Pattern / identity
    "name_pattern_match": "yes",
    "is_random_string":   "no",
    "pattern_score":      85,
    "pattern_type":       "first.last",

    // Breach / web presence
    "have_i_been_pwned":  "not_checked",    // not_checked | not_found | N_breaches
    "gravatar_profile":   "not_found",      // found | not_found | not_checked
    "linkedin":           "not_checked",
    "web_presence":       "yes",

    // Inbox ground truth
    "confirmed_received":  "no",            // yes = email appeared in inbox before
    "domain_inbox_active": "unknown"        // active | unknown
  },

  "score_breakdown": {
    "smtp_valid":      +30,
    "google_ws":       +20,
    "name_pattern":    +10,
    "domain_age":      +10,
    ...
  }
}

Email Finder

Find the corporate email for any person by name + company domain. Uses pattern matching, web scraping, and SMTP verification. ~70%+ find rate on Fortune 1000. Costs 5 credits.
POST /find-email/v2 Find verified email by first name, last name, domain
ParamTypeRequiredDescription
first_namestringYESFirst name
last_namestringYESLast name
domainstringYESCompany domain (e.g. stripe.com)
company_namestringoptionalImproves web scraping accuracy
do_smtpbooldefault: trueSMTP-verify each candidate email
curl -X POST "http://52.87.60.126:8000/find-email/v2?first_name=John&last_name=Smith&domain=stripe.com" \
  -H "X-API-Key: evp_live_your_key_here"
{
  "best_email": "john.smith@stripe.com",
  "best_confidence": 0.91,
  "domain_format": "first.last",    // the format this company uses
  "domain_format_confidence": 0.88,
  "candidates": [
    {
      "email": "john.smith@stripe.com",
      "confidence": 0.91,
      "format_type": "first.last",
      "verified": true,
      "smtp_status": "valid"
    }
  ],
  "find_time_ms": 1840,
  "credits_used": 5
}

Suppression List

Manage your do-not-contact list. Hard bounces and spam complaints are auto-added. Every /validate call checks suppression status automatically.
GET /suppression/check?email= Is this email suppressed?
curl "http://52.87.60.126:8000/suppression/check?email=user@company.com"
# → {"is_suppressed": false, "reason": null, "should_never_send": false}
POST /suppression/add Add email to suppression list
curl -X POST "http://52.87.60.126:8000/suppression/add" \
  -H "Content-Type: application/json" \
  -d '{"email": "optout@co.com", "reason": "unsubscribe"}'
DELETE /suppression/{email} Remove from suppression list
curl -X DELETE "http://52.87.60.126:8000/suppression/optout@co.com" \
  -H "X-API-Key: evp_live_your_key_here"

Feedback & ML Training

Send delivery outcomes back to improve accuracy over time. The ML model retrains on every bounce and confirmed delivery you report.
POST /bounce Report a real bounce — trains ML + auto-suppresses hard bounces
curl -X POST "http://52.87.60.126:8000/bounce" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@company.com",
    "bounce_type": "hard_bounce",
    "bounce_code": "550",
    "bounce_msg": "User unknown"
  }'
POST /received/batch Mark emails as confirmed received — highest quality signal
High-value. Emails confirmed as received get a +25 score bonus on all future verifications, bypassing catch-all penalties. Send inbox senders here regularly.
curl -X POST "http://52.87.60.126:8000/received/batch" \
  -H "Content-Type: application/json" \
  -d '{
    "senders": [
      {"email": "john@company.com", "received_at": "Mon, Jun 16, 2026, 9:10 AM"}
    ],
    "source": "inbox"
  }'
Want the full API explorer?
Every endpoint with live Try-it-out, request schemas, and response examples.
Open Swagger UI →