Mandrill genuinely receives email, but it's an add-on to a paid Mailchimp Standard+ marketing plan and hands you inbound as a batched mandrill_events array with the auth signal spread across separate fields. MailKite delivers one parsed email.received JSON event with the auth verdict already resolved, and sending shares the same API — no marketing suite required.
Mandrill really does receive inbound at scale, batching up to 1,000 events per request, and each message carries spam_report, spf, and dkim signals. If your org already pays for Mailchimp Standard, keeping marketing and transactional under one login is a legitimate reason to stay.
Mandrill isn't standalone: Transactional is an add-on to a paid Mailchimp Standard (~$20/mo) or Premium plan, then blocks of 25k emails on top. MailKite has no marketing-suite prerequisite — DNS-verify a domain and start on the free tier.
Mandrill POSTs a form-encoded body whose mandrill_events field is a JSON string holding an array you unpack and loop. MailKite POSTs one email.received JSON object with decoded text, HTML, and threading already parsed.
Mandrill gives you separate spf, dkim, and spam_report fields you assemble into a trust decision by hand. MailKite ships one auth block — { spf, dkim, dmarc, spam } — so an agent can weigh a sender before acting on the body.
Replying on Mandrill is a separate Messages/send call where threading headers are yours to set. MailKite's mk.send({ inReplyTo: event.id }) threads the reply from the address it was written to, sharing one quota with inbound.
| MailKite | Mandrill (Mailchimp Transactional) | |
|---|---|---|
| Receives inbound email | Yes — parsed JSON event | Yes — batched mandrill_events array |
| Prerequisite to start | DNS-verify a domain (MX to receive, SPF+DKIM to send) | Paid Mailchimp Standard+ plan, then Transactional add-on |
| Inbound shape | One parsed email.received JSON object | mandrill_events[] JSON string in a form-encoded POST |
| Auth verdict | One auth block: { spf, dkim, dmarc, spam } | Separate spf / dkim / spam_report you combine |
| Signature check | verifyWebhook(sig, raw, secret) — one call | Rebuild HMAC-SHA1 over sorted POST pairs yourself |
| Reply / threading | mk.send({ inReplyTo: event.id }) threads it | Separate send call; you set threading headers |
| Per-domain fees | None — unlimited domains | Block-based transactional pricing on top of a plan |
| Built-in agent loop | BYO loop, or a route with action: 'agent' | None — you host the whole model loop |
Competitor capabilities change — we re-audit these tables regularly. Spot something out of date? Tell us and we'll fix it.
A batched mandrill_events array you JSON-parse out of a form field and compose a trust verdict from — vs one email.received object with the auth verdict already attached.
POST /hooks/mandrill
Content-Type: application/x-www-form-urlencoded
X-Mandrill-Signature: <base64 HMAC-SHA1 over URL + sorted POST pairs>
mandrill_events=[
{
"event": "inbound",
"msg": {
"from_email": "ada@example.com",
"subject": "Re: invoice #1042",
"text": "Looks good — approved!",
"spf": { "result": "pass" },
"dkim": { "signed": true, "valid": true },
"spam_report": { "score": 0.1 }
}
}
] // one JSON string, inside a form field, holding an array you unpack POST /your-webhook Content-Type: application/json
x-mailkite-signature: t=…,v1=… (HMAC-SHA256 — verify locally)
{
"id": "msg_2Hk9…",
"type": "email.received",
"from": { "address": "ada@example.com" },
"to": [{ "address": "support@myapp.ai" }],
"subject": "Re: invoice #1042",
"text": "Looks good — approved!",
"html": "<p>Looks good — approved!</p>",
"threadId": "<a1b2c3@mail.example.com>",
"auth": { "spf": "pass", "dkim": "pass", "dmarc": "pass", "spam": "ham" },
"attachments": [
{ "filename": "po.pdf", "contentType": "application/pdf",
"size": 18213, "url": "https://api.mailkite.dev/att/2Hk9…/0?sig=…" }
]
} A low-volume agent that just reads a few emails starts near $40/mo of marketing-suite spend on Mandrill before its first reply; at very high send volume Mandrill's block pricing gets competitive per message — the trade is the marketing plan and the inbound assembly you own.
Add the MailKite MX records to your domain — no paid Mailchimp Standard plan or Transactional add-on to enable first. Add SPF+DKIM too if the agent will also reply.
Delete the form parser, the JSON.parse of the mandrill_events string, and the array loop. Read the JSON body directly: event.from.address, event.subject, event.text, event.attachments[].
Drop the hand-rolled HMAC-SHA1-over-sorted-pairs verify for verifyWebhook(sig, raw, secret), then reply through the same send API with mk.send({ inReplyTo: event.id }) instead of a separate Messages/send call.
No. Mandrill hasn't been standalone since 2016 — it's an add-on to a paid Mailchimp Standard or Premium marketing plan, then transactional blocks on top. MailKite has no marketing-plan prerequisite: DNS-verify a domain and the free tier covers 3,000 messages a month, inbound and outbound.
Yes, and it hands it to you more directly. Mandrill genuinely receives, batching events and carrying spf/dkim/spam_report signals — but you unpack the mandrill_events array, rebuild the X-Mandrill-Signature, and assemble a trust verdict yourself. MailKite delivers one parsed email.received event with a resolved auth block.
Mandrill's signature is a base64 HMAC-SHA1 you rebuild from your exact webhook URL plus every POST key and value in sorted order (binary base64, not hex). MailKite verifies in one call — MailKite.verifyWebhook(sig, rawBody, secret) — which handles the signature, replay window, and constant-time compare for you.
The Mandrill alternative for AI agents →
The long-form take on our blog — receipts, runnable code, and where we won't overclaim.
Point a domain, drop in a webhook URL, receive your first email. Unlimited domains, no credit card.