Mandrill is the transactional arm of Mailchimp, and it powers a lot of production traffic: password resets, order confirmations, magic links, invoices, shipping updates. Most of that traffic is sent through the Mandrill API (/messages/send or /messages/send-template) from application code, which means there is no marketing UI in the loop. If a message lands in spam at Gmail, your app logs will still say "sent" and Mandrill's dashboard will still say "delivered". Nothing in your stack tells you where it actually landed.
Mandrill reports MTA delivery, not inbox placement. Add a seed list (Gmail, Outlook, Yahoo, Mail.ru, Yandex, ProtonMail, Fastmail) to every transactional template and read the placement breakdown per provider. Password resets in spam are a silent conversion killer.
Why the Mandrill dashboard misses placement
Mandrill's dashboard is strong on the metrics it has access to — delivery, soft and hard bounces, rejects, opens, clicks, unsubscribes — but none of those are placement signals. A message counted as "delivered" is simply one the receiving MTA accepted with a 250 response. Whether Gmail then put it into Inbox, Promotions, Updates or Spam happens downstream, inside a filter you cannot see.
Transactional mail makes this worse in two ways. First, volumes per template are often low (a new signup might produce one welcome email per day for a small SaaS), so there is no macro signal from open rates. Second, the stakes are high: a password reset in the spam folder is a support ticket, a dropped order confirmation is a chargeback. You want pre-send certainty, not post-send analytics.
The seed-list pattern for transactional APIs
A seed list is a small set of mailboxes you control across every major provider. You include them in every transactional send, read the folder each one landed in, and you have a real placement map per template and per provider. With Mandrill, you have three natural integration points:
- BCC on every message via the
bcc_addressfield on/messages/send. Simplest, always on, zero code changes beyond one config value. - Recipient fan-out — include seed addresses in the
toarray withtype: "bcc"for each seed. Works across bothsendandsend-template. - Dedicated test template — duplicate each production template as
template-name-seedand trigger it on deploy, to the full seed list.
For most teams the BCC approach is the right starting point. It costs nothing, it runs on every production message, and it lets you spot placement drift the day it happens instead of a month later.
BCC integration: one field, full coverage
Mandrill's /messages/send endpoint accepts a bcc_address on the message object. Set it to a catch-all inbox on your domain and forward to your seed list, or set per-template seed lists via the recipient array. The JSON payload looks like this:
POST https://mandrillapp.com/api/1.0/messages/send
{
"key": "YOUR_MANDRILL_KEY",
"message": {
"subject": "Reset your password",
"from_email": "no-reply@brand.com",
"from_name": "Brand",
"to": [
{ "email": "user@customer.com", "type": "to" }
],
"bcc_address": "seed-bcc@brand.com",
"html": "<p>...</p>"
}
}At seed-bcc@brand.com, configure a forwarding rule (or a small Postfix virtual alias) that explodes to every seed mailbox. The seed run is now automatic on every transactional send, with no application-code changes.
Template sends and merge vars
/messages/send-template behaves the same way for seed purposes, but you should be careful with merge variables. If your production template uses recipient-specific merge tags (first name, order number, magic-link token), seed mailboxes will receive the real user's merge data. That is usually fine for seed inspection but a privacy concern if seeds are outside your company.
Two options:
- Use Mandrill's
global_merge_varsto inject a "SEED" banner conditionally based on the recipient domain, so seed copies are visually distinct. - Send a separate, sanitised seed variant after each real send, using fixture data for merge tags. This mirrors the production template but removes user PII.
Reading results across providers
The seed inboxes are only half the picture. The second half is aggregating folder placement — Gmail Inbox vs Promotions vs Spam, Outlook Inbox vs Junk vs Focused, Mail.ru Inbox vs Рассылки vs Спам — into a single view.
This is where the free Inbox Check tool comes in. Instead of you maintaining 20 mailboxes, it runs the seed fleet, reads each folder, and returns a per-provider placement report. You can also pull the result via API and alert when a template drops below a placement threshold.
The free Inbox Check tool generates 20+ fresh seed addresses per test across Gmail, Outlook, Yahoo, Mail.ru, Yandex, ProtonMail and more. No signup, no credit card.
Common transactional placement problems on Mandrill
DKIM on the sending domain, not on mandrillapp.com
Mandrill signs with its own DKIM by default, which technically passes DKIM — but DMARC alignment requires the d= domain to match the From header. Add your Mandrill sending domain in the dashboard and publish the DKIM selector records so alignment passes.
Missing or misaligned SPF
Mandrill's return-path is mandrillapp.com, so SPF "passes" on that domain by default. For DMARC alignment you want SPF on your own From domain. Mandrill's docs describe the SPF include; verify with dig txt brand.com and confirm it resolves cleanly.
Shared IP variability
On the default Mandrill shared pool, your placement is partly a function of who else shares the pool that hour. A seed test at 9am may show Inbox at Gmail; a seed test at 2pm may show Promotions. Run seed tests on a schedule, not just once, to see the variance.
Low engagement on transactional templates
Some transactional templates — e.g. legal notices, privacy policy updates — get almost zero engagement. Over time, low open rates drag the sending domain's Gmail reputation down. A dedicated subdomain for these low-engagement sends (e.g. notices.brand.com) isolates the reputation impact.
Continuous monitoring, not one-off checks
The value of seed testing compounds when it runs continuously. Wire seed results into your observability stack the same way you track 5xx errors:
- Poll the Inbox Check API on every deploy of a template change.
- Alert to Slack when Gmail placement drops below 90% or Mail.ru drops below 70%.
- Store the placement history next to your change log — you will want to correlate placement drops with template edits, IP changes or content tweaks.