Replace Postal inbound routes with MailKite
Move application-facing inbound email from a self-hosted Postal route to MailKite webhooks, with a safe DNS cutover and attachment handling.
Reviewed
If Postal is only receiving mail for an application, MailKite can take over that inbound path: MailKite receives the message, parses it, and sends your app a signed webhook with normalized sender-authentication results and attachment access. You no longer operate Postal for that domain’s inbound application mail. This does not migrate Postal’s outbound sending, stored messages, or message history; Postal is not an IMAP/POP mailbox host.
Before the cutover
You need a MailKite account, a domain you can update in DNS, and a public HTTPS webhook endpoint. Read the MailKite receiving guide and webhook security guide. Keep Postal running during the transition; changing MX records affects where new inbound messages are delivered.
Configure MailKite
- Add the receiving domain in MailKite and complete its domain verification.
- Create a route for the exact address or pattern your application needs and set its webhook URL.
- Store the route’s webhook signing secret in your application secret manager, separate from any API key.
- Verify webhook signatures with the MailKite SDK before trusting the event, then persist it durably and return success. Deduplicate retries using the message/event identity in the current webhook contract.
- Use the event’s normalized
authresult for SPF, DKIM, and DMARC signals. Treat these as sender-authentication evidence, not proof that the message content is safe.
Use MailKite’s receiving guide for a verified handler pattern. For attachments, use the attachment references provided by the MailKite event contract rather than Postal’s inline Base64 attachments[].data; enforce size/type policy before retrieval or processing.
Move mail delivery
Update the domain’s MX records to the values shown in MailKite’s domain setup. DNS changes can take time to propagate, so monitor both MailKite and Postal during the TTL window. Send controlled test messages to the addresses your app handles and confirm that each message arrives once, the signature verifies, authentication fields are present as expected, and attachments follow your policy.
Do not leave old Postal MX records mixed with the new records as a permanent load-balancing plan: senders choose among MX hosts according to DNS priority and implementation, so delivery can split unpredictably. If Postal still needs to receive other mail, keep that mail on a separately configured domain or subdomain with its own MX records and routing plan.
After observing successful delivery through MailKite and accounting for DNS caching, remove or disable only the Postal inbound routes that are no longer needed. Keep Postal’s outbound configuration unchanged if it still sends mail for you.
What changes in your application
Postal’s incoming HTTP route sends Postal-specific JSON (or raw MIME) to your endpoint. MailKite sends its own signed webhook contract. Update signature verification, payload mapping, attachment access, retry/idempotency handling, and monitoring together; changing only the destination URL is not a migration. Do not pass a Postal payload to MailKite.verifyWebhook or claim it has MailKite’s normalized auth data.
See receive inbound email with Postal for the existing Postal path and MailKite receiving docs for current DNS and event details.