Mailchimp Transactional
Send transactional email with Mailchimp Transactional (formerly Mandrill). Use
You are an email operations specialist who integrates Mailchimp Transactional (Mandrill) into projects. Mandrill is Mailchimp's transactional email service with strong template management, metadata tracking, and subaccount support for multi-tenant applications. ## Key Points - Use metadata on every send for traceability — userId, orderId, workflow - Use subaccounts for multi-tenant applications to isolate reputation - Disable open/click tracking for security-sensitive email (password resets, OTPs) - Use template merge tags for personalization — keep HTML out of code - Set `preserve_recipients: false` in batch sends to hide recipient lists - Monitor rejection and bounce rates through Mandrill's dashboard - Sending marketing email through Mandrill — use Mailchimp for campaigns - Not using metadata — makes webhook correlation impossible - Tracking security-sensitive transactional email (OTPs, password resets) - Not implementing subaccounts for multi-tenant — one bad customer ruins reputation - Passing HTML directly instead of using templates for recurring emails - Ignoring hard_bounce and spam events ## Quick Example ```bash npm install @mailchimp/mailchimp_transactional ``` ```typescript import mailchimp from '@mailchimp/mailchimp_transactional'; const client = mailchimp(process.env.MANDRILL_API_KEY); ```
skilldb get email-services-skills/Mailchimp TransactionalFull skill: 201 linesMailchimp Transactional (Mandrill) Email Integration
You are an email operations specialist who integrates Mailchimp Transactional (Mandrill) into projects. Mandrill is Mailchimp's transactional email service with strong template management, metadata tracking, and subaccount support for multi-tenant applications.
Core Philosophy
Metadata is your audit trail
Mandrill's metadata system lets you attach arbitrary key-value pairs to every message. These flow through to webhooks, making it easy to correlate delivery events with business entities like orders, invoices, or user actions.
Subaccounts for multi-tenant
If your application serves multiple customers (SaaS, marketplace), use subaccounts to isolate sending reputation and quota per customer. Each subaccount gets independent bounce and complaint tracking.
Templates with merge tags
Mandrill templates use Mailchimp-style merge tags (*|VARIABLE|*). Templates live
on Mandrill's servers and can be edited by non-developers through the dashboard.
Setup
Install
npm install @mailchimp/mailchimp_transactional
Initialize
import mailchimp from '@mailchimp/mailchimp_transactional';
const client = mailchimp(process.env.MANDRILL_API_KEY);
Key Techniques
Simple send
await client.messages.send({
message: {
from_email: 'noreply@yourdomain.com',
from_name: 'App',
to: [{ email: 'user@example.com', type: 'to' }],
subject: 'Your password reset link',
html: '<p>Click <a href="...">here</a> to reset.</p>',
text: 'Reset: https://...',
tags: ['password_reset'],
metadata: { userId: '123', workflow: 'password_reset' },
track_opens: false, // Disable tracking for security emails
track_clicks: false,
},
});
Template send
await client.messages.sendTemplate({
template_name: 'password-reset',
template_content: [], // Required but can be empty with merge tags
message: {
from_email: 'noreply@yourdomain.com',
from_name: 'App',
to: [{ email: 'user@example.com', type: 'to' }],
subject: 'Reset your password',
merge_vars: [{
rcpt: 'user@example.com',
vars: [
{ name: 'NAME', content: 'Alice' },
{ name: 'RESET_URL', content: 'https://...' },
{ name: 'EXPIRES_IN', content: '1 hour' },
],
}],
tags: ['password_reset'],
metadata: { userId: '123' },
},
});
Batch send with per-recipient merge vars
await client.messages.sendTemplate({
template_name: 'weekly-summary',
template_content: [],
message: {
from_email: 'noreply@yourdomain.com',
to: [
{ email: 'user1@example.com', type: 'to' },
{ email: 'user2@example.com', type: 'to' },
],
subject: 'Your weekly summary',
merge_vars: [
{ rcpt: 'user1@example.com', vars: [{ name: 'NAME', content: 'Alice' }] },
{ rcpt: 'user2@example.com', vars: [{ name: 'NAME', content: 'Bob' }] },
],
preserve_recipients: false, // Hide other recipients
tags: ['weekly_summary'],
},
});
Scheduled send
await client.messages.send({
message: {
from_email: 'noreply@yourdomain.com',
to: [{ email: 'user@example.com', type: 'to' }],
subject: 'Trial ending tomorrow',
html: trialEndingHtml,
},
send_at: '2025-12-25 09:00:00', // UTC
});
Subaccounts (multi-tenant)
// Create subaccount
await client.subaccounts.add({
id: 'customer-123',
name: 'Acme Inc',
notes: 'Enterprise customer',
});
// Send through subaccount
await client.messages.send({
message: {
from_email: 'noreply@acme.yourdomain.com',
to: [{ email: 'user@example.com', type: 'to' }],
subject: 'Your invoice',
html: invoiceHtml,
subaccount: 'customer-123',
},
});
Webhook Processing
| Event | Action |
|---|---|
send | Log send attempt |
delivered | Mark delivered |
hard_bounce | Suppress address permanently |
soft_bounce | Log, monitor |
spam | Suppress from all non-essential sends |
reject | Log — Mandrill rejected before sending |
open | Update engagement (marketing only) |
click | Update engagement (marketing only) |
export async function POST(req: Request) {
const form = await req.formData();
const events = JSON.parse(form.get('mandrill_events') as string);
for (const event of events) {
const email = event.msg?.email;
const metadata = event.msg?.metadata || {};
switch (event.event) {
case 'hard_bounce':
await suppressAddress(email, 'hard_bounce');
break;
case 'spam':
await suppressAddress(email, 'complaint');
break;
}
}
return new Response('OK');
}
Best Practices
- Use metadata on every send for traceability — userId, orderId, workflow
- Use subaccounts for multi-tenant applications to isolate reputation
- Disable open/click tracking for security-sensitive email (password resets, OTPs)
- Use template merge tags for personalization — keep HTML out of code
- Set
preserve_recipients: falsein batch sends to hide recipient lists - Monitor rejection and bounce rates through Mandrill's dashboard
Anti-Patterns
- Sending marketing email through Mandrill — use Mailchimp for campaigns
- Not using metadata — makes webhook correlation impossible
- Tracking security-sensitive transactional email (OTPs, password resets)
- Not implementing subaccounts for multi-tenant — one bad customer ruins reputation
- Passing HTML directly instead of using templates for recurring emails
- Ignoring hard_bounce and spam events
Install this skill directly: skilldb add email-services-skills
Related Skills
AWS Ses
Send email at scale with Amazon SES (Simple Email Service). Use this skill when
Brevo
Send transactional and marketing email with Brevo (formerly Sendinblue). Use this
Courier
Send transactional notifications including email with Courier. Use this skill when
Customerio
Send transactional and marketing email with Customer.io. Use this skill when the
Email Deliverability
Optimize email deliverability across any provider. Use this skill when the project
Loops
Send transactional and marketing email with Loops. Use this skill when the project