Resend is a beautifully built sending platform that added receiving in 2025. MailKite is inbound-first: the full parsed message arrives in the webhook itself, domains are unlimited and free rather than one-on-the-free-tier, and you get an open-source webmail component and a Claude Code plugin on top.
Resend has arguably the best developer experience in transactional sending, and adding inbound was its most-requested feature — it now receives. The distinction is design center: sending-first with inbound added, versus inbound-first by design.
MailKite POSTs the parsed text, HTML, headers, threading, and signed attachment URLs in the inbound event — no follow-up API call to fetch the body.
Run every product and client domain on the free plan. No one-domain free tier — add as many as you like at no cost.
@mailkite/mail (MIT) gives you a drop-in inbox UI — a credibility and product surface beyond the API.
A hosted MCP server and Claude Code plugin, so agents and AI tools can drive email directly.
| MailKite | Resend | |
|---|---|---|
| Send API + DX | Clean SDKs, 8 languages | Excellent send DX |
| Inbound design center | Inbound-first | Sending-first, inbound added |
| Full body in webhook | Yes — no second call | Fetch/parse patterns vary |
| Domains on free tier | Unlimited | Limited on free tier |
| OSS webmail component | @mailkite/mail (MIT) | None |
| MCP + Claude Code plugin | Yes | Varies |
| Graceful overage | Metered, no hard cut | Plan limits |
Competitor capabilities change — we re-audit these tables regularly. Spot something out of date? Tell us and we'll fix it.
MailKite ships the whole parsed message in the webhook — body, threading, auth, and signed attachment URLs — so there's no second round-trip to read what arrived.
// Inbound event notifies you a message arrived…
{
"type": "email.received",
"data": { "email_id": "…", "from": "ada@example.com", "subject": "…" }
}
// …then you call the API again to fetch the body/attachments:
const msg = await client.emails.get(event.data.email_id)
// parse msg.text / msg.html / attachments here 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=…" }
]
} Both are developer-first. If you run many domains or lead with inbound, MailKite's unlimited-domains free tier and full-message webhook are the differentiators.
Add our MX records or start on a managed subdomain — all your domains included free.
Read event.text, event.html, event.threadId, event.attachments[] directly — no follow-up fetch by message id.
Verify the HMAC signature. Send through MailKite's API to share one quota, or keep sending on Resend and use MailKite just for inbound.
Capability-wise both receive. MailKite is inbound-first: the full parsed message is in the webhook (no second API call), domains are unlimited on the free tier, and you get an OSS webmail component. Resend's edge is its polished sending DX.
MailKite ships clean SDKs across eight languages plus a CLI, MCP, and a Claude Code plugin. Resend set a high bar for send DX; MailKite's advantage is treating send and receive as one inbound-first platform with unlimited free domains.
Yes. Point MX at MailKite for receiving and keep sending wherever you like — or consolidate onto one shared quota later.
Point a domain, drop in a webhook URL, receive your first email. Unlimited domains, no credit card.