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 Audience → Lists & Segments → choose the list to export. On the list page, Manage List → Export 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).

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

2. Click "Import" in the list toolbar#
The wizard entrypoint is on the list detail page:

3. Upload your CSV#
Drop the CSV file from the previous platform into the upload area:

AcelleMail parses the file and confirms detection:

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:

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:

You'll see Pending → Running → Complete 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#