TL;DR
Resend is the email API developers reach for when they need to send. Clean REST API, React Email integration, TypeScript SDK, nine language clients. It handles outbound well.
Inbound support arrived in November 2025. When a message arrives at a Resend domain, the platform fires a webhook and stores the email for 30 days. That is where Resend's role ends.
There is no inbox object. No thread model. No per-agent address you can provision with an API call.
AgentMail was designed around the inbox as the primitive. Each inbox has its own address, a persistent message store, automatic threading, webhooks, and WebSockets. Provisioning is one API call.
When Resend is the right call
- Send-only workloads: password resets, transactional notifications, marketing broadcasts.
- The team is building with React or Next.js and wants to use React Email for templates.
- TypeScript is the primary language and developer experience is the top priority.
- Volume is high and the workload is one-directional.
When AgentMail is the right call
- The agent needs two-way email: send, receive, parse, thread, respond.
- Each agent or tenant needs a scoped identity: own address, own API key, isolated data.
- The team prefers a managed inbox layer over building one on top of a webhook endpoint and a database.
- The agent uses MCP or webhook-driven workflows.
- Receiving needs to work without a 30-day retention ceiling.
What each one is built for
Resend is a transactional and marketing email API built for developers. The send side is the product: clean API, React Email templates, TypeScript-first SDK, nine official language clients, and an MCP server. Inbound was added in November 2025 as a webhook layer. Configure an MX record on your domain, point a webhook endpoint at Resend, and inbound messages arrive as email.received events. The platform stores each message for up to 30 days and exposes a Received Emails API for retrieval.
There is no inbox object. The domain is a catch-all; routing by recipient address is the application's responsibility. There is no thread model; reconstructing a conversation requires querying stored messages and joining on RFC 5322 headers. The webhook payload is metadata only: sender, recipient, subject, and attachment filenames. The message body and attachment content require a separate API call.
AgentMail is built around the inbox as the primitive. Each inbox has its own address, a persistent message store, automatic threading, webhooks, and WebSockets. Inboxes can be grouped into Pods that isolate one tenant from another.
The agent loop
| Step in the agent loop | Resend | AgentMail |
|---|---|---|
| Send outbound message | Native | Native |
| Receive inbound message | Native (webhook; payload is metadata only) | Native (webhook, WebSocket) |
| Parse content and attachments | Not included in webhook; body and attachments require follow-up API calls | Built in |
| Thread reply against conversation | Customer-built; References chain and database managed by the developer | Built in |
| Store conversation history | 30-day retention via Received Emails API | Built in, persistent |
| Respond in-thread | Native send; In-Reply-To and References headers set manually | Native threaded reply API |
| Stable identity per agent | Domain-level catch-all; no inbox object | Inbox is the identity |
Resend covers sending and receiving. Everything after the webhook fires is yours to build: threading, storage, per-agent identity.
The threading problem
Resend's documentation tells developers how to thread a reply: extract the inbound message_id, set In-Reply-To to that value in the reply, then append all previous message IDs to the References header, separated by spaces. That logic lives in your code and in your database.
If a webhook delivery fails before your database write completes, the next reply will have an incomplete References header. Gmail and Outlook will break the thread. The user sees a new conversation instead of a continuation. For an agent handling many concurrent threads, this failure mode compounds quietly.
AgentMail manages threading automatically. The reply API takes a message_id and handles the headers.
Pricing
Resend
| Plan | Price | Emails/month | Domains | Retention |
|---|---|---|---|---|
| Free | $0 | 3,000 | 1 | 30 days |
| Pro | From $20/month | 50,000 | 10 | 30 days |
| Scale | From $90/month | 100,000 | 1,000 | 30 days |
| Enterprise | Custom | Custom | Custom | Custom |
Dedicated IPs are a $30/month add-on on Scale and above, requiring 500+ emails per day to qualify. All sent and received emails count against the same monthly quota.
AgentMail
| Plan | Price | Inboxes | Emails/month | Retention |
|---|---|---|---|---|
| Free | $0 | 3 | 3,000 | Persistent |
| Developer | $20/month | 10 | 10,000 | Persistent |
| Startup | $200/month | 150 | 150,000 | Persistent |
| Enterprise | Custom | Custom | Custom | Persistent |
Dedicated IPs and SOC 2 Type II report on Startup and above. Full pricing at agentmail.to/pricing.
A note on comparing these numbers
Resend's Pro plan starts at $20/month for 50,000 emails. AgentMail's Developer plan is $20/month for 10,000 emails plus the inbox layer: provisioned addresses, persistent storage, automatic threading, multi-tenant isolation, webhooks, and an MCP server. For send-only workloads, Resend is the better value at this tier. For agent workloads, the comparison is the inbox layer versus building it yourself.
What an AgentMail subscription covers that Resend doesn't
Building a working receive pipeline on Resend means a webhook handler, a database to store message bodies and attachment content (neither is in the webhook payload), threading logic that reconstructs the References chain, and retry handling for failed deliveries. Before any of that, you need domain verification, MX record configuration, and a catch-all endpoint with routing logic. AgentMail collapses all of it to one API call.
The inbox-as-primitive also matters for identity. Every agent on a Resend domain shares the same catch-all event stream, differentiated only by the to field. On AgentMail, each inbox is its own address with its own API key and scoped credentials. Inbox Pods isolate tenant data entirely, so a credential issue in one tenant's environment stays there.
Resend's rate limit is 5 requests per second per team, shared across all API keys. If you're running many agents under one account, they compete for the same bucket. AgentMail's limits are per-inbox.
Code: the full agent loop
AgentMail
from agentmail import AgentMail
from agentmail.inboxes.types import CreateInboxRequest
client = AgentMail(api_key="your_api_key")
inbox = client.inboxes.create(
request=CreateInboxRequest(username="sales-agent")
)
client.inboxes.messages.send(
inbox_id=inbox.inbox_id,
to=["lead@example.com"],
subject="Quick question",
text="Hi Alex, saw your post about email infrastructure..."
)
def on_inbound_email(payload):
message_id = payload["message"]["message_id"]
client.inboxes.messages.reply(
inbox_id=inbox.inbox_id,
message_id=message_id,
text="Thanks for getting back. To answer your question..."
)
Resend
The send call is comparable. The receive flow requires a verified domain, MX record, running webhook endpoint, and application-side storage for threading and history.
import { Resend } from 'resend';
const resend = new Resend('re_your_api_key');
await resend.emails.send({
from: 'sales-agent@yourdomain.com',
to: ['lead@example.com'],
subject: 'Quick question',
text: 'Hi Alex...',
});
async function onInboundEmail(event: any) {
const { email_id, from, subject, message_id } = event.data;
// Webhook payload contains no body; requires a follow-up call
const received = await resend.emails.receiving.get(email_id);
const body = received.data?.text;
const previousRefs = await db.getReferences(message_id);
await resend.emails.send({
from: 'sales-agent@yourdomain.com',
to: [from],
subject: `Re: ${subject}`,
text: 'Thanks for getting back...',
headers: {
'In-Reply-To': message_id,
'References': [...previousRefs, message_id].join(' '),
},
});
// If this write fails, the next reply breaks the thread
await db.saveReference(message_id);
}
The db.getReferences and db.saveReference calls represent a threading layer the developer builds and maintains. A failed webhook delivery before db.saveReference completes silently corrupts the thread for every subsequent reply.
Identity and multi-tenancy
Resend's identity unit is the domain. Every inbound message lands in the same event stream; you route by inspecting the to field in code. Multi-tenant isolation means routing logic, per-tenant storage, and cleanup on offboarding. Rate limits are per team, not per key, so all agents under one Resend account share the same request budget.
AgentMail's identity unit is the inbox. Inboxes group into Pods, which isolate tenant data at the infrastructure level. API keys scope to a pod, so a leaked credential in one tenant's environment can't touch another's mail.
Migrating from Resend to AgentMail
The send side is close to a drop-in. resend.emails.send becomes client.inboxes.messages.send with similar arguments.
The receive side is the larger change. The catch-all webhook, the threading database, and any storage logic get replaced by per-inbox provisioning and AgentMail's inbound events. AgentMail DNS records can run alongside Resend records during the transition, so the cutover doesn't have to be instant.
Frequently asked questions
Does Resend have inbox objects? No. Resend accepts inbound email at the domain level via a catch-all and fires a webhook for each message. There is no inbox resource, no thread object, and no per-address provisioning API.
Is the Resend inbound webhook payload complete?
No. The email.received event includes metadata: sender, recipient, subject, and attachment filenames. Retrieving the body requires a follow-up call to the Received Emails API.
How long does Resend retain inbound emails? 30 days on all non-Enterprise plans. AgentMail retains messages persistently.
Does AgentMail support React Email templates? AgentMail accepts HTML in the send call. React Email renders to HTML, so templates built with React Email work with AgentMail's send API.
Can I use both AgentMail and Resend together? Yes. Some teams use Resend for high-volume one-way notifications and AgentMail for agents that need full inbox capabilities.
Is AgentMail SOC 2 compliant? Yes, SOC 2 Type II.
Does AgentMail offer inbound filtering and prompt-injection protection? Yes. Allowlists and blocklists can be configured per inbox to filter senders before they reach the agent. Combined with per-inbox API keys, this limits the blast radius of an injected message.
Choosing between them
If your system sends email, Resend works. If your system is email, meaning it reads, remembers, and responds, the architectural difference matters. Resend has no inbox. AgentMail is nothing but inbox.
The Free plan provisions real inboxes with full sending and receiving. No credit card required.
AgentMail gives your agents real inboxes. Create inboxes via API. Send and receive Emails with 0 complexity. Free to start.
![AgentMail vs Amazon SES for AI Agents [2026 Comparison]](/_next/image?url=%2Fblog%2Fagentmail-vs-amazon-ses.jpg&w=3840&q=75&dpl=dpl_A4674JMvczXNXqAcEpm9aYKjbC1y)
![5 Best Email API For Developers Compared [2026]](/_next/image?url=%2Fblog%2F5-best-email-api-for-developers-compared.png&w=3840&q=75&dpl=dpl_A4674JMvczXNXqAcEpm9aYKjbC1y)
