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

9 comentarios

7 comentarios

  1. tranminh.devop…
    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.
    1. admin (editado)
      Useful context. The fact that it took 3 weeks end-to-end is realistic; we sometimes get pushed to say 1-week timelines and theyre not honest
  2. ahmed.hassan.c…
    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. anyway
  3. d.cohen.tlv
    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.
  4. cw.dev.sh
    the cost-comparison table is the only honest one i've seen. most 'acellemail vs x' content underestimates the ops cost of self-hosting.
  5. sobrien.kw
    Does this guide assume self-hosted Acelle or does it work with the hosted offering too?
    1. admin
      short answer: yes — set the mysql session variable from your worker's .env on boot and you'll get the longer timeout per connection. we'll add an explicit recipe in the next refresh...
  6. jmorrison.itop…
    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 yo describe.
  7. danrey.dev
    Did this last year. Confirming: the cron + worker setup is 80% of the install pain. Once those are running, the rest is documentation-following.

More in Migration & Comparison