Migration illustration Migration guide

Migrate from Mailchimp Transactional to Mailtrap

A complete technical guide to switch from Mailchimp Transactional (formerly Mandrill) to Mailtrap. Most teams complete the migration in under an hour.

Migration Checklist

  1. Authenticate your domain
    Add and verify your domain before sending. Follow the Domain Setup article at docs.mailtrap.io.

Need some help?

Contact our support and our developers will help you with it.

Need some help?
  1. Get your API token
    Mailtrap auto-generates a token when you add a domain. Find it under Settings → API Tokens. Read more on API tokens.
  2. Update your integration
    Swap your Mailchimp Transactional endpoints and credentials for Mailtrap’s (API or SMTP). See the migration sections below.
  3. Migrate templates
    Both platforms use Handlebars, so content migrates directly. See the templates sections below.
  4. Migrate suppressions
    Export Mailchimp Transactional suppressions and import them into Mailtrap via CSV or manually. Click here for more information.
  5. Migrate users
    Add users from the User Management tab and review permissions during migration.
  6. Set up webhooks
    Follow the Mailtrap Webhooks step-by-step guide.
  7. Security and compliance
    Visit the Trust Center page to review Mailtrap’s security practices and compliance standards.

Mailtrap tip

You can use ActionMailer Balancer Ruby gem to proportionally distribute the email sending load between two different sending services (e.g. 70% Mailchimp Transactional and 30% Mailtrap) to mitigate the sending risks.

 

Mailtrap tip

Concepts

Sending domains

Mailchimp Transactional equivalent: Sending Domains / Domain Authentication

Both platforms require DNS-based domain authentication using SPF, DKIM, and DMARC records. Mailchimp uses two CNAME records for DKIM, plus a TXT record for domain ownership verification. Mailtrap also requires DMARC validation. 

The DNS standards are the same. The difference is in how each platform surfaces domain status and what records it generates for you.

And DKIM records can be added alongside Mailchimp’s (different selectors, no conflict), and one DMARC record covers both. 

Important: For Mailchimp specifically, SPF inclusion (servers.mcsv.net) is optional. DMARC compliance is achieved via DKIM alone, since Mailchimp doesn’t use your domain in the Return-Path. Adding it to your SPF record is technically harmless but increases your DNS lookup count unnecessarily.

See the Mailtrap domain setup guide for step-by-step instructions.

Separate sending streams

Mailchimp Transactional equivalent: N/A – single endpoint

Mailchimp routes all email through a single API endpoint and SMTP host. Mailtrap separates transactional and bulk email into distinct infrastructure:

  • Transactional: For sending user-triggered emails like welcome emails and password resets.
  • Bulk: For sending promotional, marketing, emails like newsletters and product updates.

By keeping the sending infrastructures separate, you are able to:

  • Protect your transactional email reputation from the performance of your bulk campaigns
  • Ensure each stream routes through the right IP pools
  • Give mailbox providers the signals they need to categorize and deliver your emails correctly
Image

Email categories

Mailchimp Transactional equivalent: Tags (up to 100 per message)

Mailchimp uses tags – an array of strings in the API request – to group messages for stats aggregation. Stats accumulate per-tag, and you can filter activity by tag.

Mailtrap uses Email Categories – set via the category field in the API or the X-MT-Category header in SMTP. Categories serve a similar purpose: grouping messages for tracking and analytics.

Image

Key difference: Mailchimp supports multiple tags per message; Mailtrap assigns one category per message.

Organization & sub-accounts

Mailchimp Transactional equivalent: Subaccounts

Mailchimp’s Subaccounts API lets you segment sending reputation, track stats, and manage quotas per tenant or team. You pass a subaccount ID in the send request.

Mailtrap offers Organization and sub-account management from Business plan onwards. It lets you manage complex setups involving multiple teams, clients, environments, or products under a single Organization. To start using the feature, you first need to enable it under the Organization tab.

Image

Terminology comparison

API migration

Authentication

Mailchimp Transactional and Mailtrap authenticate differently:

Mailchimp TransactionalMailtrap
MethodAPI key in JSON request bodyBearer token in Authorization header
Header/field"key": "YOUR_API_KEY" (body field)Authorization: Bearer YOUR_MAILTRAP_API_KEY
HTTP methodsAll endpoints are POSTStandard REST (POST for send)

Mailchimp’s approach means the API key travels inside the payload, not the header. When migrating, move your auth from the request body to the Authorization header.

API mapping

API typeMailchimp TransactionalMailtrapNotes
Transactional emailPOST https://mandrillapp.com/api/1.0/messages/send.jsonPOST https://send.api.mailtrap.io/api/sendDifferent auth model; different field structure (see field map below)
Bulk emailSame messages/send endpointPOST https://bulk.api.mailtrap.io/api/sendMailtrap separates bulk to a dedicated host; Mailchimp uses one endpoint for all
Template sendingPOST https://mandrillapp.com/api/1.0/messages/send-template.jsonPOST https://send.api.mailtrap.io/api/send (with template_uuid)Mailchimp has a separate endpoint for template sends
SuppressionsPOST /api/1.0/rejects/{add,list,delete}.json and /allowlists/GET https://mailtrap.io/fr/api/accounts/{account_id}/suppressionsMailchimp splits into Denylist and Allowlist
StatsPOST /api/1.0/tags/{list,info,time-series}.json and /users/info.jsonGET /api/accounts/{account_id}/stats, /stats/domains, /stats/categories, /stats/email_service_providers, and /stats/dateMailchimp aggregates stats by tag
Email logsPOST /api/1.0/messages/{search,info,content}.jsonGET https://mailtrap.io/fr/api/accounts/{account_id}/email_logsMailchimp’s messages/search is rate-limited to 20 calls/min

Outbound Sending API JSON Field Mapping

FieldMailchimp TransactionalMailtrap
From emailmessage.from_emailfrom.email
From namemessage.from_namefrom.name
To emailmessage.to[].emailto[].email
To namemessage.to[].nameto[].name
To typemessage.to[].type (to, cc, bcc)Separate to, cc, bcc arrays
CCmessage.to[] with type: cccc[].email
BCCmessage.to[] with type: bcc or message.bcc_addressbcc[].email
Subjectmessage.subjectsubject
HTML bodymessage.htmlhtml
Plain-text bodymessage.texttext
Category/Tagmessage.tags (array, up to 100)category (single string)
Custom variables/Metadatamessage.metadata (object) + message.recipient_metadata (per-recipient)custom_variables (object)
Reply-Tomessage.headers["Reply-To"]reply_to object
Custom headersmessage.headers (only Reply-To and X-* allowed)headers
Template IDtemplate_name (slug, top-level in send-template)template_uuid
Template variablesmessage.global_merge_vars + message.merge_vars (per-recipient)template_variables
Template content regionstemplate_content(fills mc:edit regions)N/A
Merge language selectormessage.merge_language (mailchimp” or handlebars)N/A – Handlebars only
Attachmentsmessage.attachments[].{type, name, content} (base64)attachments:[{content, filename, type, disposition}] (base64)
Scheduled sendsend_at (UTC timestamp, top-level)N/A
IP poolip_pool (top-level)N/A – managed by Mailtrap
Open trackingmessage.track_opens (boolean)Via account settings or headers
Click trackingmessage.track_clicks (boolean)Via account settings or headers
Multi-recipient batchingpersonalizations[] (up to 1,000 recipients per request)
Sending streamN/A – single endpointDetermined by endpoint: send.api.mailtrap.io (transactional) or bulk.api.mailtrap.io (bulk)
Inline imagesmessage.images[].{type, name, content}attachments:[{content, filename, type, disposition:”inline”,content_id}]
Subaccountmessage.subaccountN/A – determined by API token scope
Auto-generate text from HTMLmessage.auto_text (boolean)Not supported – send both html and text explicitly
Auto-generate HTML from textmessage.auto_html (boolean)Not supported
Inline CSSmessage.inline_css (boolean)Not supported – inline CSS before sending

Code snippets

  • Mailtrap cURL SDK code snippet cURL
Mailchimp Transactional Mailchimp Transactional
curl -X POST https://mandrillapp.com/api/1.0/messages/send.json \
  -H "Content-Type: application/json" \
  -d '{
    "key": "YOUR_API_KEY",
    "message": {
      "from_email": "sender@yourdomain.com",
      "from_name": "Sender Name",
      "to": [
        {
          "email": "recipient@example.com",
          "name": "Recipient Name",
          "type": "to"
        }
      ],
      "subject": "Welcome aboard",
      "html": "<h1>Hello</h1><p>Welcome to the platform.</p>",
      "text": "Hello. Welcome to the platform.",
      "tags": ["welcome"],
      "track_opens": true,
      "track_clicks": true
    }
  }'
Mailtrap Mailtrap

Copy

curl -X POST https://send.api.mailtrap.io/api/send \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": {
      "email": "sender@yourdomain.com",
      "name": "Sender Name"
    },
    "to": [
      {
        "email": "recipient@example.com",
        "name": "Recipient Name"
      }
    ],
    "subject": "Welcome aboard",
    "html": "<h1>Hello</h1><p>Welcome to the platform.</p>",
    "text": "Hello. Welcome to the platform.",
    "category": "welcome"
  }'

Note: Mailchimp Transactional nests all message fields inside a “message” object with the API key at the top level. Mailtrap uses a flat structure with auth in the header.

SMTP migration

SettingMailchimp TransactionalMailtrap (Transactional)Mailtrap (Bulk)
Hostsmtp.mandrillapp.comlive.smtp.mailtrap.iobulk.smtp.mailtrap.io
Port587, 25, 2525 (STARTTLS), 465 (implicit TLS)587 (recommended), 25, 2525587 (recommended), 25, 2525
TLSSTARTTLS on 587/25/2525; implicit SSL on 465Required (STARTTLS)Required (STARTTLS)
AuthenticationPLAIN, LOGINPLAIN, LOGINPLAIN, LOGIN
UsernameAny valid email addressapi (literal string)api (literal string)
PasswordAPI keyAPI tokenAPI token

Migration notes:

  • Host: Replace smtp.mandrillapp.com with the appropriate Mailtrap host. If you send both transactional and bulk email over SMTP, you now need two separate SMTP configurations.
  • Username: Mailchimp Transactional accepts any email address as the username (it’s ignored for auth). Mailtrap requires the literal string api.
  • Port 465: Mailchimp supports implicit TLS on port 465. Mailtrap does not – use port 587 with STARTTLS instead.
  • Password: Both use an API key/token as the password. Generate a new token in your Mailtrap dashboard.
Image

For more information on migrating your SMTP configuration, click this link. ⬅️

Rate limits & quotas

LimitMailchimp TransactionalMailtrap
API rate limitNot publicly documented150 requests per 10 seconds per API token
Batch sizeNo dedicated batch endpoint; multi-recipient via to array (constrained by 10 MB payload limit)500 emails per batch call
Message size25 MB10 MB default (extendable to 30 MB on request)
Max recipients per SMTP send1,000Single send ( /api/send ) → 1 email, up to 1,000 recipients per field ( to / cc / bcc )
Batch send ( /api/batch ) → up to 500 separate emails per API call
Hourly sending quotaAccount-dependent (reputation-based); 5% reserved for transactional when bulk is queuedPlan-dependent

Email templates

Mailchimp Transactional supports two template syntaxes: Mailchimp merge tags (*|VAR|*) and Handlebars ({{var}}). Mailtrap uses Handlebars exclusively.

If your Mailchimp templates already use Handlebars (merge_language: "handlebars"), the template markup migrates directly – just copy the HTML.

Mailchimp merge tagHandlebars equivalent
*|FNAME|*{{fname}}
*|IF:FNAME|*…*|ELSE:|*…*|END:IF|*{{#if fname}}…{{else}}…{{/if}}

Syntax comparison

PatternMailchimp TransactionalMailtrap
Variable insertion{{variable_name}} (Handlebars) or *|VARIABLE|* (Mailchimp){{variable_name}}
Default/fallback valueSame in Handlebars mode; conditional *|IF:VAR|* in Mailchimp mode{{#if var}}{{var}}{{else}}default{{/if}}
Date formattingNot supported – format before passingNot supported – format before passing
Pass variables via APIglobal_merge_vars + merge_vars (array of {name, content} objects, with per-recipient overrides)template_variables (flat object)
Template identifiertemplate_name (slug)template_uuid
Editable regionsmc:edit regions filled via template_contentN/A
Loops{{#each items}}…{{/each}} (Handlebars mode only){{#each items}}…{{/each}}

Migration notes

  • Mailchimp Transactional variable format uses arrays of {“name“: “var“, “content”: “value“} objects, with separate global_merge_vars (all recipients) and merge_vars (per-recipient). 
  • Mailtrap uses a flat template_variables object: {“var“: “value“}. You’ll need to restructure this when migrating your send calls.

Question icon

Frequently Asked Questions

  • Do I need to re-verify my domain if I’ve already set it up in Mailchimp Transactional?

    Yes, you’ll need to re-verify your domain. See the Mailtrap Knowledge Base for up-to-date guidance.

  • Why does Mailtrap have two separate SMTP hosts?

    Mailtrap separates transactional and bulk streams to protect your sender reputation and ensure proper delivery routing for each email type.

  • Does Mailtrap offer migration assistance?

    Yes, Mailtrap offers migration assistance from Business plan onwards.

  • How do I migrate templates from Mailchimp?

    If your Mailchimp Transactional templates use Handlebars syntax, the template markup copies over directly. Update your API calls to use template_uuid instead of template_name, and pass variables via template_variables (a flat object) instead of global_merge_vars/merge_vars (arrays of name/content pairs). If you use Mailchimp merge tags (*|VAR|*), convert them to Handlebars ({{var}}) first.

  • What about Mailchimp’s ‘mc:edit’ template regions?

    Mailtrap doesn’t use editable content regions. Instead, use Handlebars variables directly in your template markup to insert dynamic content.

  • Can I keep using port 465 with implicit TLS?

    Mailtrap does not support port 465. Use port 587 with STARTTLS instead – this is the recommended configuration.