VerifyMail

Stop fake signups with a
single API call

Detect disposable, catch-all, and abusive email addresses at the moment of registration — with explainable signals, not a boolean.

Get 100 checks for free →No credit card · Credits never expire · p99 under 28ms
POSThttps://api.verifymailapi.com/v1/check
{
  "meta": {
    "request_id": "req_7f3a2c1b4e5d",
    "domain": "mailinator.com",
    "latency_ms": 4,
    "path_taken": "fast"
  },
  "verdict": {
    "recommendation": "block",
    "risk_level": "critical",
    "disposable": true,
    "summary": "Domain is a confirmed disposable email provider."
  },
  "score": {
    "value": 100,
    "confidence": 1.0,
    "confidence_level": "high"
  },
  "signals": {
    "fired": [
      { "name": "known_disposable_domain", "weight": 100 }
    ]
  }
}

It's simple and it's fast.
Here's how it works.

01

Sign up

Get 100 free checks on signup. Then buy credits — bundles from $0.0016/check. No subscriptions, no monthly minimums.

02

Call our API

Send a single HTTP request with the email. Get back a confidence-scored risk verdict in under 100ms.

03

Block fake signups

Switch on the recommendation value — block / verify / flag / allow — and stop trial abuse before it starts.

You get responses that are…

01 — SCORED

Confidence-scored, not boolean

A 0–100 risk score paired with a confidence value between 0 and 1. The verdict recommendation is always one of four values — block, verify_manually, allow_with_flag, allow — so you can switch on it in code without parsing thresholds.

"score": {
  "value": 94,
  "confidence": 0.91,
  "confidence_level": "high"
},
"verdict": {
  "recommendation": "block",
  "risk_level": "critical"
}
02 — EXPLAINABLE

Every signal, every weight

Every response includes a signals array listing which signals fired, their direction (risk or trust), their weight, and why. Debug false positives in 10 seconds instead of opening a support ticket.

"fired": [
  { "name": "catch_all_confirmed",
    "direction": "risk", "weight": 55 },
  { "name": "domain_age_14_days",
    "direction": "risk", "weight": 42 },
  { "name": "mx_shared_with_9_domains",
    "direction": "risk", "weight": 35 }
]
03 — CATCH-ALL AWARE

Catch-all detection built in

A Bayesian confidence model catches rotating catch-alls that defeat naive SMTP probes — combining infrastructure signals, behavioral history, and cross-customer network data into a single probability.

Evidence → Probability
SMTP probe
Infrastructure
Behavioral history
Network data
04 — FAST

Fast by design

85% of traffic resolves from in-memory caches in under 5ms. Weighted p99 latency across all checks is under 28ms. Async-with-preliminary path for deep checks so your signup flow never waits.

Latency distribution
cache hit
<5ms
fast path
<150ms
deep check
<800ms

Powerful SDKs

Use VerifyMail with your favorite language or framework.

verify.jsNode 18+ / ESM
import { VerifyMail } from 'verifymail';

const client = new VerifyMail({ apiKey: 'vm_live_...' });

const result = await client.check('user@mailinator.com');

switch (result.verdict.recommendation) {
  case 'block':
    throw new Error(result.verdict.summary);
  case 'verify_manually':
    queueForReview(email, result); break;
  case 'allow_with_flag':
    logSuspicious(email, result.signals.fired); break;
  case 'allow':
    // safe to proceed
    break;
}
Signal catalog

Every verdict is built from real signals.

A preview of what the API actually checks — grouped by category, each with a weight in the score.

Blocklist
  • known_disposable_domain+100
  • mx_on_abuse_list+80
  • asn_known_bad+60
Infrastructure
  • catch_all_confirmed+55
  • domain_age_under_30d+42
  • mx_shared_with_n_domains+35
  • spf_missing+18
Pattern
  • random_localpart+38
  • plus_addressing_suspicious+22
  • role_based_address+15
  • gmail_dot_trick+12
Behavioral
  • signup_velocity_high+45
  • seen_across_n_tenants+30
  • first_seen_within_hours+20
Trust
  • corporate_domain−40
  • domain_age_over_5y−25
  • reputable_mx_provider−20
And more

40+ signals across 6 categories. Every one returned in the signals.fired[] array with name, direction, and weight. Full list in the docs.

Test out the API in seconds to see if it's a fit for you.

"It took 5 minutes and just worked. Cheapest option that actually gets catch-alls right."— Brad Henderson
Get an API key
*No credit card needed. 100 checks free to start.