EmailVerify LogoEmailVerify

ActiveCampaign

Email checker for ActiveCampaign. Verify contacts in your email marketing automation.

Integrate EmailVerify with ActiveCampaign to verify email addresses, clean your contact lists, and improve email deliverability.

Integration Methods

MethodBest ForComplexity
Webhook AutomationReal-time verificationLow
API IntegrationCustom workflowsMedium
Bulk ImportList cleaningLow

Method 1: Webhook Automation

Create an automation that verifies emails when contacts are added.

Create Webhook Action

  1. Go to AutomationsNew Automation
  2. Choose a trigger (e.g., "Subscribes to a list")
  3. Add action → Conditions and WorkflowWebhook
  4. Configure the webhook:
URL: https://api.emailverify.ai/v1/verify
Method: POST
Headers:
  Authorization: Bearer YOUR_API_KEY
  Content-Type: application/json
Body:
{
  "email": "%EMAIL%",
  "webhook_url": "https://yoursite.com/api/activecampaign/callback"
}

Create Callback Handler

Handle verification results from EmailVerify.

// pages/api/activecampaign/callback.js
import crypto from 'crypto';

export default async function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).json({ error: 'Method not allowed' });
  }

  const { email, status, result } = req.body;

  // Update contact in ActiveCampaign based on result
  const acApiUrl = process.env.ACTIVECAMPAIGN_API_URL;
  const acApiKey = process.env.ACTIVECAMPAIGN_API_KEY;

  try {
    // Find contact by email
    const searchResponse = await fetch(
      `${acApiUrl}/api/3/contacts?email=${encodeURIComponent(email)}`,
      {
        headers: {
          'Api-Token': acApiKey,
        },
      }
    );

    const searchData = await searchResponse.json();
    const contact = searchData.contacts[0];

    if (!contact) {
      return res.status(404).json({ error: 'Contact not found' });
    }

    // Update contact with verification status
    const fieldUpdates = {
      contact: {
        fieldValues: [
          {
            field: process.env.AC_FIELD_EMAIL_STATUS,
            value: status,
          },
          {
            field: process.env.AC_FIELD_EMAIL_SCORE,
            value: result.score?.toString() || '',
          },
        ],
      },
    };

    await fetch(`${acApiUrl}/api/3/contacts/${contact.id}`, {
      method: 'PUT',
      headers: {
        'Api-Token': acApiKey,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(fieldUpdates),
    });

    // Add tag based on status
    const tagName = status === 'valid' ? 'Email Verified' : 'Email Invalid';
    await addTagToContact(contact.id, tagName, acApiUrl, acApiKey);

    res.status(200).json({ success: true });
  } catch (error) {
    console.error('ActiveCampaign update error:', error);
    res.status(500).json({ error: 'Update failed' });
  }
}

async function addTagToContact(contactId, tagName, apiUrl, apiKey) {
  // First, find or create the tag
  const tagResponse = await fetch(
    `${apiUrl}/api/3/tags?search=${encodeURIComponent(tagName)}`,
    {
      headers: { 'Api-Token': apiKey },
    }
  );

  const tagData = await tagResponse.json();
  let tagId = tagData.tags[0]?.id;

  if (!tagId) {
    // Create tag if it doesn't exist
    const createResponse = await fetch(`${apiUrl}/api/3/tags`, {
      method: 'POST',
      headers: {
        'Api-Token': apiKey,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        tag: { tag: tagName, tagType: 'contact' },
      }),
    });
    const createData = await createResponse.json();
    tagId = createData.tag.id;
  }

  // Add tag to contact
  await fetch(`${apiUrl}/api/3/contactTags`, {
    method: 'POST',
    headers: {
      'Api-Token': apiKey,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      contactTag: { contact: contactId, tag: tagId },
    }),
  });
}

Method 2: API Integration

Build custom integrations using both APIs.

ActiveCampaign Service

// services/activecampaign.js
import EmailVerify from '@emailverify/sdk';

class ActiveCampaignService {
  constructor() {
    this.apiUrl = process.env.ACTIVECAMPAIGN_API_URL;
    this.apiKey = process.env.ACTIVECAMPAIGN_API_KEY;
    this.bv = new EmailVerify(process.env.EMAILVERIFY_API_KEY);
  }

  async verifyContact(contactId) {
    // Get contact details
    const contact = await this.getContact(contactId);

    if (!contact?.email) {
      throw new Error('Contact has no email');
    }

    // Verify email
    const result = await this.bv.verify({ email: contact.email });

    // Update contact with results
    await this.updateContactFields(contactId, {
      email_status: result.status,
      email_score: result.score,
      email_disposable: result.is_disposable ? 'Yes' : 'No',
      email_verified_at: new Date().toISOString(),
    });

    // Apply automation based on result
    if (result.status === 'invalid') {
      await this.addToAutomation(contactId, 'Invalid Email Cleanup');
    }

    return result;
  }

  async getContact(contactId) {
    const response = await fetch(
      `${this.apiUrl}/api/3/contacts/${contactId}`,
      {
        headers: { 'Api-Token': this.apiKey },
      }
    );
    const data = await response.json();
    return data.contact;
  }

  async updateContactFields(contactId, fields) {
    const fieldValues = await this.mapToFieldValues(fields);

    await fetch(`${this.apiUrl}/api/3/contacts/${contactId}`, {
      method: 'PUT',
      headers: {
        'Api-Token': this.apiKey,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        contact: { fieldValues },
      }),
    });
  }

  async mapToFieldValues(fields) {
    // Get custom field IDs
    const customFields = await this.getCustomFields();

    return Object.entries(fields).map(([key, value]) => ({
      field: customFields[key],
      value: String(value),
    }));
  }

  async getCustomFields() {
    const response = await fetch(`${this.apiUrl}/api/3/fields`, {
      headers: { 'Api-Token': this.apiKey },
    });
    const data = await response.json();

    return data.fields.reduce((acc, field) => {
      acc[field.perstag.toLowerCase()] = field.id;
      return acc;
    }, {});
  }

  async addToAutomation(contactId, automationName) {
    // Find automation by name
    const response = await fetch(
      `${this.apiUrl}/api/3/automations?search=${encodeURIComponent(automationName)}`,
      {
        headers: { 'Api-Token': this.apiKey },
      }
    );
    const data = await response.json();
    const automation = data.automations[0];

    if (automation) {
      await fetch(`${this.apiUrl}/api/3/contactAutomations`, {
        method: 'POST',
        headers: {
          'Api-Token': this.apiKey,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          contactAutomation: {
            contact: contactId,
            automation: automation.id,
          },
        }),
      });
    }
  }

  async verifyList(listId) {
    // Get all contacts in list
    const contacts = await this.getListContacts(listId);
    const emails = contacts.map(c => c.email);

    // Bulk verify
    const job = await this.bv.verifyBulk(emails);

    // Wait for completion
    let status;
    do {
      await new Promise(resolve => setTimeout(resolve, 5000));
      status = await this.bv.getBulkJobStatus(job.job_id);
    } while (status.status !== 'completed');

    // Get results and update contacts
    const results = await this.bv.getBulkJobResults(job.job_id);

    for (const result of results.results) {
      const contact = contacts.find(c => c.email === result.email);
      if (contact) {
        await this.updateContactFields(contact.id, {
          email_status: result.status,
          email_score: result.score,
        });
      }
    }

    return {
      total: results.results.length,
      valid: results.results.filter(r => r.status === 'valid').length,
      invalid: results.results.filter(r => r.status === 'invalid').length,
    };
  }

  async getListContacts(listId) {
    const contacts = [];
    let offset = 0;
    const limit = 100;

    while (true) {
      const response = await fetch(
        `${this.apiUrl}/api/3/contacts?listid=${listId}&limit=${limit}&offset=${offset}`,
        {
          headers: { 'Api-Token': this.apiKey },
        }
      );
      const data = await response.json();

      if (data.contacts.length === 0) break;

      contacts.push(...data.contacts);
      offset += limit;
    }

    return contacts;
  }
}

export default new ActiveCampaignService();

Usage Example

import activeCampaign from './services/activecampaign';

// Verify single contact
const result = await activeCampaign.verifyContact('12345');
console.log(`Email status: ${result.status}`);

// Verify entire list
const listResults = await activeCampaign.verifyList('1');
console.log(`Verified ${listResults.total} contacts`);
console.log(`Valid: ${listResults.valid}, Invalid: ${listResults.invalid}`);

Method 3: Form Integration

Verify emails on ActiveCampaign forms before submission.

Custom Form Handler

<!-- ActiveCampaign Form with EmailVerify -->
<form id="ac-form" action="https://yoursite.activehosted.com/proc.php" method="POST">
  <input type="hidden" name="u" value="1" />
  <input type="hidden" name="f" value="1" />
  <input type="hidden" name="s" />
  <input type="hidden" name="c" value="0" />
  <input type="hidden" name="m" value="0" />
  <input type="hidden" name="act" value="sub" />
  <input type="hidden" name="v" value="2" />

  <div class="form-group">
    <label for="email">Email Address</label>
    <input type="email" id="email" name="email" required />
    <span id="email-status"></span>
  </div>

  <div class="form-group">
    <label for="fullname">Full Name</label>
    <input type="text" id="fullname" name="fullname" />
  </div>

  <button type="submit" id="submit-btn">Subscribe</button>
</form>

<script>
const form = document.getElementById('ac-form');
const emailInput = document.getElementById('email');
const emailStatus = document.getElementById('email-status');
const submitBtn = document.getElementById('submit-btn');

let emailValid = false;

emailInput.addEventListener('blur', async function() {
  const email = this.value;
  if (!email) return;

  emailStatus.textContent = 'Verifying...';
  emailStatus.className = 'verifying';
  submitBtn.disabled = true;

  try {
    const response = await fetch('/api/verify-email', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email }),
    });

    const result = await response.json();

    if (result.status === 'valid') {
      emailStatus.textContent = '✓ Valid email';
      emailStatus.className = 'valid';
      emailValid = true;
    } else {
      emailStatus.textContent = '✗ Please enter a valid email';
      emailStatus.className = 'invalid';
      emailValid = false;
    }
  } catch (error) {
    // Allow submission on API error
    emailStatus.textContent = '';
    emailValid = true;
  }

  submitBtn.disabled = false;
});

form.addEventListener('submit', function(e) {
  if (!emailValid) {
    e.preventDefault();
    emailStatus.textContent = 'Please enter a valid email address';
    emailStatus.className = 'invalid';
  }
});
</script>

<style>
.form-group {
  margin-bottom: 1rem;
}

#email-status {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.875rem;
}

#email-status.verifying { color: #666; }
#email-status.valid { color: #28a745; }
#email-status.invalid { color: #dc3545; }

button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
</style>

Automation Workflows

Verification on Subscribe

Trigger: Contact subscribes to list

Action: Webhook to EmailVerify

Wait: Until webhook response

If/Else: Check email_status field
  ├─ If "valid": Continue to welcome email
  └─ If "invalid": Add to "Invalid Emails" list, End

Periodic List Cleaning

Trigger: Run once per month

Action: Webhook to start bulk verification

Wait: 24 hours (for bulk job completion)

Goal: Bulk verification complete

Action: Process results via webhook callback

Re-engagement Campaign

Trigger: Contact hasn't opened email in 90 days

Action: Verify email address

If/Else: Email status
  ├─ If "valid": Send re-engagement email
  └─ If "invalid": Unsubscribe contact

Custom Fields Setup

Create these custom fields in ActiveCampaign:

Field NameTypePersonalization Tag
Email StatusText%EMAIL_STATUS%
Email ScoreNumber%EMAIL_SCORE%
Email DisposableDropdown (Yes/No)%EMAIL_DISPOSABLE%
Email Verified AtDate%EMAIL_VERIFIED_AT%

Create Fields via API

async function createCustomFields(apiUrl, apiKey) {
  const fields = [
    { title: 'Email Status', type: 'text', perstag: 'EMAIL_STATUS' },
    { title: 'Email Score', type: 'text', perstag: 'EMAIL_SCORE' },
    { title: 'Email Disposable', type: 'dropdown', perstag: 'EMAIL_DISPOSABLE', options: ['Yes', 'No'] },
    { title: 'Email Verified At', type: 'date', perstag: 'EMAIL_VERIFIED_AT' },
  ];

  for (const field of fields) {
    await fetch(`${apiUrl}/api/3/fields`, {
      method: 'POST',
      headers: {
        'Api-Token': apiKey,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ field }),
    });
  }
}

Segmentation

Create segments based on email verification status.

Valid Emails Segment

Conditions:
- Contact field "Email Status" is "valid"
- Contact field "Email Score" is greater than 0.7

Invalid Emails Segment

Conditions:
- Contact field "Email Status" is "invalid"
OR
- Contact field "Email Status" is "unknown"

High-Risk Emails Segment

Conditions:
- Contact field "Email Disposable" is "Yes"
OR
- Contact field "Email Score" is less than 0.5

Best Practices

1. Verify Before Campaigns

Always verify your list before major campaigns:

async function preCampaignVerification(listId, campaignId) {
  const service = new ActiveCampaignService();

  // Verify list
  const results = await service.verifyList(listId);

  // Only proceed if invalid rate is acceptable
  const invalidRate = results.invalid / results.total;

  if (invalidRate > 0.05) { // More than 5% invalid
    console.warn(`High invalid rate: ${(invalidRate * 100).toFixed(1)}%`);
    console.warn('Consider cleaning list before sending');
    return false;
  }

  return true;
}

2. Handle Rate Limits

async function verifyWithRateLimit(contacts) {
  const batchSize = 100;
  const delayMs = 1000;

  for (let i = 0; i < contacts.length; i += batchSize) {
    const batch = contacts.slice(i, i + batchSize);

    await Promise.all(
      batch.map(contact => verifyContact(contact.id))
    );

    if (i + batchSize < contacts.length) {
      await new Promise(resolve => setTimeout(resolve, delayMs));
    }
  }
}

3. Error Handling

async function safeVerify(email) {
  try {
    const result = await bv.verify({ email });
    return result;
  } catch (error) {
    console.error(`Verification failed for ${email}:`, error);

    // Return unknown status to allow further processing
    return {
      email,
      status: 'unknown',
      error: error.message,
    };
  }
}

On this page