Email Verification Webhook Integration: Real-Time Notifications Guide

API calls are great until they're not. You send a verification request, wait for the response, hope nothing times out, and repeat this dance thousands of times. For high-volume applications, this request-response model becomes a bottleneck.

Webhooks solve this. Instead of your application constantly checking "is it done yet?", the verification service notifies you the instant verification completes. Your app does other things while waiting. Resources are freed up. Response times improve. Everything scales better.

Let me show you how to implement this properly.

What Are Webhooks and Why Use Them

A webhook is a reverse API call. Instead of you calling the API and waiting for a response, you give the API a URL endpoint on your server. When something happens (like verification completing), the API makes an HTTP POST request to your endpoint with the results.

Think of it like this: standard APIs are like making phone calls and staying on the line until the other person answers. Webhooks are like text messages - you send your request, go do other things, and get notified when there's a response.

📊
Key Stat: Applications using webhooks for verification can handle 10x more concurrent requests than those using synchronous API calls, because they're not blocking threads waiting for responses. This dramatically improves application performance and resource efficiency.

For email verification, webhooks are particularly valuable because verification times vary dramatically. A simple syntax check takes milliseconds. Full SMTP verification can take 1-30 seconds depending on the mail server. Some checks require retries due to greylisting, which means waiting minutes.

With webhooks, your application doesn't care. Send the verification request, provide your webhook URL, and move on. When verification completes, you get a POST request with the results.

Basic Webhook Implementation

Here's how to set up a webhook endpoint to receive verification results.

PHP Webhook Endpoint

PHP
<?php
// webhook-endpoint.php
// This receives POST requests from BulkEmailChecker

// Get the POST payload
$payload = file_get_contents('php://input');
$data = json_decode($payload, true);

// Verify webhook signature for security
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$secret = 'your_webhook_secret';
$expected = hash_hmac('sha256', $payload, $secret);

if(!hash_equals($expected, $signature)) {
    http_response_code(401);
    exit('Invalid signature');
}

// Process the verification result
$email = $data['email'];
$status = $data['status'];
$event = $data['event'];

if($status === 'passed') {
    // Email is valid
    update_user_email_status($email, 'verified');
} elseif($status === 'failed') {
    // Email is invalid
    update_user_email_status($email, 'invalid');
    log_reason($email, $event);
} else {
    // Status is unknown (catch-all, greylisting, etc)
    update_user_email_status($email, 'unknown');
}

// Always respond with 200 OK
http_response_code(200);
echo json_encode(['received' => true]);
?>

Python Webhook Endpoint

Python
from flask import Flask, request, jsonify
import hmac
import hashlib

app = Flask(__name__)
WEBHOOK_SECRET = 'your_webhook_secret'

@app.route('/webhook/verification', methods=['POST'])
def verification_webhook():
    # Get the payload
    payload = request.get_data()
    signature = request.headers.get('X-Webhook-Signature', '')
    
    # Verify signature
    expected = hmac.new(
        WEBHOOK_SECRET.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    
    if not hmac.compare_digest(expected, signature):
        return jsonify({'error': 'Invalid signature'}), 401
    
    # Parse the data
    data = request.get_json()
    email = data['email']
    status = data['status']
    
    # Process based on status
    if status == 'passed':
        update_email_status(email, 'verified')
    elif status == 'failed':
        update_email_status(email, 'invalid')
    else:
        update_email_status(email, 'unknown')
    
    return jsonify({'received': True}), 200

if __name__ == '__main__':
    app.run()

Node.js Webhook Endpoint

JavaScript
const express = require('express');
const crypto = require('crypto');
const app = express();

const WEBHOOK_SECRET = 'your_webhook_secret';

app.post('/webhook/verification', express.raw({type: 'application/json'}), (req, res) => {
    const signature = req.headers['x-webhook-signature'];
    const payload = req.body;
    
    // Verify signature
    const expected = crypto
        .createHmac('sha256', WEBHOOK_SECRET)
        .update(payload)
        .digest('hex');
    
    if(signature !== expected) {
        return res.status(401).json({error: 'Invalid signature'});
    }
    
    // Parse the payload
    const data = JSON.parse(payload.toString());
    const {email, status, event} = data;
    
    // Process the result
    if(status === 'passed') {
        updateEmailStatus(email, 'verified');
    } else if(status === 'failed') {
        updateEmailStatus(email, 'invalid');
    } else {
        updateEmailStatus(email, 'unknown');
    }
    
    res.status(200).json({received: true});
});

app.listen(3000);

Webhook Security Best Practices

Webhooks create a security consideration: anyone who knows your webhook URL can send fake requests to it. You need to verify that requests actually come from BulkEmailChecker.

⚠️
Warning: Never trust webhook data without signature verification. Attackers can easily forge POST requests to your endpoint. Always validate the webhook signature using HMAC-SHA256 before processing any data.

HMAC Signature Verification

BulkEmailChecker signs every webhook request with an HMAC-SHA256 signature. The signature is sent in the X-Webhook-Signature header. You verify it by computing the HMAC of the raw request body using your webhook secret.

This ensures the request came from BulkEmailChecker and hasn't been tampered with.

Additional Security Measures

Beyond signature verification, implement these security practices:

  • HTTPS only - Never use HTTP for webhooks. Always use HTTPS to encrypt data in transit.
  • IP whitelist - Restrict webhook endpoint to accept requests only from BulkEmailChecker's IP addresses.
  • Rate limiting - Implement rate limiting to prevent webhook flooding attacks.
  • Idempotency - Handle duplicate webhook deliveries gracefully by checking if you've already processed this verification.
💡
Pro Tip: Store your webhook secret in environment variables, never in your code. Use different secrets for development and production environments. Rotate secrets periodically for enhanced security.

Understanding Webhook Payloads

The webhook POST request includes the complete verification result in JSON format. Here's what you'll receive:

JSON
{
    "email": "user@example.com",
    "status": "passed",
    "event": "mailbox_exists",
    "details": "Mailbox exists and is accepting mail",
    "isDisposable": false,
    "isFreeService": true,
    "isRoleAccount": false,
    "domain": "example.com",
    "timestampUTC": "2026-02-05T14:30:00Z",
    "execution": "1.23",
    "webhookId": "wh_abc123def456"
}

Key fields explained:

  • status - Overall result: "passed", "failed", or "unknown"
  • event - Specific reason: "mailbox_exists", "mailbox_does_not_exist", "is_catchall", etc.
  • isDisposable - Boolean flag for temporary email addresses
  • isFreeService - Boolean flag for Gmail, Yahoo, etc.
  • isRoleAccount - Boolean flag for info@, sales@, etc.
  • webhookId - Unique ID for this webhook delivery (use for idempotency)

For complete field documentation, see the BulkEmailChecker API reference.

Webhook Retry and Failure Handling

Webhooks can fail. Your server might be temporarily down, experiencing high load, or having network issues. BulkEmailChecker automatically retries failed webhook deliveries.

Automatic Retry Schedule

If your endpoint doesn't respond with HTTP 200 within 10 seconds, the webhook is retried:

  • Attempt 1: Immediate
  • Attempt 2: After 1 minute
  • Attempt 3: After 5 minutes
  • Attempt 4: After 15 minutes
  • Attempt 5: After 1 hour

After 5 failed attempts, the webhook delivery is marked as failed and you'll need to manually retrieve the result.

Implementing Idempotent Webhook Handling

Because of retries, your endpoint might receive the same webhook multiple times. Handle this gracefully:

PHP
<?php
function handle_webhook_idempotent($data) {
    $webhook_id = $data['webhookId'];
    
    // Check if we've already processed this webhook
    if(webhook_already_processed($webhook_id)) {
        // Already handled - just return success
        return true;
    }
    
    // Process the webhook
    $email = $data['email'];
    $status = $data['status'];
    
    // Begin transaction
    db_begin_transaction();
    
    try {
        // Update email status
        update_email_status($email, $status);
        
        // Mark webhook as processed
        mark_webhook_processed($webhook_id);
        
        db_commit();
        return true;
    } catch(Exception $e) {
        db_rollback();
        throw $e;
    }
}
?>
Action Required: Always store the webhookId and check if you've processed it before. This prevents duplicate processing if the same webhook is delivered multiple times due to retries.

Testing Webhooks Locally

Testing webhooks during development is tricky because your local server isn't publicly accessible. Here are solutions:

Using ngrok for Local Testing

Ngrok creates a public URL that tunnels to your localhost:

Bash
# Start your local server on port 3000
php -S localhost:3000

# In another terminal, start ngrok
ngrok http 3000

# Use the ngrok URL as your webhook endpoint
# Example: https://abc123.ngrok.io/webhook/verification

Now you can configure this ngrok URL as your webhook endpoint and test locally.

Manual Webhook Testing

You can also manually trigger test webhooks using curl:

Bash
curl -X POST https://yourdomain.com/webhook/verification \
  -H "Content-Type: application/json" \
  -H "X-Webhook-Signature: test_signature" \
  -d '{
    "email": "test@example.com",
    "status": "passed",
    "event": "mailbox_exists",
    "webhookId": "test_wh_123"
  }'

Production Deployment Considerations

When deploying webhooks to production, keep these considerations in mind.

Webhook Endpoint Performance

Your webhook endpoint should respond quickly (under 1 second ideally). If processing takes longer:

  1. Immediately acknowledge receipt (return 200 OK)
  2. Queue the data for background processing
  3. Process asynchronously

Don't make your webhook endpoint do heavy work synchronously. The API will timeout and retry if you take too long to respond.

Scaling Webhook Handlers

For high-volume applications, use a queue-based architecture:

PHP
<?php
// Webhook endpoint - fast response
function webhook_endpoint() {
    $payload = file_get_contents('php://input');
    
    // Verify signature (fast)
    if(!verify_signature($payload)) {
        http_response_code(401);
        return;
    }
    
    // Push to queue (fast) - Redis, RabbitMQ, SQS, etc.
    queue_push('verification_webhooks', $payload);
    
    // Immediate response
    http_response_code(200);
    echo json_encode(['queued' => true]);
}

// Separate worker process handles the queue
function worker_process() {
    while(true) {
        $payload = queue_pop('verification_webhooks');
        if($payload) {
            process_verification_result($payload);
        }
        sleep(1);
    }
}
?>

Monitoring and Debugging Webhooks

Track these metrics to ensure your webhook integration is healthy:

  • Success rate - Percentage of webhooks that receive 200 OK on first attempt
  • Response time - How quickly your endpoint responds
  • Retry frequency - How often webhooks need to be retried
  • Processing lag - Time between webhook receipt and data processing completion

Webhook Logging

Log all webhook receipts for debugging:

PHP
<?php
function log_webhook($data, $success) {
    $log_entry = [
        'timestamp' => date('Y-m-d H:i:s'),
        'webhook_id' => $data['webhookId'],
        'email' => $data['email'],
        'status' => $data['status'],
        'success' => $success,
        'ip' => $_SERVER['REMOTE_ADDR']
    ];
    
    // Log to database or file
    file_put_contents(
        '/var/log/webhooks.log',
        json_encode($log_entry) . "\n",
        FILE_APPEND
    );
}
?>

Frequently Asked Questions

What happens if my webhook endpoint is down?

BulkEmailChecker will automatically retry the webhook delivery up to 5 times over the course of an hour. If all retries fail, you can manually retrieve the verification result using the API by querying the original request ID.

Can I use the same webhook URL for multiple verification requests?

Yes, absolutely. Your webhook endpoint should be designed to handle all verification results. Use the email address or a custom identifier in your original request to route the webhook data to the correct record in your system.

How do I test webhooks without exposing my development server?

Use ngrok or a similar tunneling service to create a temporary public URL that forwards to your localhost. Alternatively, deploy a staging environment with a public URL specifically for webhook testing.

Should I respond to the webhook before or after processing the data?

Respond immediately with 200 OK, then process the data asynchronously. This prevents timeouts and retries. Queue the webhook payload and process it in a background worker.

Conclusion

Webhooks transform email verification from a blocking operation into an efficient, scalable process. Your application submits verification requests without waiting for results, processes other tasks, and receives instant notifications when verification completes.

The key to successful webhook implementation is security (verify signatures), reliability (handle retries idempotently), and performance (respond quickly and process asynchronously).

Start by implementing a basic webhook endpoint with signature verification. Test it locally using ngrok. Deploy to production with queue-based processing for scale. Monitor success rates and response times to ensure reliability.

For complete webhook documentation and code examples, check the BulkEmailChecker API docs. Ready to get started? Try the free email verification tool to see verification in action, then integrate webhooks for production-scale applications with unlimited API pricing.

99.7% Accuracy Guarantee

Stop Bouncing. Start Converting.

Millions of emails verified daily. Industry-leading SMTP validation engine.