Inbound email to webhook compared: Resend, Mailgun, SendGrid, Postmark, Cloudflare and MarkRelay
What lands at your endpoint when an email arrives, as each provider documents it: the format, whether the body and attachments are included, how you verify the request, and the size limits.
- Published by
- MarkRelay Research
- Updated
- Sources
- 7 primary sources, linked below
Summary
Every major sending service can also receive mail and POST it to your app, but the payloads differ. Resend's email.received webhook carries only metadata; you fetch the body and attachments from its API. Mailgun routes forward a parsed copy, form-encoded or JSON, with HMAC signature fields. SendGrid Inbound Parse posts multipart form data from a dedicated MX hostname, with an option for raw MIME and a recommended 30 MB ceiling, and documents no signature. Postmark posts JSON with the text, HTML, a stripped reply and base64 attachments up to 35 MB, and retries on failure. Cloudflare Email Workers give you the raw message and leave the rest to your code. MarkRelay posts a signed email.received event with the parsed message and attachment information to webhooks scoped to the mailboxes they cover, and keeps the message in your own Cloudflare account.
Key findings
- 1Resend: event email.received; the webhook has metadata only (IDs, from, to, subject, attachment list); body and attachments come from its API.
- 2Mailgun: route forward() POSTs body-plain, body-html, stripped text and attachments, as form data or JSON; signature, timestamp and token verify the request.
- 3SendGrid Inbound Parse: MX at a dedicated hostname to mx.sendgrid.net; multipart form data or raw MIME; keep messages under 30 MB; no request signature documented.
- 4Postmark: JSON POST with TextBody, HtmlBody, StrippedTextReply and base64 Attachments (35 MB total); 10 retries over up to 6 hours; inbound is listed on the Pro plan.
- 5Cloudflare Email Workers: the raw MIME stream in an email() handler; parsing, storage and any webhook are your code.
Questions this report answers
Asked by real people, quoted as they wrote them.
“email to webhook”
Google and Bing search suggestion
Point the domain's MX at a service that receives and posts each message to your URL: Mailgun routes, SendGrid Inbound Parse, Postmark inbound, Resend receiving, or a Cloudflare Email Worker. The table below shows what each one sends.
“Can I use GoDaddy email instead of EmailJS to receive emails via code?”
r/webhosting
Receiving in code needs mail delivered to something that calls your endpoint, which a hosted mailbox does not do by itself. Any of the services here can post each email to your code; MarkRelay does it from your own Cloudflare account and keeps a copy in a mailbox.
“how to receive email through laravel?”
Stack Overflow
Use an inbound webhook: the provider receives the mail and POSTs it to a Laravel route. Verify the request first: Mailgun with its HMAC signature, MarkRelay with HMAC-SHA256 over the timestamp and raw body.
“Is it possible to use email workers for notifications?”
r/CloudFlare
Email Workers can fetch() any URL with the message they receive, so they can notify a service. Parsing the MIME, retrying and signing are up to you.
What arrives at your endpoint
| Provider | Format | Body and attachments in the request | Verify the request | Size |
|---|---|---|---|---|
| Resend | JSON, email.received | No: metadata, then fetch via API | Not stated | Not stated |
| Mailgun routes | Form data or JSON | Yes, parsed; raw MIME option | HMAC signature, timestamp, token | Not stated |
| SendGrid Inbound Parse | multipart/form-data or raw MIME | Yes | None documented | Keep under 30 MB |
| Postmark | JSON | Yes, attachments base64 | Not stated | 35 MB attachments |
| Cloudflare Email Worker | Raw MIME stream in code | You parse it | Your code | 25 MiB inbound |
| MarkRelay | JSON, email.received | Yes: content and attachment information | HMAC-SHA256 over timestamp and raw body | 25 MiB inbound (Cloudflare) |
Resend
- Format
- JSON, email.received
- Body and attachments in the request
- No: metadata, then fetch via API
- Verify the request
- Not stated
- Size
- Not stated
Mailgun routes
- Format
- Form data or JSON
- Body and attachments in the request
- Yes, parsed; raw MIME option
- Verify the request
- HMAC signature, timestamp, token
- Size
- Not stated
SendGrid Inbound Parse
- Format
- multipart/form-data or raw MIME
- Body and attachments in the request
- Yes
- Verify the request
- None documented
- Size
- Keep under 30 MB
Postmark
- Format
- JSON
- Body and attachments in the request
- Yes, attachments base64
- Verify the request
- Not stated
- Size
- 35 MB attachments
Cloudflare Email Worker
- Format
- Raw MIME stream in code
- Body and attachments in the request
- You parse it
- Verify the request
- Your code
- Size
- 25 MiB inbound
MarkRelay
- Format
- JSON, email.received
- Body and attachments in the request
- Yes: content and attachment information
- Verify the request
- HMAC-SHA256 over timestamp and raw body
- Size
- 25 MiB inbound (Cloudflare)
Not stated means the provider's own page does not say. Source: Resend receiving webhook, Mailgun receive via HTTP, SendGrid Inbound Parse, Postmark inbound, Cloudflare Email Workers.
Webhook only, or webhook plus a mailbox
The hosted services treat inbound mail as an event: they parse it, post it and, depending on the plan, keep it for a while. If the post fails past the retries, or you need to look at the original later, you depend on their retention.
MarkRelay stores every received message in the mailbox first, in your D1 database with attachments in R2, then posts the webhook. Each webhook is scoped to what its owner can access, one domain or chosen mailboxes, and every request carries X-MarkRelay-Event, a timestamp and an HMAC-SHA256 signature of the timestamp and raw body. The same mailbox is readable in the webmail and over the API, so a support agent or an AI agent can reply from it.
Where MarkRelay fits
A good fit when
- Inbound mail that should land in a mailbox people can read, and in your app, at the same time.
- Webhooks per mailbox or per domain with a signature you can verify, on Cloudflare.
Look elsewhere when
- Inbound on a domain whose MX must stay with another provider.
- Raw MIME posted to your endpoint: MarkRelay posts the parsed message.
Common questions
Does Resend's inbound webhook include the email body?
No. Resend's received-email webhook carries metadata only; you fetch the body, headers and attachments with its API.
How do I verify a MarkRelay webhook?
Compute HMAC-SHA256 with your signing secret over the X-MarkRelay-Timestamp value, a dot and the raw body, and compare it in constant time with X-MarkRelay-Signature.
Sources and method
- Resend receiving (resend.com/docs/dashboard/receiving/introduction)
- Resend receiving webhook (resend.com/docs/dashboard/receiving/create-receiving-webhook)
- Mailgun receive via HTTP (documentation.mailgun.com/docs/mailgun/user-manual/receive-forward-store/receive-http)
- SendGrid Inbound Parse (www.twilio.com/docs/sendgrid/for-developers/parsing-email/setting-up-the-inbound-parse-webhook)
- Postmark inbound (postmarkapp.com/developer/user-guide/inbound/parse-an-email)
- Postmark pricing (postmarkapp.com/pricing)
- Cloudflare Email Workers (developers.cloudflare.com/email-routing/email-workers/runtime-api/)
Facts are taken from each vendor's own pricing pages, documentation or terms as of the updated date above; prices are in US dollars per month unless stated. Cost comparisons apply each vendor's published rates to the same volume. MarkRelay is not affiliated with the providers covered here;MarkRelay sells a self-hosted email app, which this page mentions where it fits. Spotted something outdated? Tell us.
Revisions
- : First published; every fact checked on the vendor's own pages.
Related guides
More research
- Email Routing and Sendingsite.cloudflare.com Email Routing: free custom domain email, and how to send
- Transactional emailsite.resend.com pricing: free plan, 3,000 emails and 100 a day
- Email marketing and SMTPsite.brevo.com pricing: free plan, 300 emails a day
- Custom domain emailsite.zoho.com Mail pricing: free plan for 5 users, and Mail Lite at $1
- Custom domain emailsite.fastmail.com pricing: custom domain email from $5 a month
- Custom domain emailsite.workspace.google.com pricing: Business Starter at $7, and what it costs a team