Email Validation Integration Guide: API, ESPs & No-Code (2026) | Email Wipes

Complete email validation integration guide for developers and marketers. REST API quickstart in Node.js, Python, PHP, webhook setup, Mailchimp, HubSpot, Klaviyo, ActiveCampaign, SendGrid, and Zapier workflows.

Email Validation Integration Guide: API, ESPs & No-Code (2026)

Published February 19, 2026  ·  12 min read  ·  Developer Guide

Email validation should be a background layer in your stack — invisible to users, automatic in operation, and feeding clean data everywhere it's needed. This guide walks you through integrating the Email Wipes API from zero to production: quickstart examples in the three most common server-side languages, webhook configuration, native integrations with five major ESPs, a Zapier workflow for no-code teams, and production-grade error handling and rate limiting patterns.

For the full API reference, see the API documentation. For a faster path to your first API call, see the API quick start guide.

API Overview & Authentication

The Email Wipes API is a REST API that accepts JSON and returns JSON. All requests are made over HTTPS. Authentication uses a Bearer token passed in the Authorization header.

Base URL: https://api.emails-wipes.com/v1

Key endpoints:

  • POST /verify — single email verification (synchronous, <300ms)
  • POST /bulk — batch verification (async, returns a job ID)
  • GET /bulk/{jobId} — poll job status and retrieve results
  • GET /account — check credit balance and account details

A verification response includes these fields:

FieldTypeDescription
emailstringThe verified email address
statusstringvalid, invalid, risky, unknown
sub_statusstringReason code: mailbox_not_found, disposable, catch_all, role_based, etc.
is_disposablebooleanDisposable/temporary address detection
is_role_basedbooleanRole-based address detection
mx_foundbooleanValid MX record present
smtp_checkbooleanMailbox-level SMTP verification passed
scorefloat0.0–1.0 deliverability confidence score

REST API Quickstart

Node.js

javascript
// npm install node-fetch (or use built-in fetch in Node 18+)
const API_KEY = process.env.EMAILWIPES_API_KEY;

async function verifyEmail(email) {
  const response = await fetch('https://api.emails-wipes.com/v1/verify', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ email })
  });

  if (!response.ok) {
    const err = await response.json();
    throw new Error(`API error ${response.status}: ${err.message}`);
  }

  return response.json();
}

// Usage
const result = await verifyEmail('[email protected]');
console.log(result.status);     // "valid"
console.log(result.score);      // 0.98
console.log(result.sub_status); // null

// Block invalid and risky emails at signup
if (result.status === 'invalid' || result.is_disposable) {
  throw new Error('Please enter a valid business email address.');
}

Express.js Middleware Example

javascript
// Middleware: validate email before processing signup
async function validateEmailMiddleware(req, res, next) {
  const { email } = req.body;

  if (!email) return res.status(400).json({ error: 'Email is required' });

  try {
    const result = await verifyEmail(email);

    if (result.status === 'invalid') {
      return res.status(422).json({
        error: 'Invalid email address',
        field: 'email'
      });
    }

    if (result.is_disposable) {
      return res.status(422).json({
        error: 'Disposable email addresses are not allowed',
        field: 'email'
      });
    }

    // Attach result to request for downstream use
    req.emailValidation = result;
    next();
  } catch (err) {
    // On API error, allow through (fail open) — log for review
    console.error('Email validation failed:', err.message);
    next();
  }
}

// Apply to signup route
app.post('/signup', validateEmailMiddleware, signupHandler);

Python

python
import os
import requests

API_KEY = os.environ["EMAILWIPES_API_KEY"]
BASE_URL = "https://api.emails-wipes.com/v1"

def verify_email(email: str) -> dict:
    """Verify a single email address. Returns validation result dict."""
    response = requests.post(
        f"{BASE_URL}/verify",
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json"
        },
        json={"email": email},
        timeout=10  # Always set a timeout in production
    )
    response.raise_for_status()
    return response.json()

def is_safe_to_send(email: str) -> bool:
    """Returns True if the email is valid and safe to send to."""
    try:
        result = verify_email(email)
        return (
            result["status"] == "valid"
            and not result["is_disposable"]
            and not result["is_role_based"]
            and result["score"] > 0.7
        )
    except requests.RequestException as e:
        print(f"Validation API error: {e}")
        return True  # Fail open — don't block signups on API outage

# Django / Flask form validation example
from django.core.exceptions import ValidationError

def validate_email_field(value):
    result = verify_email(value)
    if result["status"] == "invalid":
        raise ValidationError("This email address appears to be invalid.")
    if result["is_disposable"]:
        raise ValidationError("Please use a permanent email address.")

PHP

php
<?php
class EmailWipesClient {
    private string $apiKey;
    private string $baseUrl = 'https://api.emails-wipes.com/v1';

    public function __construct(string $apiKey) {
        $this->apiKey = $apiKey;
    }

    public function verify(string $email): array {
        $ch = curl_init("{$this->baseUrl}/verify");

        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => json_encode(['email' => $email]),
            CURLOPT_TIMEOUT        => 10,
            CURLOPT_HTTPHEADER     => [
                'Authorization: Bearer ' . $this->apiKey,
                'Content-Type: application/json',
                'Accept: application/json'
            ]
        ]);

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

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

        return json_decode($response, true);
    }

    public function isSafeToSend(string $email): bool {
        try {
            $result = $this->verify($email);
            return $result['status'] === 'valid'
                && !$result['is_disposable']
                && $result['score'] > 0.7;
        } catch (RuntimeException $e) {
            error_log("Email validation error: " . $e->getMessage());
            return true; // Fail open on API errors
        }
    }
}

// Usage
$client = new EmailWipesClient($_ENV['EMAILWIPES_API_KEY']);
$result = $client->verify('[email protected]');

if ($result['status'] === 'invalid') {
    // Return validation error to form
    $errors['email'] = 'Please enter a valid email address.';
}

Webhook Setup

Webhooks are ideal for async bulk validation jobs and for triggering downstream actions (CRM updates, suppression list updates, re-engagement queues) without polling. Configure your webhook endpoint in the API dashboard.

When a bulk job completes, Email Wipes sends a POST request to your endpoint with this payload:

json
{
  "event": "bulk_job.completed",
  "job_id": "job_abc123",
  "total": 15000,
  "valid": 12480,
  "invalid": 1830,
  "risky": 690,
  "download_url": "https://api.emails-wipes.com/v1/bulk/job_abc123/results",
  "created_at": "2026-02-19T14:32:00Z",
  "completed_at": "2026-02-19T14:34:12Z"
}

Verify webhook authenticity using the X-EmailWipes-Signature header (HMAC-SHA256 of the raw request body using your webhook secret):

javascript
import crypto from 'crypto';

function verifyWebhookSignature(rawBody, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

// Express webhook handler
app.post('/webhooks/emailwipes', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = req.headers['x-emailwipes-signature'];

  if (!verifyWebhookSignature(req.body, sig, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }

  const event = JSON.parse(req.body);

  if (event.event === 'bulk_job.completed') {
    // Trigger your downstream processing
    processValidationResults(event.job_id, event.download_url);
  }

  res.sendStatus(200); // Acknowledge immediately
});
Best practice: Always acknowledge webhooks with a 200 immediately, then process asynchronously. If processing takes more than a few seconds, push to a queue (SQS, BullMQ, etc.) and return 200 before the work starts.

ESP Integrations

Mailchimp

Use the Mailchimp Merge Tag approach: add a hidden EMAIL_SCORE field to your signup form, populate it via the Email Wipes API before form submission (via a small client-side call or a server-side form processor), then use Mailchimp segments to exclude contacts with low scores. For bulk cleaning: export your Mailchimp audience as CSV → run through the bulk verifier → re-import with an EMAILWIPES_STATUS tag → create a segment where that tag = "invalid" → archive the segment. Never delete — archive for compliance.

HubSpot

HubSpot's native forms don't support real-time external validation, but you can work around this via HubSpot Workflows + the Email Wipes API. Trigger: "Contact is created." Action: call the Email Wipes /verify endpoint via a webhook action in HubSpot. Then use a property setter action to write the result to a custom contact property (Email Validation Status). Use this property in active lists to suppress invalid contacts from enrollment in nurture sequences.

ActiveCampaign

ActiveCampaign supports webhook actions in automations. Build an automation: trigger = "Contact subscribes to list" → action = "Webhook" → POST to your Email Wipes proxy endpoint → your server calls the API and writes back the status via the ActiveCampaign contacts API. Alternatively, use the ActiveCampaign contact.add webhook in reverse: receive the contact data, validate externally, and update the contact record with a custom field before they enter any campaign automation.

Klaviyo

The cleanest Klaviyo integration uses Klaviyo's flow trigger webhook. When a profile is added to a list, Klaviyo can trigger a flow that POSTs to your endpoint. Validate the email, then call the Klaviyo API to suppress invalid profiles (PUT /v2/list/{list_id}/suppress). For bulk cleaning of existing Klaviyo lists, see our dedicated Klaviyo list cleaning guide.

SendGrid

SendGrid's Event Webhook (bounces, spam reports) should feed directly into your Email Wipes suppression workflow. Set up a relay: SendGrid bounce event → your endpoint → add to Email Wipes bulk suppression list → sync back to SendGrid suppression group. For real-time validation, add a server-side call to /verify in your SendGrid contact ingestion pipeline before calling PUT /v3/marketing/contacts.

Zapier No-Code Workflow

For teams without dedicated engineering resources, Zapier provides a no-code path to real-time email validation in your lead capture stack:

  1. Trigger: "New row in Google Sheets" (or Typeform, Gravity Forms, Webflow form — any lead source that Zapier supports)
  2. Action 1 — Webhooks by Zapier: POST to https://api.emails-wipes.com/v1/verify with the email address from step 1. Set the Authorization header to Bearer YOUR_API_KEY.
  3. Filter: "Continue if" — status equals "valid" AND is_disposable equals "false"
  4. Action 2 — Mailchimp / HubSpot / ActiveCampaign: Add the validated contact to your ESP list, passing the validation score as a custom field.
  5. Action 3 (optional) — Google Sheets: Update the original row with the validation status for your records.

This workflow validates every new lead at the moment of collection, ensures only valid addresses enter your ESP, and costs a fraction of a cent per lead in API credits. The Zapier free plan handles up to 100 tasks per month; paid plans scale to millions.

Error Handling Best Practices

The Email Wipes API uses standard HTTP status codes. Here's how to handle each category correctly:

Status CodeMeaningRecommended Action
200 OKSuccessful verificationProcess the result normally
400 Bad RequestMalformed request or invalid inputFix request format; log for debugging
401 UnauthorizedMissing or invalid API keyCheck key; rotate if compromised
402 Payment RequiredCredit balance exhaustedAlert on-call; top up credits; fail open temporarily
422 UnprocessableEmail syntax invalid (pre-SMTP)Return validation error to user immediately
429 Too Many RequestsRate limit exceededImplement exponential backoff (see below)
5xx Server ErrorAPI service issueRetry with backoff; fail open after 3 attempts

Fail open vs. fail closed: For signup forms, the default best practice is to fail open on API errors — allow the email through rather than blocking a potentially valid user because of a transient API issue. Log every failure for later batch re-verification. For high-risk contexts (preventing fraud, pre-send list cleaning), consider fail closed with a user-facing message: "We're having trouble verifying your email right now. Please try again in a moment."

javascript
// Exponential backoff with jitter
async function verifyWithRetry(email, maxRetries = 3) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      return await verifyEmail(email);
    } catch (err) {
      const isRetryable = err.status === 429 || err.status >= 500;

      if (!isRetryable || attempt === maxRetries) {
        // Fail open: log and return a "pass" result
        console.error(`Validation failed after ${attempt} retries:`, err);
        return { status: 'unknown', score: 0.5, _failedOpen: true };
      }

      // Exponential backoff: 100ms, 200ms, 400ms + random jitter
      const delay = Math.pow(2, attempt) * 100 + Math.random() * 50;
      await new Promise(r => setTimeout(r, delay));
    }
  }
}

Rate Limiting Guide

Email Wipes API rate limits vary by plan. The standard limits are:

PlanSingle VerifyBulk JobsConcurrent Bulk
Free100/min1,000/job1
Starter300/min100,000/job3
Growth1,000/min1,000,000/job10
EnterpriseCustomUnlimitedCustom

For high-throughput integrations, use bulk verification instead of individual /verify calls whenever possible. Batching 10,000 emails into a single bulk job is always more efficient than 10,000 individual API calls — both for rate limit management and for cost.

For real-time signup validation at scale (>500 signups/minute), consider a local caching layer: cache validation results for 24 hours by email address. Most email domains don't change SMTP configuration within a 24-hour window, and caching eliminates redundant API calls for repeat submissions.

Production tip: Monitor your X-RateLimit-Remaining response header. When it drops below 10% of your limit, trigger a backpressure mechanism — queue requests and process them with a slight delay rather than hitting 429 errors.

For complete endpoint documentation, request/response schemas, and SDK downloads in Go, Ruby, and Java, visit the full API documentation or follow the API quick start guide to make your first call in under 2 minutes.

Start Integrating in Minutes

Get your free API key and 100 free verifications. No credit card required.

Get Your Free API Key →