EmailVerify LogoEmailVerify

Mailchimp

Email checker for Mailchimp. Clean your email list before sending campaigns.

Keep your Mailchimp lists clean, improve deliverability, and reduce costs by verifying subscriber emails with EmailVerify.

Why Verify Mailchimp Lists?

ProblemImpactSolution
Invalid emailsHigh bounce ratesVerify before sending
Disposable emailsLow engagementFilter during signup
Stale listsDamaged reputationPeriodic cleaning
Spam trapsBlacklisting riskIdentify risky addresses

Integration Methods

MethodUse CaseAutomation
API IntegrationReal-time verificationFull
ZapierNo-code automationFull
Export/ImportBulk list cleaningManual
WebhookNew subscriber verificationFull

The easiest way to verify Mailchimp subscribers automatically.

New Subscriber Verification

Trigger: Mailchimp → New Subscriber

Action: EmailVerify → Verify Email

Filter: Based on verification result

Action: Mailchimp → Update subscriber / Unsubscribe

Setup Steps:

  1. Create a new Zap in Zapier
  2. Trigger: Mailchimp - New Subscriber
  3. Action: Webhooks - POST to https://api.emailverify.ai/v1/verify
  4. Filter: Only continue if status = "valid"
  5. Action: Mailchimp - Update Subscriber with tags

Configuration:

Webhook Settings:
  URL: https://api.emailverify.ai/v1/verify
  Method: POST
  Headers:
    Authorization: Bearer YOUR_API_KEY
    Content-Type: application/json
  Body: {"email": "{{email}}"}

Tag Subscribers by Quality

Add tags based on verification results:

If status = "valid" AND disposable = false
  → Add tag: "verified"

If disposable = true
  → Add tag: "disposable"
  → Update: Marketing permissions = false

If status = "invalid"
  → Unsubscribe member
  → Add tag: "invalid_email"

Method 2: Direct API Integration

For custom applications, integrate directly with both APIs.

Node.js Example

const mailchimp = require('@mailchimp/mailchimp_marketing');
const { EmailVerify } = require('@emailverify/node');

// Initialize clients
mailchimp.setConfig({
  apiKey: process.env.MAILCHIMP_API_KEY,
  server: 'us1', // Your server prefix
});

const emailVerify = new EmailVerify({
  apiKey: process.env.EMAILVERIFY_API_KEY,
});

// Verify a subscriber
async function verifySubscriber(listId, email) {
  // Get verification result
  const result = await emailVerify.verify(email);

  // Get subscriber hash (MD5 of lowercase email)
  const subscriberHash = crypto
    .createHash('md5')
    .update(email.toLowerCase())
    .digest('hex');

  // Update subscriber based on result
  if (result.status === 'invalid') {
    // Unsubscribe invalid emails
    await mailchimp.lists.updateListMember(listId, subscriberHash, {
      status: 'unsubscribed',
    });

    // Add tag
    await mailchimp.lists.updateListMemberTags(listId, subscriberHash, {
      tags: [{ name: 'invalid_email', status: 'active' }],
    });
  } else if (result.status === 'valid') {
    // Tag as verified
    const tags = [{ name: 'verified', status: 'active' }];

    if (result.result.disposable) {
      tags.push({ name: 'disposable', status: 'active' });
    }

    await mailchimp.lists.updateListMemberTags(listId, subscriberHash, { tags });
  }

  return result;
}

Python Example

import mailchimp_marketing as mailchimp
from emailverify import Client as EmailVerify
import hashlib
import os

# Initialize clients
mailchimp_client = mailchimp.Client()
mailchimp_client.set_config({
    "api_key": os.environ["MAILCHIMP_API_KEY"],
    "server": "us1"
})

bv_client = EmailVerify(api_key=os.environ["EMAILVERIFY_API_KEY"])

def verify_subscriber(list_id: str, email: str):
    # Verify email
    result = bv_client.verify(email)

    # Get subscriber hash
    subscriber_hash = hashlib.md5(email.lower().encode()).hexdigest()

    if result.status == "invalid":
        # Unsubscribe invalid emails
        mailchimp_client.lists.update_list_member(
            list_id,
            subscriber_hash,
            {"status": "unsubscribed"}
        )

        # Add tag
        mailchimp_client.lists.update_list_member_tags(
            list_id,
            subscriber_hash,
            {"tags": [{"name": "invalid_email", "status": "active"}]}
        )

    elif result.status == "valid":
        tags = [{"name": "verified", "status": "active"}]

        if result.result.disposable:
            tags.append({"name": "disposable", "status": "active"})

        mailchimp_client.lists.update_list_member_tags(
            list_id,
            subscriber_hash,
            {"tags": tags}
        )

    return result


# Bulk verify entire list
def clean_list(list_id: str):
    # Get all subscribers
    members = mailchimp_client.lists.get_list_members_info(
        list_id,
        count=1000,
        status="subscribed"
    )

    results = {"valid": 0, "invalid": 0, "unknown": 0}

    for member in members["members"]:
        result = verify_subscriber(list_id, member["email_address"])
        results[result.status] = results.get(result.status, 0) + 1

    return results

Method 3: Bulk List Cleaning

For large lists, export and use EmailVerify's bulk verification.

Step 1: Export from Mailchimp

  1. Go to AudienceAll contacts
  2. Click Export Audience
  3. Download the CSV file

Step 2: Verify with EmailVerify

Using the Dashboard:

  1. Log in to EmailVerify
  2. Go to Bulk Verification
  3. Upload your CSV file
  4. Wait for processing
  5. Download results

Using the API:

const fs = require('fs');
const { EmailVerify } = require('@emailverify/node');

const client = new EmailVerify({
  apiKey: process.env.EMAILVERIFY_API_KEY,
});

async function cleanMailchimpExport(csvPath) {
  // Read CSV and extract emails
  const csv = fs.readFileSync(csvPath, 'utf-8');
  const lines = csv.split('\n');
  const emails = lines
    .slice(1) // Skip header
    .map((line) => line.split(',')[0]) // First column is email
    .filter((email) => email);

  // Submit bulk job
  const job = await client.verifyBulk(emails);
  console.log(`Job ID: ${job.job_id}`);

  // Wait for completion (poll or use webhook)
  let status;
  do {
    await new Promise((r) => setTimeout(r, 10000)); // Wait 10s
    status = await client.getBulkJobStatus(job.job_id);
    console.log(`Progress: ${status.progress_percent}%`);
  } while (status.status !== 'completed');

  // Get results
  const results = await client.getBulkJobResults(job.job_id);

  // Separate by status
  const valid = results.results.filter((r) => r.status === 'valid');
  const invalid = results.results.filter((r) => r.status === 'invalid');

  console.log(`Valid: ${valid.length}, Invalid: ${invalid.length}`);

  return { valid, invalid };
}

Step 3: Import Results Back

Create a CSV for Mailchimp import:

function createMailchimpImportCSV(verificationResults) {
  const header = 'Email Address,Tags\n';

  const validRows = verificationResults.valid
    .map((r) => {
      const tags = ['verified'];
      if (r.result.disposable) tags.push('disposable');
      return `${r.email},"${tags.join(',')}"`;
    })
    .join('\n');

  const invalidRows = verificationResults.invalid
    .map((r) => `${r.email},"invalid_email,unsubscribe"`)
    .join('\n');

  return header + validRows + '\n' + invalidRows;
}

Import Steps:

  1. Go to AudienceImport contacts
  2. Upload the CSV
  3. Map fields: Email Address and Tags
  4. Choose Update existing contacts
  5. Complete import

Webhook Integration

Receive notifications when verification completes:

Set Up Webhook in EmailVerify

// Create webhook
const webhook = await client.webhooks.create({
  url: 'https://your-server.com/api/emailverify-webhook',
  events: ['verification.completed'],
  secret: 'your-webhook-secret',
});

Handle Webhook

// Express.js endpoint
app.post('/api/emailverify-webhook', express.json(), async (req, res) => {
  const { event, data } = req.body;

  if (event === 'verification.completed') {
    const { email, status, result } = data;

    // Update Mailchimp subscriber
    await updateMailchimpSubscriber(email, status, result);
  }

  res.status(200).send('OK');
});

async function updateMailchimpSubscriber(email, status, result) {
  const subscriberHash = crypto
    .createHash('md5')
    .update(email.toLowerCase())
    .digest('hex');

  const tags = [];

  if (status === 'valid') {
    tags.push({ name: 'verified', status: 'active' });
  } else if (status === 'invalid') {
    tags.push({ name: 'invalid_email', status: 'active' });
  }

  if (result.disposable) {
    tags.push({ name: 'disposable', status: 'active' });
  }

  await mailchimp.lists.updateListMemberTags(
    process.env.MAILCHIMP_LIST_ID,
    subscriberHash,
    { tags }
  );
}

Best Practices

1. Verify Before Adding

Verify emails before adding to Mailchimp:

async function addSubscriber(listId, email, firstName, lastName) {
  // Verify first
  const verification = await emailVerify.verify(email);

  if (verification.status === 'invalid') {
    throw new Error('Invalid email address');
  }

  if (verification.result.disposable) {
    throw new Error('Disposable emails not allowed');
  }

  // Add to Mailchimp
  await mailchimp.lists.addListMember(listId, {
    email_address: email,
    status: 'subscribed',
    merge_fields: {
      FNAME: firstName,
      LNAME: lastName,
    },
    tags: ['verified'],
  });
}

2. Clean Lists Regularly

Schedule monthly list cleaning:

// Cron job example (monthly)
const cron = require('node-cron');

cron.schedule('0 0 1 * *', async () => {
  console.log('Starting monthly list cleaning...');

  const lists = await mailchimp.lists.getAllLists();

  for (const list of lists.lists) {
    await cleanList(list.id);
  }

  console.log('List cleaning complete');
});

3. Segment by Email Quality

Create segments for targeting:

High Quality Segment:

{
  "name": "High Quality Subscribers",
  "conditions": {
    "match": "all",
    "conditions": [
      {
        "field": "tag",
        "op": "contains",
        "value": "verified"
      },
      {
        "field": "tag",
        "op": "notcontain",
        "value": "disposable"
      }
    ]
  }
}

4. Use Tags Effectively

Implement a tagging strategy:

TagMeaningAction
verifiedEmail is validInclude in campaigns
disposableTemporary emailLimit sending
invalid_emailEmail bouncedExclude from campaigns
role_basedinfo@, support@Consider excluding
needs_reverifyLast verified >90 daysRe-verify

5. Monitor Metrics

Track these metrics after implementing:

  • Bounce rate: Should decrease significantly
  • Open rate: Should improve
  • Deliverability score: Should increase
  • List growth quality: Track verified vs unverified signups

Cost Savings Calculator

Estimate your savings from list cleaning:

MetricBefore CleaningAfter Cleaning
List Size100,00085,000
Invalid Emails15%Less than 1%
Bounce Rate8%Less than 2%
Monthly ESP Cost$250$212
Annual Savings-$456

Smaller, cleaner lists often have higher engagement rates, improving your sender reputation and deliverability.

Troubleshooting

High Bounce Rates After Cleaning

  • Verify the cleaning process completed successfully
  • Check for recently added unverified subscribers
  • Re-verify emails showing as valid but bouncing

Tags Not Applying

  • Verify API permissions include tag management
  • Check subscriber status (archived members can't be tagged)
  • Ensure tag names don't exceed character limits

Rate Limiting

Both Mailchimp and EmailVerify have rate limits:

ServiceLimit
Mailchimp Marketing API10 requests/second
EmailVerifyBased on plan

Implement delays for bulk operations:

async function processWithDelay(items, processFn, delayMs = 100) {
  for (const item of items) {
    await processFn(item);
    await new Promise((r) => setTimeout(r, delayMs));
  }
}

On this page