Sign Up Free

Email Verification API Integration Guide

An email verification API lets you validate email addresses programmatically — checking syntax, domain, MX records, and mailbox existence in real time. This guide covers everything you need to integrate email verification into your application: authentication, endpoints, code examples, error handling, and best practices.

Why Integrate an Email Verification API

Collecting email addresses is easy. Collecting valid email addresses is hard. Signup forms, checkout flows, and lead generation pages all accept whatever users type, and a significant percentage of those inputs are invalid. Typos, fake addresses, disposable emails, and abandoned mailboxes all look like real addresses to your application but will bounce when you try to send to them.

An email verification API solves this by checking each address in real time before it enters your system. The API performs checks that client-side regex validation cannot: DNS resolution, MX record lookup, SMTP mailbox verification, disposable email detection, and risk scoring. The result is a clean, verified address that you can trust.

The business impact is direct. Verified email lists have bounce rates under 0.5% compared to 5-15% for unverified lists. Lower bounce rates mean better sender reputation, higher inbox placement, and more revenue from email campaigns. For applications that depend on email delivery — password resets, order confirmations, two-factor authentication — verification prevents critical failures.

How Email Verification APIs Work

When you submit an email address to a verification API, it performs a series of checks in sequence. Each check adds confidence to the final result.

Step 1: Syntax Validation

The API checks whether the address follows RFC 5322 formatting rules. This catches missing @ symbols, invalid characters, consecutive dots, and length violations. This is the same check you can do with regex, but the API applies it as a first filter.

Step 2: Domain and DNS Check

The API resolves the domain's DNS records to confirm it exists and is configured for email. It checks for A records, MX records, and whether the domain is currently reachable. Domains that do not exist or have no DNS records are immediately flagged as invalid.

Step 3: MX Record Lookup

The API queries the domain's MX (Mail Exchange) records to identify the mail servers responsible for receiving email. A domain without MX records (and without an A record fallback) cannot receive email. The API also identifies the email provider (Gmail, Outlook, custom) based on the MX records. Learn more about MX records in our MX record lookup guide.

Step 4: SMTP Verification

The API connects to the mail server and initiates an SMTP handshake. It issues a MAIL FROM command followed by a RCPT TO command with the target address. The server's response reveals whether the specific mailbox exists. This is the most definitive check but can be limited by servers that accept all addresses (catch-all domains).

Step 5: Additional Checks

The API runs supplementary checks including disposable email detection (checking against 150,000+ known temporary email domains), role-based address detection (info@, admin@, support@), catch-all domain detection, spam trap identification, and risk scoring based on historical data.

Integrating the Email Verification API

Authentication

Most email verification APIs authenticate requests using an API key passed as a header or query parameter. Keep your API key secure — never expose it in client-side code. All verification requests should be made from your server.

// API key should be stored in environment variables
// NEVER expose in client-side JavaScript
const API_KEY = process.env.EMAIL_VERIFIER_API_KEY;

Single Email Verification — Node.js

// Verify a single email address — Node.js
const https = require('https');

async function verifyEmail(email) {
  const url = `https://api.emailverifier.com/v2/verify?email=${encodeURIComponent(email)}`;

  const response = await fetch(url, {
    method: 'GET',
    headers: {
      'Authorization': `Bearer ${process.env.EMAIL_VERIFIER_API_KEY}`,
      'Content-Type': 'application/json',
    },
  });

  if (!response.ok) {
    throw new Error(`API error: ${response.status} ${response.statusText}`);
  }

  return response.json();
}

// Usage
try {
  const result = await verifyEmail('user@example.com');
  console.log('Status:', result.status);       // valid, invalid, risky, unknown
  console.log('Score:', result.score);          // 0-100 confidence score
  console.log('Disposable:', result.disposable); // true/false
  console.log('MX Found:', result.mx_found);    // true/false

  if (result.status === 'valid') {
    // Safe to send email
  } else if (result.status === 'risky') {
    // Proceed with caution or request confirmation
  } else {
    // Do not send — address is invalid
  }
} catch (error) {
  console.error('Verification failed:', error.message);
}

Single Email Verification — PHP

// Verify a single email address — PHP
function verifyEmail(string $email): array {
    $apiKey = getenv('EMAIL_VERIFIER_API_KEY');
    $url = 'https://api.emailverifier.com/v2/verify?email=' . urlencode($email);

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => [
            "Authorization: Bearer $apiKey",
            'Content-Type: application/json',
        ],
        CURLOPT_TIMEOUT => 30,
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode !== 200) {
        throw new RuntimeException("API error: HTTP $httpCode");
    }

    return json_decode($response, true);
}

// Usage
try {
    $result = verifyEmail('user@example.com');

    if ($result['status'] === 'valid') {
        echo "Email is valid and deliverable\n";
    } elseif ($result['status'] === 'risky') {
        echo "Email is risky — catch-all or unverifiable domain\n";
    } else {
        echo "Email is invalid — do not send\n";
    }
} catch (RuntimeException $e) {
    echo "Error: " . $e->getMessage() . "\n";
}

Single Email Verification — Python

// Verify a single email address — Python
import os
import requests

def verify_email(email: str) -> dict:
    api_key = os.environ['EMAIL_VERIFIER_API_KEY']
    url = 'https://api.emailverifier.com/v2/verify'

    response = requests.get(
        url,
        params={'email': email},
        headers={
            'Authorization': f'Bearer {api_key}',
            'Content-Type': 'application/json',
        },
        timeout=30,
    )
    response.raise_for_status()
    return response.json()

# Usage
result = verify_email('user@example.com')
print(f"Status: {result['status']}")
print(f"Score: {result['score']}")
print(f"Disposable: {result['disposable']}")

Batch Email Verification

For verifying multiple addresses at once, use the batch endpoint. This is more efficient than making individual API calls for each address because it processes them in parallel on the server.

// Batch email verification — Node.js
async function verifyBatch(emails) {
  const url = 'https://api.emailverifier.com/v2/verify/batch';

  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.EMAIL_VERIFIER_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ emails }),
  });

  if (!response.ok) {
    throw new Error(`Batch API error: ${response.status}`);
  }

  return response.json();
}

// Usage — verify up to 100 emails per batch
const emails = [
  'valid@example.com',
  'invalid@nonexistent.com',
  'user@tempmail.com',
];

const results = await verifyBatch(emails);
results.forEach((result) => {
  console.log(`${result.email}: ${result.status} (score: ${result.score})`);
});

For very large lists (thousands or millions of addresses), use the bulk file upload approach instead of batch API calls. Bulk verification processes the entire file asynchronously and notifies you when results are ready.

Error Handling and Edge Cases

Robust API integration requires handling errors gracefully. Here are the common scenarios and how to handle each one.

Rate Limiting

APIs enforce rate limits to prevent abuse. When you exceed the limit, the API returns a 429 status code. Implement exponential backoff to handle this:

// Retry with exponential backoff
async function verifyWithRetry(email, maxRetries = 3) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      const result = await verifyEmail(email);
      return result;
    } catch (error) {
      if (error.message.includes('429') && attempt < maxRetries) {
        const delay = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s
        console.log(`Rate limited. Retrying in ${delay}ms...`);
        await new Promise((resolve) => setTimeout(resolve, delay));
        continue;
      }
      throw error;
    }
  }
}

Timeout Handling

SMTP verification can take several seconds for slow mail servers. Set appropriate timeouts and handle them gracefully:

// Timeout handling with AbortController
async function verifyWithTimeout(email, timeoutMs = 15000) {
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), timeoutMs);

  try {
    const response = await fetch(
      `https://api.emailverifier.com/v2/verify?email=${encodeURIComponent(email)}`,
      {
        headers: { 'Authorization': `Bearer ${process.env.EMAIL_VERIFIER_API_KEY}` },
        signal: controller.signal,
      }
    );
    clearTimeout(timeout);
    return response.json();
  } catch (error) {
    clearTimeout(timeout);
    if (error.name === 'AbortError') {
      return { email, status: 'unknown', reason: 'Verification timed out' };
    }
    throw error;
  }
}

Handling Unknown Results

Not every verification produces a definitive result. Catch-all domains, greylisting servers, and temporarily unavailable mail servers can return unknown or inconclusive results. Design your application to handle this:

// Decision logic based on verification result
function handleVerificationResult(result) {
  switch (result.status) {
    case 'valid':
      return { accept: true, message: 'Email verified successfully' };

    case 'invalid':
      return { accept: false, message: 'This email address is invalid' };

    case 'risky':
      // Accept but flag for monitoring
      return { accept: true, flag: true, message: 'Email accepted (unverifiable domain)' };

    case 'disposable':
      return { accept: false, message: 'Disposable email addresses are not allowed' };

    case 'unknown':
      // Accept but schedule re-verification
      return { accept: true, reverify: true, message: 'Email accepted pending verification' };

    default:
      return { accept: true, reverify: true, message: 'Verification inconclusive' };
  }
}

API Integration Best Practices

Verify at the Point of Entry

The most effective time to verify an email is when the user enters it — during signup, checkout, or form submission. Real-time verification catches invalid addresses before they enter your database, preventing downstream issues like failed password resets and bounced order confirmations.

Cache Verification Results

If the same email is submitted multiple times (e.g., repeated login attempts), cache the verification result for 24-48 hours to avoid redundant API calls. Email validity can change, so do not cache indefinitely.

// Simple in-memory cache (use Redis in production)
const verificationCache = new Map();
const CACHE_TTL = 24 * 60 * 60 * 1000; // 24 hours

async function verifyWithCache(email) {
  const cached = verificationCache.get(email);
  if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
    return cached.result;
  }

  const result = await verifyEmail(email);
  verificationCache.set(email, { result, timestamp: Date.now() });
  return result;
}

Never Verify Client-Side

API keys must never be exposed in client-side code. Always make verification requests from your server. Use client-side regex for instant format validation, then verify server-side via the API before accepting the address.

Handle API Downtime Gracefully

No API has 100% uptime. When the verification API is unavailable, your application should degrade gracefully — accept the email with regex validation only and queue it for verification when the API recovers. Never block user signups because a third-party API is down.

Monitor Your Usage

Track your API call volume, error rates, and average response times. Set up alerts for unusual patterns like sudden spikes in invalid results (possible bot attack) or increased timeouts (possible mail server issues). Most API dashboards provide these metrics.

Webhook Integration for Async Results

For bulk verification and asynchronous processing, webhooks deliver results to your server when verification completes. This is more efficient than polling the API for status updates.

// Express webhook endpoint for verification results
app.post('/webhooks/email-verification', (req, res) => {
  const signature = req.headers['x-webhook-signature'];

  // Verify webhook signature to prevent tampering
  if (!verifyWebhookSignature(signature, req.body)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  const { event, data } = req.body;

  switch (event) {
    case 'verification.completed':
      // Single email verification result
      updateUserEmailStatus(data.email, data.status);
      break;

    case 'batch.completed':
      // Batch verification results ready for download
      downloadAndProcessResults(data.batch_id, data.download_url);
      break;

    case 'batch.failed':
      // Handle batch processing failure
      logBatchError(data.batch_id, data.error);
      break;
  }

  res.status(200).json({ received: true });
});

Security Considerations

Email verification APIs handle sensitive data. Follow these security practices to protect your users and your API access.

  • Store API keys in environment variables — never hardcode them in source code or commit them to version control
  • Use HTTPS exclusively — all API requests must use TLS encryption
  • Validate webhook signatures — verify that incoming webhooks are genuinely from the API provider
  • Rate limit your own endpoints — prevent attackers from using your verification endpoint to enumerate valid email addresses
  • Log verification results without storing full email addresses — hash or truncate addresses in logs for privacy compliance
  • Comply with GDPR and privacy regulations — ensure your verification provider processes data in compliance with applicable laws

Choosing the Right Email Verification API

When evaluating email verification APIs, consider these factors:

  • Accuracy: Look for providers that achieve 99%+ accuracy with multi-step verification (syntax, DNS, MX, SMTP, disposable detection)
  • Speed: Single verification should return in under 3 seconds. Bulk processing should handle millions of addresses within hours
  • Reliability: Look for 99.9%+ uptime SLAs and redundant infrastructure
  • Pricing: Compare per-verification costs across providers. Volume discounts matter at scale
  • Documentation: Clear, comprehensive API docs with code examples save integration time
  • Support: Responsive technical support helps resolve integration issues quickly

Our email verification API offers all of these with a generous free tier. Try the free email verifier to test accuracy before integrating.

Frequently Asked Questions

A comprehensive email verification API performs syntax validation, DNS resolution, MX record lookup, SMTP mailbox verification, disposable email detection, role-based address detection, catch-all domain detection, spam trap identification, and risk scoring. These checks go far beyond what regex can do and confirm whether an address can actually receive email.

Single email verification typically returns in 1-3 seconds. The majority of that time is spent on the SMTP handshake with the recipient mail server. Batch verification of 100 emails typically completes in 10-30 seconds. Bulk file processing of 100,000 emails takes 30-90 minutes as the system processes addresses in parallel.

Always verify server-side. API keys must never be exposed in client-side code. Use client-side regex for instant format validation as the user types, then make the API verification call from your server when the form is submitted. This gives users immediate feedback while keeping your API key secure.

An unknown result means the verification system could not determine the status, typically because the mail server was temporarily unreachable or used greylisting. Accept the email but schedule it for re-verification in 24-48 hours. Many unknown results resolve to valid or invalid on retry. Do not reject users based on an unknown result.

Implement exponential backoff — when you receive a 429 status code, wait 1 second and retry, then 2 seconds, then 4 seconds. Most APIs return rate limit headers telling you the limit and when it resets. For high-volume needs, use batch or bulk endpoints instead of individual API calls, as they are designed for volume processing.

Your application should degrade gracefully. Accept the email with regex validation only, store it, and queue it for API verification when the service recovers. Never block user signups or checkout because a third-party API is unavailable. Design your system to function with verification as an enhancement, not a hard dependency.

Start Verifying Emails with Our API

Integrate real-time email verification into your application in minutes. Free tier available with full API access, SDKs, and webhooks.