Resend has supported receiving since November 2025. Both services receive and send email; the distinction is the workflow. Resend notifies your app, then lets it fetch content. inbound includes parsed bodies in the receiving webhook and exposes thread and reply APIs.
Resend can be the better fit if you already use its sending API and want to add receiving in the same integration. Its metadata-first webhook intentionally supports serverless request-size constraints by leaving body, headers, and attachment bytes to follow-up requests.
Consider inbound if your worker needs the parsed text or HTML immediately from the webhook, and you want address routing, stored thread resources, and replies by email or thread ID. File bytes still require download handling; a body-in-webhook design does not eliminate all follow-up requests.
Resend's email.received event contains metadata. Use its Received emails API to fetch body and headers, and its attachments API to obtain download URLs. Missing inline body content is part of this documented contract, not evidence of a failed receipt.
inbound's email.received event includes email.parsedData.textBody and htmlBody alongside headers and attachment metadata. Download files through their authenticated downloadUrl values. The raw MIME field may include attachment content, so measure actual request sizes rather than assuming a JSON webhook is always small.
Resend
email.received metadata event
-> Received emails API: text, HTML, headers
-> Attachments API: download URLs
-> download files needed by the worker
inbound
email.received event
-> email.envelopeRecipients: routing recipients
-> email.parsedData: text, HTML, attachment metadata
-> authenticated downloadUrl requests for needed filesResend supports receiving on a provided domain or a custom-domain catch-all. The reviewed receiving docs do not establish a native thread resource; use their current docs for any newer capability. Keep your application conversation mapping and reply-header logic explicit when evaluating the migration.
inbound supports individual address endpoints and catch-all routing. Its thread APIs retrieve conversation context, and POST /api/e2/emails/:id/reply sets In-Reply-To and References. Keep your application's conversation ID alongside inbound's IDs rather than assuming historical conversations are imported automatically.
Resend documents 30-day email retention on Free, Pro, and Scale, with sending and receiving counted toward combined quotas. inbound plans start at $4/month and meter sending and receiving separately. Check current pricing, domain allowances, and retention requirements for your workload; entry price alone does not determine the total bill.
Map the text and html returned by Resend's Received emails API to inbound's email.parsedData.textBody and htmlBody. Use email.envelopeRecipients for inbound routing, and adapt headers and attachment metadata into your existing message model. Keep Resend provider IDs separate from inbound email.id and RFC message identifiers.
| inbound | Resend | |
|---|---|---|
| Receiving model | Domain/address routing with parsed-message webhook delivery and message APIs. | Receiving domains, metadata events, and APIs to retrieve received content. |
| Payload format | JSON containing parsed text and HTML in email.parsedData. | JSON metadata webhook; fetch body and headers from the Received emails API. |
| Attachments | Metadata and API-key-authenticated download URLs in the webhook. | Attachment metadata in events; attachments API provides temporary download URLs. |
| Threading and replies | Thread list/get APIs and reply endpoint that sets reply headers. | Use headers and application conversation state. Native thread-resource availability: see their docs. |
| Custom domains and routing | Custom MX domains, individual address endpoints, and catch-all routing. | Provided receiving domain or custom-domain catch-all. |
| Sending | Send API and dedicated replies by email or thread ID. | Sending and forwarding APIs. |
| How pricing works | Plans start at $4/month; separate sent and received allowances. See pricing. | Sent and received email share the quota; free-plan daily limits also apply to receiving. |
| Retention | Confirm current retention terms in the docs for your storage requirements. | 30-day email retention documented for Free, Pro, and Scale. |
Compared using public documentation as of September 2026. Check Resend's current receiving docs at https://resend.com/docs/dashboard/receiving/introduction, body-fetch contract at https://resend.com/docs/dashboard/receiving/get-email-content, and attachment workflow at https://resend.com/docs/dashboard/receiving/attachments. Current quotas and retention: https://resend.com/docs/knowledge-base/resend-sending-limits. Pricing: https://resend.com/pricing.
Resend intentionally sends metadata rather than body, headers, or attachment bytes in the event. Fetch content through its Received emails API using the received email ID. inbound instead includes parsed text and HTML in email.parsedData; both contracts require your handler to use the correct fields.
Preserve the original message identifiers and reply-header chain when maintaining application-owned conversations. inbound's reply endpoint accepts an email or thread ID and sets In-Reply-To and References. Test real reply exchanges in the mail clients you support; a matching subject alone is not a conversation mapping strategy.
Use a dedicated receiving subdomain for the rehearsal so your existing domain keeps its mail destination. After testing, replace MX records only for the hostname you intend to move. Keep a saved copy for rollback and leave both handlers available during DNS propagation; multiple MX providers do not create duplicate deliveries by design.
Add a domain, point an address at your webhook, and get structured JSON for every message.
Get started