Prompt
How should email delivery events get back into my app?
Latest observation
Sep 23, 2026
OpenAI APIWeb search: off
The usual pattern is:
-
Your app sends email through a provider
e.g. SES, SendGrid, Mailgun, Postmark, etc. -
The provider reports delivery events back to you via webhooks
Set up an HTTPS endpoint in your app to receive events like:- accepted / queued
- delivered
- bounced
- deferred / delayed
- opened / clicked
- complained / unsubscribed
-
Your app records those events against the original message
Typically by storing a provider message ID and/or your own internal email ID when you send the message.
Recommended architecture
- Store an internal
email_idfor every outbound email you send. - Pass that ID through the provider if possible:
- custom header like
X-Internal-Email-ID - metadata/tags/custom arguments
- custom header like
- Receive webhook events at something like:
POST /webhooks/email-provider
- Verify webhook authenticity using the provider’s signature/HMAC mechanism.
- Make the webhook handler idempotent so repeated events don’t break anything.
- Process events asynchronously if you expect volume:
- webhook receives event
- validate + enqueue
- background worker updates DB
Why webhooks are better than polling
- near real-time
- less provider load
- more reliable and standard
- easier to correlate events with your database
Important implementation details
- Don’t rely on the event order; delivery events can arrive out of order.
- Expect duplicates; providers often retry webhooks.
- Keep raw event payloads for debugging and auditing.
- Update status by monotonic progression where possible
e.g. sent → delivered is fine, but a late “deferred” shouldn’t overwrite “delivered” unless your rules allow it. - Have a fallback reconciliation job
occasionally query provider APIs for messages that never got a final status.
Typical event flow
- User signs up
- App sends welcome email
- Provider accepts message and returns a provider message ID
- Provider later sends webhook:
- delivered
- bounce
- complaint
- App updates message row and maybe user reputation / notification state
Minimal data model
You’ll usually want:
id(internal email record)user_idproviderprovider_message_idstatussent_atdelivered_atbounced_atlast_event_payloadlast_event_at
If you want the shortest answer
Use provider webhooks, signed and idempotent, and map them back to your app using an internal email/message ID stored as metadata on the outbound message.
If you want, I can sketch a concrete design for one provider (SES/SendGrid/Mailgun/Postmark) or a sample webhook handler/database schema.