All articles SMTP & Infrastructure

Email Webhooks Explained: How to Track Delivery Events in Real Time

SSam wallness16 Jun 2026
Email Webhooks Explained: How to Track Delivery Events in Real Time

When you send an email through an SMTP relay or email API, a lot happens after the message leaves your system. It might be delivered immediately. It might bounce against an invalid address. The recipient might mark it as spam. They might open it, click a link, or unsubscribe. Each of these is a delivery event — and if you are building any application that depends on email, knowing about those events in real time changes what you can build and how quickly you can respond to problems.

Email webhooks are the mechanism that turns delivery events into actionable data for your application. Instead of polling an API every few minutes to check message status, the email platform pushes event data to your server the moment something occurs. It is event-driven infrastructure, and for any production email system, it is significantly more efficient and responsive than the alternative.

What Events Webhooks Can Surface

The specific events available depend on your email sending platform, but the standard set typically includes:

  • Delivered: The receiving mail server accepted the message successfully
  • Hard bounce: The address is permanently invalid — a 5xx rejection from the receiving server
  • Soft bounce: A temporary delivery failure — a 4xx error, typically retried automatically by the sending MTA
  • Spam complaint: The recipient clicked "Report Spam" and the ISP sent a complaint notification via a feedback loop
  • Opened: The recipient opened the message, tracked via a pixel (subject to limitations from Apple Mail Privacy Protection)
  • Clicked: A tracked link within the message was clicked
  • Unsubscribed: The recipient used the list unsubscribe mechanism or clicked an unsubscribe link

Hard bounce and spam complaint events are the most operationally critical. Both indicate that you must stop sending to that address immediately. If your application does not process these events in near-real time, you will continue accumulating hard bounces and complaints that damage your sender reputation with every subsequent send.

How Email Webhooks Work

You configure a webhook by registering an HTTPS endpoint on your server with your email platform. When a delivery event occurs, the platform constructs a JSON payload describing the event — recipient address, message ID, timestamp, event type, and associated metadata — and makes an HTTP POST request to your endpoint.

Your server receives the payload, processes it (updating a database record, triggering a suppression action, logging to your analytics system), and returns an HTTP 2xx response to acknowledge receipt. If your server does not return a 2xx within the timeout period, the webhook delivery is considered failed and is typically retried with exponential backoff by the sending platform.

A Sample Webhook Payload

{
  "event": "hard_bounce",
  "timestamp": "2026-06-15T10:32:11Z",
  "message_id": "msg_8a7f3b2c1d4e9f0a",
  "recipient": "user@example.com",
  "reason": "550 5.1.1 The email account that you tried to reach does not exist",
  "smtp_code": 550
}

The exact schema varies by provider, but the core fields are consistent: event type, timestamp, recipient address, message identifier, and error details for failure events. Your application uses the event type to determine what action to take and the recipient address to look up the corresponding record in your database.

Securing Your Webhook Endpoint

Your webhook endpoint accepts HTTP POST requests from the internet, which means it is exposed to potential abuse. Without security validation, an attacker could send fake payloads to your endpoint, triggering suppression actions for legitimate recipients or injecting false data into your event log.

Most email platforms address this by signing each webhook payload with an HMAC signature computed from the raw request body and a shared secret key. The signature is delivered in an HTTP header. Your endpoint should recompute the expected signature from the request body and your secret, then compare it to the received header value before processing the payload.

import hmac
import hashlib

def verify_webhook_signature(payload_bytes, secret, received_sig):
    expected = hmac.new(
        secret.encode(),
        payload_bytes,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, received_sig)

Use hmac.compare_digest instead of a direct equality check to prevent timing-based attacks. If the signature does not match, return a 400 status and discard the payload without processing it.

Designing for Idempotency

Webhook platforms retry deliveries when your endpoint returns a non-2xx status or fails to respond within the timeout. This creates a practical concern: if your endpoint processes an event successfully but crashes before returning a 2xx, the platform retries, and your handler runs the same event twice. Processing a hard bounce twice should be harmless — suppressing an already-suppressed address has no negative effect — but other event types could cause problems if not handled carefully.

Design event handlers to be idempotent: processing the same event twice produces the same outcome as processing it once. The most common approach is using the message ID as a deduplication key. Record processed message IDs in your database and skip events you have already handled.

Using Webhooks for Real-Time Suppression

The highest-value use of email webhooks is automated suppression management. When a hard bounce event arrives, your endpoint should immediately add the address to your suppression list and mark it so future sends skip it automatically. Spam complaint events require the same treatment — any recipient who reports a message as spam must be suppressed before your next send, regardless of whether they are technically still subscribed.

Manual suppression management — checking bounce reports and complaint data weekly, then manually updating lists — is too slow for anything beyond tiny sending volumes. During a high-volume send, you can accumulate hundreds of hard bounces in minutes. If those addresses keep getting sent to, your bounce rate climbs to levels that trigger spam filtering by major inbox providers. Webhooks make this a non-issue by keeping suppression lists current in real time as events arrive.

Webhooks vs API Polling

The alternative to webhooks is polling — making periodic API calls to retrieve accumulated delivery event data. Polling has two structural problems: it creates unnecessary API load during quiet periods when nothing is happening, and it introduces latency equal to your polling interval. If you poll every five minutes, you may be sending to a newly bounced address for up to five minutes before suppression kicks in.

For production applications where deliverability matters, webhooks are the right choice. They deliver data within seconds of the triggering event and add no polling overhead. The one scenario where polling sometimes makes more sense is in local development or internal tooling that does not have a publicly accessible HTTPS endpoint for the platform to push events to.

Getting Started With Email Webhooks

If you are using MailDog's SMTP relay, delivery event webhooks are available through the platform. The documentation covers endpoint configuration, supported event types, payload schemas, and the signature verification approach. Wiring up bounce and complaint webhooks is one of the highest-ROI integrations you can build for maintaining long-term email deliverability — it is worth prioritizing early in your email infrastructure setup rather than treating it as a future enhancement. If you have questions about specific event types or webhook configuration, reach out to the support team for guidance.

Related articles