Skip to content

ActiveCampaign → AcelleMail Migration — Visual Walkthrough

Export contacts from ActiveCampaign, import into AcelleMail in 6 clicks. UI walkthrough plus optional API migration for large accounts.

Before you start

You'll need:

  • An ActiveCampaign account with contact-export permission (Admin role)
  • An AcelleMail installation up and running
  • ~45 minutes for <100k contacts + custom fields + tags

Export from ActiveCampaign

In ActiveCampaign's left sidebar, click ContactsManage Contacts. Top-right toolbar → Export.

The Export dialog asks for filters (all contacts vs. specific list/tag). Pick the scope you want. Format: CSV.

ActiveCampaign emails you the file when ready (usually <10 minutes for <100k contacts). The CSV includes: email, first name, last name, phone, all custom fields, tags (comma-separated), list memberships, account-level fields.

Import into AcelleMail (the same 6 clicks for every source)

Once you have the CSV exported from your previous platform, the import flow in AcelleMail is identical regardless of where the data came from.

1. Open your destination list

In AcelleMail's sidebar, click Audience → choose the list that will receive the migrated subscribers (or create a new one — New list button top-right).

Lists index

You'll see a per-list overview card with subscriber counts:

List overview

2. Click "Import" in the list toolbar

The wizard entrypoint is on the list detail page:

Import entry point

3. Upload your CSV

Drop the CSV file from the previous platform into the upload area:

Upload empty state

AcelleMail parses the file and confirms detection:

Upload success

4. Map the columns

The wizard auto-detects standard columns (email, first_name, last_name) and shows green Mapped to EMAIL chips. Adjust manually for any non-standard column from the source:

Map columns

5. Pick duplicate handling

In the same screen, choose what AcelleMail does when a subscriber already exists in this list:

  • Skip — keep the existing row, don't overwrite
  • Update — overwrite name/tags/custom fields with values from the CSV
  • Unsubscribe — mark existing rows as unsubscribed (rare; used when re-importing an opted-out list)

6. Run the import

Click Start import. The job runs in the background — close the popup, work elsewhere, return to Audience → [list] → Import to see progress:

Import history

You'll see PendingRunningComplete per import job, with rows-imported / rows-skipped / errors counts.

After the import

  • Verify list count matches your expected size (rows that failed validation appear in the Errors column with a downloadable error CSV).
  • Re-tag if needed — for behavioural data that doesn't fit a CSV column (e.g. "opened campaign X"), you may need to re-create the tag via segmentation rules.
  • Pause for warm-up — if the imported list is large (>10k) and your sending IP is new or recently rotated, run a short warm-up campaign to your most-engaged 10% before the full send. See IP warm-up best practices for the schedule.

Rebuilding ActiveCampaign automations

ActiveCampaign's automations map to AcelleMail's Automations. Equivalent triggers:

ActiveCampaign trigger AcelleMail trigger
Subscribes to list Subscribed to list
Tag added Tag added
Custom field changes Field value change
Opens/clicks email Link clicked
Date-based field Date relative
Site/event tracking Custom event (API)
Goal achieved (rebuild as workflow exit)

ActiveCampaign's "conditional content" inside emails (different blocks per segment) maps to AcelleMail's tag-driven email variants — set up separate campaigns per tag, OR use Liquid-style conditionals in the email body referring to {{ subscriber.tags }}.

Merge-tag syntax differences

ActiveCampaign AcelleMail
%FIRSTNAME% {{ subscriber.first_name }}
%LASTNAME% {{ subscriber.last_name }}
%EMAIL% {{ subscriber.email }}
%UNSUBSCRIBELINK% {{ unsubscribe_url }}
%FORWARDLINK% {{ web_view_url }}
Advanced: API-driven migration with ActiveCampaign's contacts endpoint

For >250k contacts or scheduled sync:

Export from ActiveCampaign via API:

# AC API URL + token from Settings → Developer
curl -X GET "https://<account>.api-us1.com/api/3/contacts?limit=100&offset=0" \
  -H "Api-Token: <AC_API_TOKEN>" \
  -o ac-contacts.json

Paginate via offset; AC returns max 100 per page.

Import into AcelleMail:

ACELLE_TOKEN="..."
ACELLE_LIST_UID="..."

jq -c '.contacts[] | {email: .email, first_name: .firstName, last_name: .lastName}' ac-contacts.json \
  | while read sub; do
      curl -X POST "https://acellemail.com/api/v1/subscribers" \
        -H "Authorization: Bearer $ACELLE_TOKEN" \
        -d "{\"list_uid\":\"$ACELLE_LIST_UID\",\"subscriber\":$sub}"
    done

ActiveCampaign's "deals" / "accounts" CRM features don't have direct AcelleMail equivalents — for CRM-adjacent workflows you'd typically keep ActiveCampaign for CRM + use AcelleMail for marketing email, syncing tags via Zapier or webhook bridges.

Related articles

28 comments

19 comments

  1. Thuỳ
    tip for anyone planning this: do a dry-run of the import with a small test list first. We caught a CSV encoding issue (Excel saved BOM-prefixed UTF-8) that wouldve affected all 60k rows.
  2. Daniel
    Year 1 cost ended up matching this guide's estimate almost exactly. Year 2 was even better because the VPS upgrade we needed was a one-time $20/mo bump
    1. Admin
      Year 2 is where the math usually separates, and you've hit the reason: the VPS bump is a step, not a slope. ActiveCampaign reprices on contact count every year whether or not your sending changed, so the curve keeps climbing. Self-hosted, you pay once for headroom and then sit on it until you outgrow it again. The guide's cost table only models year 1 right now. I'll add a year-2 column with a note that the infra step usually lands once and then flattens. If you're willing to say roughly what list size and monthly volume the $20 bump covered, that would make the example concrete instead of hypothetical.
  3. Ravi
    If your Mailchimp account has automations triggered by tags, document them carefully BEFORE export — the audit log goes away when you cancel the account and youll need that reference during the rebuild. tbh
  4. Aditi
    Completed this migration in Q1. The list-cleanup step is even more important than this guide makes it. We had 40k subscribers, exported, found that 6k were already on Mailchimp's suppression list. Importing those would've torched our new sender reputation.
  5. Isabella
    I'd push back on the 'random recipient split' for the parallel period. If your campaigns are time-sensitive (flash sales etc), random splitting causes weird timing fragmentation. We split by audience segment instead — simpler ops
  6. Carlos
    Did this last year. Confirming: the cron + worker setup is 80% of the install pain. Once those are running, the rest is documentation-following
  7. Marcus
    Question on DNS migration step — when you say 'add new include alongside old', does that work with strict DMARC alignment or does mixing two SPF includes break the alignment check?
    1. Admin
      Mixing two includes doesn't break alignment. DMARC SPF alignment only looks at the domain in the Return-Path (envelope sender) and compares it to the From domain. It doesn't care how many includes your SPF record chains through, or which one produced the pass. The two things that actually bite you during a dual-run: 1. The 10 DNS lookup limit. Each include costs at least one, and ActiveCampaign's include expands into several. Add ours on top and you can tip over into permerror, which DMARC reads as a fail. Check with a lookup counter before you cut over, not after. 2. Return-Path domain. If your bounce domain is still on the old provider's shared subdomain while From is your own domain, SPF alignment fails regardless of the includes. You'd be relying on DKIM alignment to carry DMARC. That's fine, but only if the DKIM key for the new sending domain is already published and signing, which is the step people do last. So the ordering that works: publish DKIM first, verify signed mail passes with alignment, then add the SPF include, then remove the old one once traffic is off it.
  8. Emma
    How do you handle the Mailchimp-style merge tags in old templates? We have ~50 templates with *|FNAME|* and don't want to manually rewrite each
    1. Admin
      There's no automatic merge tag converter in the importer today, so those `*|FNAME|*` strings will come through as literal text if you just paste the HTML in. With 50 templates I wouldn't do it by hand. Export them, run a find/replace over the HTML for each tag you actually use (usually it's a short list, FNAME/LNAME/EMAIL and maybe two custom fields), then import. The target tag name has to match your custom field's actual tag in the list settings, not the ActiveCampaign or Mailchimp name, so check one list first and build your mapping off that. Do one template end to end and send yourself a test before you batch the other 49. A bulk rewrite step in the import is worth adding. If you send me your tag list I'll use it as the test case.
  9. Lucas
    what about subscribers who unsubscribed via mailchimp's preference center? does the suppression-list import capture those, or just outright unsubscribes?
    1. Admin
      Both, as long as they're in the export you feed us. The import doesn't distinguish how someone opted out, it reads the status column and marks anything unsubscribed as unsubscribed on our side. The catch is on the export side: a preference-center opt-out that only turned off one group but left the contact subscribed to others will still come across as subscribed, because that's what it is in the source. Group-level preferences don't survive the move, we only carry the list-level status. If you want those partial opt-outs suppressed too, easiest path is to export the group-specific unsubscribes separately and import that file as a suppression list before you send anything. Worth noting your question says Mailchimp but this article is the ActiveCampaign walkthrough. The behaviour is the same either way, though the export screens differ. Tell me which one you're on and I'll point you at the right steps.
  10. Anna
    the cost-comparison table is the only honest one I've seen. Most 'AcelleMail vs X' content underestimates the ops cost of self-hosting.
  11. Yuki
    Genuinely useful. The 'common pitfalls' section especially — that's where most migration guides hand-wave.
    1. Admin
      That section exists because we hit every one of them ourselves. Automations are the worst, there's no export path, so anything mid-sequence just stops where it is.
  12. James
    We migrated 90k subscribers last March. The parallel period suggestion (10-25-50-75) saved us — the AcelleMail side hit a deliverability dip on day 3 we wouldnt have caught at 100% cutover.
  13. Sarah
    The 8-week timeline is reasonable for marketing-only migrations. If you have transactional email integrated (order confirmations, password resets), add 4-6 more weeks for the API rewiring. That part is underestimated everywhere...
  14. Brian
    Reading this 2 weeks into our Mailchimp migration. The 8-week timeline is conservative but accurate — we tried to compress to 4 weeks and got bitten by exactly the DNS warmup mistake you describe.
  15. Minh
    Bookmarked. We're evaluating a move next quarter and this is the most operationally-realistic guide I've found.
    1. Admin
      One thing worth planning for if the move is next quarter: the contact and list export is the mechanical part, and it goes fast. What eats the calendar is rebuilding automation logic, because ActiveCampaign's conditional branches don't come across in any export format, so someone has to sit down and re-express them. Budget for that separately rather than folding it into "import week". If you hit anything in the walkthrough that doesn't match what you see in your account, tell us which step and we'll fix the article. ActiveCampaign moves its UI around and screenshots rot faster than the prose does.
  16. Rafael
    Does this guide assume self-hosted Acelle or does it work with the hosted offering too?
    1. Admin
      Both. The import steps are the same either way, since it's all done through the customer UI (lists, CSV import, field mapping) and none of that changes between self-hosted and hosted. The one place they diverge is sending servers. On self-hosted you set those up yourself, so the walkthrough shows that screen. On hosted, sending is already configured and you can skip that section. If you're on hosted and something in the screenshots doesn't match what you see, tell me which step and I'll add a note to the article.
  17. Linh
    Adding: dont forget to migrate your webhook integrations too. We forgot ours and Shopify-cart-recovery silently stopped working for 3 weeks before anyone noticed.
  18. Priya
    Pro tip: keep the Mailchimp account at the free tier for 90 days post-cutover, not 30. We had a partner system still calling the Mailchimp API and we wouldn't have known if we'd canceled at 30
    1. Admin
      90 days is the right call, and the same reasoning applies to ActiveCampaign since this walkthrough is the AC one (the free tier equivalent there is the cheapest paid seat, so it costs a bit to sit on it). The integrations nobody remembers are almost always the ones that break: partner systems, an old Zapier zap, a form on a landing page someone built in 2019. Before you cut over, pull the API logs on the old account and see what's actually still hitting it, that's usually faster than trying to remember. I'll add a "keep the old account alive for 90 days and watch its API logs" step to the cutover section.
  19. Nadia
    For the IP warmup — is dedicated IP wrth it at 25k subscribers? Or stick with shared SES?
    1. Admin
      Shared SES at 25k. Dedicated only pays off around tens of thousands a week, otherwise the IP goes cold between sends.

More in Migration & Comparison