← Back to Blog

How to Verify Email Addresses with an API — Developer Guide

Sending emails to invalid addresses is expensive. Not in a vague, hand-wavy way — it directly damages your sender reputation, increases bounce rates, and can get your domain blacklisted by major email providers. If your bounce rate exceeds 2%, Gmail and Outlook start routing your emails to spam. Above 5%, you're looking at deliverability issues that take weeks to recover from.

Email verification solves this by checking whether an address is valid and deliverable before you send anything. This guide shows you how to integrate email verification into your application using an API.

What Email Verification Actually Checks

A proper verification goes through multiple layers:

  1. Syntax validation — Is the format valid? Does it conform to RFC 5321? This catches typos like user@gmailcom or user@@gmail.com.

  2. DNS MX record lookup — Does the domain have mail servers configured? If example.xyz has no MX records, no email is getting delivered there.

  3. SMTP handshake — Connect to the mail server, start a conversation, and ask "does this mailbox exist?" — all without actually sending an email. This is the most valuable check and the one most developers skip when building their own validation.

  4. Disposable email detection — Is this a throwaway address from services like Guerrilla Mail, Temp Mail, or Mailinator? These addresses work for 10 minutes and then disappear.

  5. Role-based detection — Addresses like admin@, info@, support@ are shared inboxes. They're valid but often have higher bounce rates and lower engagement.

  6. Catch-all detection — Some mail servers accept all addresses regardless of whether the mailbox exists. A catch-all server will say "yes" to anything@domain.com, making individual mailbox verification impossible.

Building all of this yourself means maintaining disposable domain lists, handling SMTP timeouts and greylisting, dealing with rate limiting from mail servers, and keeping up with constantly changing email infrastructure. Using an API handles all of that.

Getting Started with MailProbe

1. Create an Account

Sign up at mailprobe.dev/login. You get 100 free credits on signup — no credit card required. Each verification costs 1 credit.

2. Get Your API Key

After signing in, your API key is displayed on the dashboard. It looks like mp_live_xxxxxxxxxxxxxxxxxxxx. Keep it secure — this key authenticates all your API requests.

3. Make Your First Request

Verify a single email:

curl -X POST https://mailprobe.dev/api/v1/verify \
  -H "Authorization: Bearer mp_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"emails": ["user@example.com"]}'

The response:

[
  {
    "email": "user@example.com",
    "status": "deliverable",
    "score": 95,
    "syntax_valid": true,
    "mx_found": true,
    "smtp_check": true,
    "disposable": false,
    "role_based": false,
    "catch_all": false,
    "free_provider": false
  }
]

Every field is useful. status gives you the verdict. score gives you a confidence number (0–100). The individual boolean fields let you build custom rules.

API Reference

Verify Emails

Endpoint: POST /api/v1/verify

Headers:

  • Authorization: Bearer YOUR_API_KEY
  • Content-Type: application/json

Body:

{
  "emails": ["user@example.com", "another@domain.com"]
}

You can send up to 500 emails per request. Each email costs 1 credit.

Response: An array of verification results, one per email, in the same order as the input.

Check Credits

Endpoint: GET /api/v1/credits

Headers:

  • Authorization: Bearer YOUR_API_KEY

Response:

{
  "credits": 847
}

Understanding the Response

The status Field

  • deliverable — The email exists and can receive messages. Safe to send.
  • undeliverable — The mailbox doesn't exist or the domain has no mail servers. Do not send.
  • risky — The email might work, but there's uncertainty. Common with catch-all servers or temporary issues.
  • unknown — Verification couldn't determine the status. The mail server might be down or blocking checks.

The score Field

A number from 0 to 100 representing confidence in deliverability:

  • 90–100: High confidence, safe to send
  • 70–89: Likely valid, but some uncertainty
  • 50–69: Risky — consider whether to include
  • 0–49: Likely invalid, skip it

Boolean Flags

Flag What it means
syntax_valid Email format is valid
mx_found Domain has MX records
smtp_check SMTP handshake confirmed the mailbox
disposable Known throwaway email provider
role_based Generic address (admin@, info@, etc.)
catch_all Server accepts all addresses
free_provider Gmail, Yahoo, Outlook, etc.

Integration Patterns

Registration Form Validation

Verify emails when users sign up. Reject invalid ones before they enter your database:

# Check during registration
curl -X POST https://mailprobe.dev/api/v1/verify \
  -H "Authorization: Bearer mp_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"emails": ["newuser@signup.com"]}'

If the status is undeliverable, reject the registration with a "please enter a valid email" message. If it's risky, let it through but flag it for monitoring.

Bulk List Cleaning

Before sending a marketing campaign, verify your entire list:

# Verify up to 500 emails at once
curl -X POST https://mailprobe.dev/api/v1/verify \
  -H "Authorization: Bearer mp_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"emails": ["email1@a.com", "email2@b.com", "email3@c.com"]}'

Filter out anything with a status of undeliverable. Depending on your risk tolerance, also remove risky addresses — especially if you're sending from a new domain or one with a low sender reputation.

Webhook / Background Processing

For large lists, don't verify synchronously during a user request. Queue the emails and verify in batches:

// Node.js example — batch processing
const BATCH_SIZE = 500;

async function verifyList(emails) {
  const results = [];
  for (let i = 0; i < emails.length; i += BATCH_SIZE) {
    const batch = emails.slice(i, i + BATCH_SIZE);
    const res = await fetch('https://mailprobe.dev/api/v1/verify', {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer mp_live_YOUR_API_KEY',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ emails: batch }),
    });
    const data = await res.json();
    results.push(...data);
  }
  return results;
}

Handling Edge Cases

Catch-All Servers

When catch_all is true, the mail server accepts everything. You can't know for sure if the specific mailbox exists. In practice, most addresses on catch-all domains are valid (they're usually corporate domains with configured mail servers). Treat them as risky rather than automatically rejecting.

Temporary Failures

If the status is unknown, it usually means the mail server was temporarily unreachable. Retry after a few minutes. Don't retry more than twice — if it fails consistently, the server might be blocking verification attempts.

Rate Limiting

The API allows 60 requests per minute. Each request can contain up to 500 emails, so you can verify up to 30,000 emails per minute. If you hit the rate limit, you'll get a 429 response — back off and retry.

Disposable Emails in Registration

If disposable is true, the user signed up with a throwaway address. Whether to block this depends on your product. For free trials, you might want to block it. For a newsletter signup, it probably doesn't matter.

Pricing

MailProbe uses a simple credit-based model:

Plan Price Credits Cost per check
Free $0 100 on signup
Starter $5 1,000 $0.005
Pro $20 10,000 $0.002

No subscriptions. Buy credits when you need them. Credits don't expire. Sign up free and start with 100 credits — enough to test the API thoroughly and verify a small list.

Quick Decision Framework

Use this to decide what to do with each verification result:

  • deliverable + score ≥ 90 → Send confidently
  • deliverable + score 70–89 → Send, but monitor bounces
  • risky or catch_all → Include in campaigns with caution; exclude from cold outreach
  • undeliverable → Remove immediately
  • unknown → Retry once; if still unknown, treat as risky
  • disposable: true → Block on registration; irrelevant for list cleaning (they'll bounce anyway)
  • role_based: true → Don't block, but expect lower engagement

Next Steps

  1. Create your free account — 100 credits, no card required
  2. Grab your API key from the dashboard
  3. Make your first verification call
  4. Read the full API documentation for all available options

The entire integration takes about 15 minutes. Most of that is deciding what to do with each status — the API part is a single HTTP request.

Ready to verify your email list?

Start verifying emails with a simple API call. 100 free credits included.

Get Started Free →