Customer.io → Mailchimp
Export Customer.io people to CSV, load unsubscribes into Mailchimp first, then import the people you still mail. Campaigns, events, and Liquid stay behind.
Should you make this move?
Both platforms have a case. Compare what you gain with what you give up before scheduling the cutover.
Customer.io
- People, attributes, and events drive campaigns without a separate list for every segment
- Audience, campaigns, automations, and reporting live in one publishing system
- Journeys, Liquid, and event history have to be rebuilt, and a CSV import can fire automations while it runs
- Automation logic, analytics history, and deliverability settings are not very portable
Mailchimp
- A broad small-business marketing suite combines email, contacts, forms, and campaigns
- Audience, campaigns, automations, and reporting live in one publishing system
- Pricing, interface complexity, and audience-based billing can become frustrating
- Automation logic, analytics history, and deliverability settings are not very portable
Mailchimp: A broad small-business marketing suite combines email, contacts, forms, and campaigns. This removes a major source-side concern: Journeys, Liquid, and event history have to be rebuilt, and a CSV import can fire automations while it runs.
What you lose: People, attributes, and events drive campaigns without a separate list for every segment. What you inherit: Pricing, interface complexity, and audience-based billing can become frustrating.
Jump to a section
Know the shape of the move.
This timeline assumes
- One Customer.io workspace and one Mailchimp audience. You are the owner or an admin on both.
- You filter the People page by conditions, not by the email-address filter. Customer.io only exports the condition filter.
- Mailchimp suppression is per audience. It does not cover every audience in the account.
- The suppression import cannot mark someone who is already subscribed in that audience as unsubscribed. Load opt-outs first.
- The site already has Customer.io → Klaviyo if you want profiles and events instead of a Mailchimp audience. No Mailchimp campaign sends until the seed check passes.
What survives the move.
“Partial” and “manual” are not footnotes. They are work that must be scheduled and verified.
| Item | Outcome | Impact | What happens | Mitigation |
|---|---|---|---|---|
| People and attributes | partial | critical | From the People page you can export all attributes, the displayed columns, or a chosen set. id, city, state, and created_at come along with displayed attributes. The file is a CSV of people, not their history. | Export the attributes you still segment on. Map them to Mailchimp merge fields. Drop the rest. |
| Global unsubscribe | partial | critical | Customer.io unsubscribed true covers email, SMS, WhatsApp, and push. Mailchimp's suppression import sets email marketing status to Unsubscribed for that one audience. | Filter People where unsubscribed is true and export that file. Import it as Unsubscribed before you import anyone else. |
| Subscription-center topics | lost | high | Topic preferences are not Mailchimp groups. A global unsubscribe already removes every topic. Someone subscribed to one topic and not another needs a decision. | If you mail more than one topic, make a Mailchimp group per topic from an export of those preferences. Do not flatten them into one subscribed flag without looking. |
| Campaigns and Liquid | lost | critical | Campaigns, broadcasts, and Liquid do not import into Mailchimp. You rebuild the next emails in Mailchimp's editor. | Rebuild the next two campaigns and the one journey you cannot pause. Archive the rest as screenshots. |
| Events and deliveries | lost | high | A people CSV is not event history. A single person's JSON export includes events, devices, relationships, and deliveries. That is one person at a time. | Export JSON only for accounts you must audit. Accept that Mailchimp segments cannot use old Customer.io events. |
| Segments | manual | high | You can export a segment's people list from the segment page. Membership is a timestamp column, not a Mailchimp segment. | Export each segment you still send to. Tag those rows on import, or save a Mailchimp segment from the tag. |
| Devices and push | lost | medium | Device export is a separate Customer.io option. Mailchimp email will not register those devices. | Keep push on Customer.io until you have another push tool. Do not expect the email move to cover it. |
| Duplicate emails | manual | high | Customer.io can hold more than one person with the same email when they have different ids. Mailchimp keeps one contact per email in an audience. | Export duplicate people from Customer.io first. Decide which id wins before the Mailchimp import. |
| Export lifetime | manual | medium | Customer.io emails you when the export is ready and deletes it from the workspace after 60 days. | Download it the day it arrives and store a copy with a checksum. |
| Already-subscribed Mailchimp contacts | manual | critical | Mailchimp's suppression import does not change someone who is already subscribed or cleaned. The article says to use bulk unsubscribe for that case. | Import the suppression file into an empty audience, or bulk-unsubscribe the overlap before you treat the audience as safe. |
| SMS consent | lost | medium | Customer.io's global flag covers SMS. This Mailchimp path sets email status. SMS consent is a separate Mailchimp state. | If you text from Mailchimp, treat SMS as its own import. Do not infer it from unsubscribed. |
Where each thing goes.
| Source | Destination | Method | Notes |
|---|---|---|---|
| Customer.io email | Mailchimp Email Address | automatic | One row per email after you resolve duplicate ids. |
| unsubscribed true | Email marketing status Unsubscribed | transform | Import this file first, with the status dropdown set to Unsubscribed. |
| unsubscribed false or absent | Subscribed contact | transform | Only rows you have consent to mail. |
| id | A merge field | manual | Mailchimp will not use it as the key. Email is the key. |
| Attributes you still segment on | Merge fields | transform | Choose attributes on export so the file stays small. |
| Segment membership | Tag or group | manual | Export the segment, then tag those emails on import. |
| Campaigns and Liquid | No destination | unsupported | Rebuild the messages you will send next. |
| Events and deliveries | No destination | unsupported | Per-person JSON is an archive, not a Mailchimp import. |
| Workspace suppressions | The same Unsubscribed import | manual | Export suppressions separately and include them before subscribers. |
Make the move recoverable.
Create the source-of-truth backup
Keep a full people export, an unsubscribe export, and a copy of live campaigns before Mailchimp can send.
- Export all people with the attributes you need. Download it before the 60-day deletion.
- Export the unsubscribed condition as its own CSV.
- Export duplicate people and note which email you will keep.
- Screenshot or export the campaigns that are live this month.
- Store checksums. Work on copies.
Proof to capture: Checksums, row counts for all people and for unsubscribed, and the campaign list.
Export two people files
Separate opt-outs from everyone else before Mailchimp sees them.
- Filter with conditions, unsubscribed equals true. Export the attributes you need.
- Export everyone else you have consent to mail as a second file.
- Download both from the export email or the Exports page.
- Resolve duplicate emails down to one row per address.
Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.
Load Mailchimp in the safe order
Use the suppression import while it can still set status.
- Start from an audience that does not already contain these people as subscribed.
- Import the unsubscribed CSV. Set email marketing status to Unsubscribed.
- Import the consented CSV as subscribed. Map email and the merge fields you kept.
- If someone was already subscribed, use Mailchimp's bulk unsubscribe. The suppression file will not change them.
Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.
The things most likely to hurt.
These are operating limits. Treat every “Stop if” condition as a blocked migration, not a suggestion.
Suppression import skips current subscribers
Mailchimp documents that a suppression import cannot mark an existing subscribed contact as unsubscribed.
- Consequence
- Opt-outs stay mailable.
- Mitigation
- Import opt-outs into a fresh audience first, or bulk-unsubscribe the overlap.
Stop if: Any sampled Customer.io opt-out is still subscribed in Mailchimp.
One email hides two people
Customer.io allows the same email on different ids. Mailchimp keeps one contact.
- Consequence
- You keep the wrong attributes and drop a second relationship.
- Mitigation
- Run the duplicate-people export and pick a winner first.
Stop if: Duplicate emails are still in the file you upload.
Both products send
Campaigns keep running in Customer.io until you stop them.
- Consequence
- The list gets two emails.
- Mitigation
- Stop Customer.io campaigns before the Mailchimp audience is allowed to send.
Stop if: A Customer.io campaign or broadcast is still scheduled.
Do the work in this order.
- Day 1 · export
Export people, opt-outs, and duplicates
2 hours active1 day elapsedCustomer.io export email waiting- Export unsubscribed people and the consented set.
- Export duplicates.
- List live campaigns.
Stop / go checkpointAre both CSVs complete?
Go when: Row counts match the People filters and the files are downloaded.
Stop when: The export expired or the condition filter was the email search.
- Day 2 · clean
One row per email
2 to 3 hours active1 day elapsedNone waiting- Pick a winning id when emails repeat.
- Map attributes to merge fields.
- Create the Mailchimp audience if you need an empty one.
Depends on: export
Stop / go checkpointIs the file safe to upload?
Go when: No duplicate emails remain, and opt-outs are in their own file.
Stop when: You cannot tell which duplicate to keep.
- Day 3 · import
Import opt-outs, then subscribers
2 hours active1 day elapsedMailchimp import notice waiting- Import unsubscribed with status Unsubscribed.
- Import consented contacts as subscribed.
- Sample both groups.
Depends on: clean
Stop / go checkpointDid consent survive?
Go when: Every sampled opt-out is unsubscribed and subscribed counts match.
Stop when: An opt-out is subscribed.
- Day 4 · rebuild
Rebuild the next campaign and seed it
3 hours active1 day elapsedNone waiting- Recreate the next email.
- Stop Customer.io sends.
- Seed-send from Mailchimp only.
Depends on: import
Stop / go checkpointCan Mailchimp own the next send?
Go when: The seed arrives once and Customer.io has nothing scheduled.
Stop when: Both products can still send.
- Day 5 · cutover
Send once and watch
1 hour active1 day elapsedThe send window waiting- Import the last-day delta.
- Send the Mailchimp campaign.
- Check bounces and unsubscribes the next morning.
Depends on: rebuild
Stop / go checkpointStay on Mailchimp?
Go when: One send completed and opt-out samples still hold.
Stop when: Complaints or a double send show up.
Cut over with a way back.
Cutover
Let Mailchimp send the next campaign without Customer.io sending too, and without mailing opt-outs.
- Stop Customer.io campaigns and broadcasts. Record the time.
- Export the unsubscribe filter again and import any new opt-outs first.
- Import new consented people.
- Confirm Mailchimp is the only scheduled send.
- Send, then check a sample of opt-outs again.
Proof to capture: Stop time, both import notices, and the single scheduled campaign.
Rollback
Return the next send to Customer.io if Mailchimp consent is wrong.
- Unschedule the Mailchimp campaign.
- Do not delete the Customer.io workspace.
- Turn the Customer.io campaign back on only after you know it will not replay the import.
- Export any Mailchimp unsubscribes that happened and set unsubscribed true in Customer.io.
- Name one sender before anyone leaves.
Proof to capture: Customer.io is the only scheduled sender and new Mailchimp opt-outs were written back.
- A Customer.io opt-out is subscribed in Mailchimp.
- Both products show a scheduled send.
- Duplicate emails were imported as the wrong person.
- The subscribed count is off and the gap is unexplained.
Prove the migration worked.
Every blocking check must pass. Capture the evidence before cleanup begins.
| Pass | ID | Check | Method | Expected result | Evidence |
|---|---|---|---|---|---|
EXP-01Blocking | People export matches the filter | Compare the CSV row count with the People page condition. | The counts match after you remove the header. | The export email and the row count. | |
UNS-01Blocking | Opt-outs are unsubscribed | Sample 20 unsubscribed emails in the Mailchimp audience. | Each shows email marketing status Unsubscribed. | The sample list. | |
SUB-01Blocking | Subscribed count | Compare the consented CSV with the Mailchimp subscribed total. | Counts match, or each gap is an invalid address you logged. | Both counts. | |
DUP-01Blocking | Duplicate emails | Search the upload file for repeated emails. | No email appears twice. | The duplicate check output. | |
SEG-01 | A live segment became a tag | Compare one exported segment count with the Mailchimp tag. | The counts match. | The segment export and the tag count. | |
CAM-01Blocking | Customer.io is stopped | Open campaigns and broadcasts. | Nothing is scheduled or running. | Screenshots of both lists. | |
SEED-01Blocking | Seed message | Send the Mailchimp campaign to seed addresses only. | One message each. Unsubscribe works. Customer.io sent nothing. | Seed headers. | |
SMS-01 | SMS was not inferred | If the audience has SMS, compare consent with the email file. | SMS status was set on purpose, or SMS is off. | A note of the decision. |
Remove the scaffolding safely.
Safe after: One Mailchimp campaign, a day of delivery checks, and opt-out samples that still hold.
- Store the Customer.io CSVs outside the workspace before the 60-day deletion.
- Leave Customer.io campaigns stopped.
- Remove workspace users who only exported data.
- Keep the workspace readable until the retention date you wrote down.
- Update the next review date.
Verify against the primary material.
Platform behavior changes. Check these sources and the review dates above before executing a production migration.
- Customer.io: export people dataAccessed 2026-11-06
- Customer.io: global unsubscribesAccessed 2026-11-06
- Mailchimp: import a suppression listAccessed 2026-11-06
- Mailchimp: view or export contactsAccessed 2026-11-06