Inbound Email Webhooks Guide
Receive email as structured webhooks with parsed headers, bodies, attachments, routing rules, and retry handling.
TL;DR
Point MX records at Postscale for an inbound domain or subdomain, create routing rules, verify webhook signatures, and treat attachment downloads separately from webhook retries. Keep inbound on a subdomain if your root domain already has mailboxes.
What you will learn
- Route inbound mail to Postscale without disrupting existing mailboxes
- Design a webhook handler that verifies signatures and handles retries
- Use aliases, rules, and metadata to route messages inside your application
If messages appear in your inbox but no webhook attempts are made, check the recipient route. Follow Mail is stored but there are zero webhook attempts to find the cause and test the fix.
Pick the receiving domain
Use a dedicated inbound subdomain when possible:
inbound.example.com. MX 10 mx1.postscale.io.
inbound.example.com. MX 20 mx2.postscale.io.
This lets your application receive ticket-123@inbound.example.com while normal company mail stays on example.com.
Create a webhook endpoint
Your endpoint should:
- Accept POST requests.
- Verify the Postscale signature.
- Store the event id for idempotency.
- Return a 2xx response after durable processing.
- Download attachments asynchronously if needed.
Do not perform slow downstream work before acknowledging the webhook. Queue it instead.
Route by recipient
Creating an endpoint is only the first step. Select it in an alias with action Webhook, or enable domain catch-all and create a domain-wide webhook rule. Catch-all without a matching alias or rule stores the message without sending a webhook.
For all incoming mail, use the dashboard recipe with exact field values. For one address, use the exact-alias recipe.
Common patterns:
| Address pattern | Use case |
|---|---|
support@inbound.example.com | Shared support intake |
reply+{thread}@inbound.example.com | Threaded product replies |
{customer}@inbound.example.com | Per-customer routing |
| Random aliases | Abuse-resistant inbound workflows |
Keep parsing rules deterministic. Ambiguous routing is hard to debug.
Verify signatures
Webhook signatures protect your endpoint from forged inbound events. Validate the HMAC against the raw request body before parsing JSON.
Reject requests when:
- The signature is missing.
- The timestamp is too old.
- The computed signature does not match.
- The event id has already been processed.
Idempotency matters because retries are normal for webhooks.
Handle attachments
Attachments can be large, so the webhook payload includes metadata and download links. Process downloads in a worker:
- Check file name and content type.
- Enforce size limits in your application.
- Virus scan before user exposure.
- Store only what your retention policy allows.
For support inboxes, store the original message id and thread headers so replies stay connected.
FAQ
Can I receive email on a subdomain only?
Yes. This is the safest pattern when your root domain already uses another mailbox provider.
Are attachments sent inside the webhook payload?
Attachment metadata is included in the payload. Download URLs keep large files out of retry bodies.
Related guides
Put the guide into production
Postscale brings sending, inbound processing, DMARC reporting, and masked addresses behind one API so the operational pieces stay connected.