Migrate from Mailchimp

Moving from Mailchimp means exporting your audience with every status, importing it with the right subscription flags, rebuilding templates, and recreating automation flows. Mailchimp can keep sending until you are ready.

Updated · 8 min read

What moves, and what you rebuild

From MailchimpIn PlunkHow
Domain authenticationDomainNew DNS records, alongside Mailchimp’s
Audience (subscribed)ContactsCSV import
Unsubscribed, cleaned and non-subscribedUnsubscribed contactsCSV import with subscribed set to false
Tags and audience fieldsCustom fieldsCome along in the CSV
Custom-coded templatesTemplatesExport the HTML, rewrite merge tags
Drag-and-drop templatesTemplatesRebuild in Plunk’s editor
Automation flowsWorkflowsRebuild by hand; Mailchimp has no export
Mailchimp TransactionalPOST /v1/send or SMTPChange the request or the SMTP settings

1. Verify your domain in Plunk

Add your sending domain under Settings → Domains in Plunk. Plunk shows three CNAME records named <token>._domainkey, pointing to <token>.dkim.amazonses.com. Add them at your DNS provider and Plunk marks the domain verified once they resolve.

You do not need to remove anything first. Mailchimp authenticates with its own two CNAME records, and Mailchimp Transactional with mte1._domainkey and mte2._domainkey. Plunk’s DKIM selectors are different, so both sets of records can live side by side and Mailchimp keeps working while you move.

Plunk also offers an optional custom MAIL FROM domain: an MX and an SPF TXT record on a plunk. subdomain. It aligns bounces with your domain and is worth adding, but sending works without it.

2. Move your audience

In Mailchimp, open Audience, pick the audience and choose Export audience. You get a ZIP with a separate CSV for each status. That split is the useful part, because each file maps to one subscription state in Plunk:

File in the exportsubscribed in Plunk
Subscribedtrue
Unsubscribedfalse
Cleaned (addresses that bounced)false
Non-subscribed (never opted in)false
  1. Rename the address column

    Mailchimp calls it Email Address. Plunk needs a column named email, and skips rows without one.
  2. Add a subscribed column

    Set it per file as in the table above. Combining the four files into one CSV is fine.
  3. Tidy the field names you will use

    Headers are lowercased on import, so First Name becomes first name. Renaming it to firstname gives you {{firstname}} in templates.
  4. Import

    Contacts → Import in Plunk. Files are limited to 5 MB, so split a large audience into several.
ColumnWhat Plunk does with it
emailRequired. Rows without a valid address are skipped and listed as errors.
subscribedOptional. true, 1 or yes subscribes the contact; any other value unsubscribes it. Empty keeps an existing contact as it is; new contacts default to subscribed.
Anything elseStored as a custom field. Headers are lowercased, so firstName becomes firstname and First Name becomes first name.

Tags arrive as a text field. A segment with the contains operator on it rebuilds each tag as an audience you can send campaigns to.

3. Move templates

For custom-coded templates, choose Export as template in Mailchimp to download the HTML, then paste it into a Plunk template in HTML mode. Mailchimp cannot export drag-and-drop templates, so rebuild those in Plunk’s visual editor.

Merge tags become Liquid variables named after your imported columns:

MailchimpPlunk
*|FNAME|*{{firstname}} (or {{first name}} if you kept the header)
*|EMAIL|*{{email}}
*|UNSUB|*Remove it: marketing templates get Plunk’s footer
*|IF:FNAME|* … *|END:IF|*{% if firstname %} … {% endif %}

4. Rebuild automation flows

Mailchimp cannot export automation flows; it can only copy them to another audience in the same account. Write down each flow’s trigger, emails and delays, then rebuild it as a Plunk workflow.

Flows that start when someone joins your audience map to a workflow on the contact.subscribed event or on entering a segment. Flows that start from something in your product become a workflow on a custom event you send to POST /v1/track.

5. Move Mailchimp Transactional

If you send receipts or password resets through Mailchimp Transactional (formerly Mandrill):

messages/sendPlunk /v1/sendNotes
message.htmlbodyPlunk builds the plain-text part itself
message.subjectsubject
message.from_email, from_namefrom {email, name}
message.to[] (type "to")tocc and bcc types are not supported
global_merge_varsdata
merge_vars (per recipient)dataSend one request per recipient
message.headersheaders
message.attachments[] {type, name, content}attachments[] {contentType, filename, content}
After: Plunk
const response = await fetch('https://send-api.akmarketingseo.com/v1/send', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${process.env.PLUNK_SECRET_KEY}`,
  },
  body: JSON.stringify({
    to: 'ana@acme.com',
    from: {email: 'hello@acme.com', name: 'Acme'},
    subject: 'Your receipt',
    body: '<p>Thanks, {{firstname}}. Your order is on its way.</p>',
    data: {firstname: 'Ana'},
  }),
});

if (!response.ok) {
  throw new Error(`Plunk returned ${response.status}`);
}

If your app sends through Mailchimp Transactional’s SMTP server instead of the API, only the settings change:

SMTP settings
# Before (Mailchimp Transactional)
host:     smtp.mandrillapp.com
username: any string
password: your Transactional API key

# After (Plunk)
host:     smtp.useplunk.com
port:     587 (STARTTLS) or 465 (TLS)
username: plunk
password: your Plunk secret key (sk_...)

6. Rebuild webhooks

Plunk has no global webhook setting. Instead, you create a workflow that starts on an event and add a Webhook step that posts to your URL. One workflow per event you care about, each with its own URL and headers if you want them.

Mailchimp eventPlunk event
subscribe (audience)contact.subscribed
unsubscribe (audience), unsubcontact.unsubscribed
sendemail.sent
deliveredemail.delivery
openemail.open
clickemail.click
hard_bounce, soft_bounce, cleanedemail.bounce
spamemail.complaint

Plunk’s email.open and email.click fire on the first open and first click of each email, not on every one. The payloads differ, so the code that reads them needs updating. Plunk’s payload for each event is listed in the webhooks guide.

7. Switch over

  1. Send to yourself first

    Send a few real templates from Plunk to your own inboxes and check rendering, links and variables. Gmail’s “Show original” should report DKIM pass for your domain.
  2. Move one kind of email at a time

    Switch one flow, such as password resets, and watch delivery in Plunk for a day before moving the rest. Mailchimp stays available as a fallback the whole time.
  3. Remove the old records last

    Once nothing sends through Mailchimp any more, wait a few days for any retries to settle, then remove its DNS records and cancel the plan.

Keep reading

Frequently asked questions

Move from Mailchimp at your own pace.

Start on the free plan with 1,000 emails a month, no credit card needed. When you need more, every email is $0.001, with unlimited contacts and every feature included.