Skip to content

Klaviyo → AcelleMail Migration — Visual Walkthrough

Export your Klaviyo profiles as CSV, import into AcelleMail via the 6-click wizard. Visual walkthrough plus power-user API path for large Klaviyo accounts.

Before you start

You'll need:

  • A Klaviyo account with profile-export permission (Owner or Admin role)
  • An AcelleMail installation up and running
  • ~45 minutes for <100k profiles + tags + custom properties

Klaviyo's profile model is rich (event history, conditional segments, predictive metrics). The CSV migration preserves identity + custom properties; behavioural segments + flows are rebuilt manually in AcelleMail's visual builder.

Export from Klaviyo

In Klaviyo's left sidebar, click AudienceLists & Segments → choose the list to export. On the list page, Manage ListExport List to CSV.

Klaviyo asks which properties to include — select All (or trim down if you have hundreds of custom properties you don't need). The file prepares in the background; Downloads sidebar item shows the download link when ready (usually <5 minutes for <100k).

Exported CSV includes: email, all standard + custom profile properties, opt-in date, source, last activity timestamp.

For segment-based migration (e.g. only profiles matching "Engaged in last 30 days"), use Segments → [segment name] → Export Segment — same flow, scoped output.

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 Klaviyo flows in AcelleMail

Klaviyo's flows map to AcelleMail's Automations. Equivalent triggers:

Klaviyo trigger AcelleMail trigger
Subscribed to list Subscribed to list
Added to segment Tag added (via segment-to-tag mapping)
Metric event (Shopify, custom) Custom event (API)
Profile property change Field value change
Date property matches Date relative
Clicked email link Link clicked

For Klaviyo's predictive analytics + AI features (predicted CLV, churn risk), AcelleMail doesn't have direct equivalents — these are Klaviyo-specific advantages. If you depend on them, evaluate whether the cost savings of self-hosting justify rebuilding those signals via your own data pipeline.

Merge-tag syntax differences

Klaviyo AcelleMail
{{ first_name }} (root scope) {{ subscriber.first_name }}
{{ last_name }} {{ subscriber.last_name }}
{{ email }} {{ subscriber.email }}
{{ organization.web_view_url }} {{ web_view_url }}
{{ organization.unsubscribe_url }} {{ unsubscribe_url }}

Klaviyo's Jinja-style conditionals ({% if profile.tags contains 'vip' %}) work in AcelleMail's email builder with minor adjustments (use subscriber.tags instead of profile.tags).

Advanced: API-driven migration with Klaviyo's profile export endpoint

For >250k profiles or for ongoing sync from a CRM-of-record, Klaviyo's API supports bulk export.

Export from Klaviyo via API:

# Klaviyo Private API key from Settings → API Keys
curl -X GET "https://a.klaviyo.com/api/profiles/?page[size]=100&page[cursor]=" \
  -H "Authorization: Klaviyo-API-Key <KLAVIYO_PRIVATE_KEY>" \
  -H "revision: 2024-10-15" \
  -o klaviyo-profiles.json

Klaviyo paginates via cursor; loop until links.next is null.

Import into AcelleMail via REST API:

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

jq -c '.data[] | {email: .attributes.email, first_name: .attributes.first_name, last_name: .attributes.last_name}' klaviyo-profiles.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

For Klaviyo-specific behavioural data (events table, metric aggregates), you'll need to bridge via your own ETL — AcelleMail doesn't have direct event-stream ingestion. The path most teams take: keep the rich behavioural store in your data warehouse (Postgres / BigQuery / Snowflake), use AcelleMail's API to push tag/segment updates based on warehouse-computed signals.

Related articles

19 comments

13 comments

  1. Akira
    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 touch alignment. DMARC alignment on the SPF side only looks at whether the Return-Path domain matches your From domain, it doesn't care how many includes the SPF record has or which one produced the pass. So keeping Klaviyo's include next to ours during the cutover is safe under strict alignment, as long as each sender's Return-Path is already on a subdomain of your From domain (that's the part to check, not the includes). The real thing to watch with two includes is the 10 DNS lookup limit. Klaviyo's include plus ours plus whatever else you have (Google Workspace, a helpdesk, etc.) adds up fast, and blowing past 10 gives you a permerror, which under strict DMARC fails everything. Count them before you add, and drop the Klaviyo include once the last send is out. I'll add both points to the DNS step in the article, it currently glosses over the lookup budget.
  2. Brian
    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 would've affected all 60k rows.
    1. Admin
      The Excel BOM one is nasty because it only corrupts the first column header, so you end up with a field named something like "email" that doesn't map to anything, and every row after that looks fine. Easy to miss on a 60k import if you don't look at the mapping step closely. Dry-run with a small slice is the right call. I'll add a note to the walkthrough about exporting from Klaviyo straight to CSV rather than routing it through Excel, and what the BOM looks like when it shows up in the field mapper.
  3. Sofia
    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.
  4. Marcus
    What about subscribers who unsubscribed via Mailchimp's preference center? Does the suppression-list import capture those, or just outright unsubscribes? fwiw
    1. Admin
      Both end up in the suppression export, so they do come across, but they come across flattened. Whatever the source platform considers "do not email this person" lands in one list, and our importer marks all of them unsubscribed on the target list. What you lose is the reason and the granularity. If someone used a preference center to opt out of one topic and stay on another, that nuance isn't in the export and we have nowhere to put it anyway, since we don't model per-topic subscription preferences yet. The safe read is that a partial opt-out becomes a full unsubscribe. If that's too blunt for your setup, export the preference data separately before you migrate and split it into separate lists on our side, one per topic. Clunky, but it's what people do today. Granular preferences are on the list, no date on it. I'll add a note about this to the article, the current version doesn't call it out and it should.
  5. David
    Id 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
    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.
  7. Rafael
    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...
  8. Aisha
    Bookmarked. We're evaluating a move next quarter and this is the most operationally-realistic guide I've found...
    1. Admin
      Do the Klaviyo export early, suppression list and profile properties especially. Those are what people find missing after cutover. And budget time to rebuild flows, they don't map across.
  9. Lucas
    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 built-in converter for `*|FNAME|*` today, so nothing in the import step will rewrite them for you. With 50 templates the practical move is a find/replace pass over the HTML before you import, since the Mailchimp tag format is regular enough that one regex per tag name handles the whole set. Map each `*|X|*` to the matching custom field tag in your list, then import. Worth flagging that this walkthrough is Klaviyo-specific, and Klaviyo templates don't use that syntax, so I'm guessing your 50 are older Mailchimp exports that went through Klaviyo. If that's the case, tell me which tags you actually have in there and I'll confirm the field mapping rather than have you guess at it. A bulk tag-rewrite on import is a reasonable thing to add, it's just not there now.
  10. Quân
    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. Daniel
    Did this last year. Confirming: the cron + worker setup is 80% of the install pain. Once those are running, the rest is documentation-following
  12. Aditi
    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. :)
    1. Admin
      Day 3 is where it usually shows up. New sending IP, reputation still forming, and the ESPs that were quiet on day 1 start throttling once they've seen enough volume to form an opinion. At 100% cutover you find out from your open rate a week later, at 25% you find out while you still have Klaviyo carrying the other 75%. 90k in one move is on the larger end of what we see, so the staged split doing real work there is worth knowing. The walkthrough currently presents 10-25-50-75 as a suggestion in passing. I'll rewrite that section to make it the default path and call out the day 2-4 window as the one to actually watch bounce and deferral rates in, rather than just eyeballing the final numbers.
  13. Vera
    For the IP warmup — is dedicated IP worth it at 25k subscribers? Or stick with shared SES?

More in Migration & Comparison