All articles SMTP & Infrastructure

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

SSam wallness07 Jul 2026
Email Webhooks Explained: How to Track Delivery Events in Real Time

Most email systems treat delivery as a black box. You press send, the message goes out, and unless you're actively polling an API or waiting for a bounce notification, you have no real-time visibility into what happened next. Email webhooks change that. They let your systems respond instantly when specific events occur — a delivery, a bounce, a spam complaint, an unsubscribe — without polling or waiting. If you're building or managing any kind of transactional email system, understanding how webhooks work will make your infrastructure significantly more responsive.

What Is an Email Webhook?

A webhook is an HTTP callback. When a specific event occurs — say, an email you sent gets delivered — your email provider makes an HTTP POST request to a URL you've configured. That POST contains a payload of data about the event: what happened, when, to which address, and relevant metadata.

Your server receives that request and does something with it — updates a database record, triggers a retry, fires a notification, suppresses an address from future sends. The whole thing happens in seconds, automatically, without any action on your part.

Compare this to polling: without webhooks, you'd have to periodically query the API asking "did anything happen?" Webhooks invert that model. Instead of your system asking the provider what happened, the provider tells your system the moment something happens.

Common Email Webhook Events

Different providers expose different events, but the core set is relatively standard:

  • Delivered — the receiving mail server accepted the message
  • Opened — a tracking pixel in the email was loaded (not available for all recipients due to privacy protections)
  • Clicked — a tracked link in the email was clicked
  • Bounced (hard) — the address doesn't exist or the domain is invalid; the message was permanently rejected
  • Bounced (soft) — temporary delivery failure; mailbox full, server temporarily unavailable
  • Spam complaint — the recipient marked the message as spam via their email client
  • Unsubscribed — the recipient clicked an unsubscribe link or used the List-Unsubscribe header
  • Deferred — delivery is being retried; the receiving server accepted the connection but asked for later delivery

Setting Up a Webhook Endpoint

Your webhook endpoint is just an HTTP server that accepts POST requests. Here's what it needs to do:

Accept the Request and Return 200 Quickly

Return a 200 OK response within a second or two. Email providers interpret slow responses or non-200 responses as delivery failures and will retry, potentially flooding your endpoint. Don't do heavy processing in the request handler itself; accept the payload, add it to an internal queue, and return 200 immediately.

POST /webhooks/email
Content-Type: application/json

{
  "event": "bounce",
  "type": "hard",
  "email": "user@example.com",
  "timestamp": "2026-06-15T14:23:01Z",
  "messageId": "abc123"
}

Validate the Signature

Any public HTTP endpoint that accepts data and acts on it is a potential attack surface. Email providers typically sign their webhook payloads with an HMAC signature sent in a request header. Validate this signature before processing any event. If the signature doesn't match, discard the request and log the attempt.

// Signature validation (pseudocode)
const signature = request.headers['x-webhook-signature'];
const expectedSig = hmac_sha256(webhookSecret, request.body);
if (signature !== expectedSig) {
  return 401;
}

Handle Duplicate Events

Webhooks are delivered at-least-once, not exactly-once. Network failures, timeouts, and retries mean you'll occasionally receive the same event twice. Make your event processing idempotent — processing the same event twice should produce the same result as processing it once. Usually this means checking if you've already handled a given messageId and event type before taking action.

What to Do With Webhook Events

Hard Bounces

When you receive a hard bounce event, immediately add that address to your suppression list and never send to it again. Hard bounces mean the address definitively doesn't exist. Continuing to send to hard-bounced addresses raises your bounce rate, which damages your sender reputation. Automate this suppression — don't rely on manual cleanup.

Spam Complaints

A complaint event means a real person explicitly marked your message as spam. Remove them from all future sending immediately, regardless of whether they're on your marketing list, transactional list, or any other segment. One complaint costs more in reputation than the value of keeping that address on your list.

Unsubscribes

Honor unsubscribe events within seconds, not within days. Laws like CAN-SPAM give you 10 business days, but doing it in real time is both better practice and better for reputation. When you receive an unsubscribe webhook, your system should update the subscriber's record immediately before the next send goes out.

Soft Bounces

Track soft bounce counts per address. A single soft bounce is unremarkable — a mailbox temporarily full, a server temporarily down. Three or more soft bounces for the same address in a short period suggests a more permanent problem. After a defined threshold, treat it like a hard bounce and suppress the address.

Building Reliable Webhook Infrastructure

A few architectural notes worth keeping in mind:

  • Use a queue between your webhook endpoint and your processing logic — this decouples receiving from processing and makes retries manageable
  • Log every incoming event with its full payload before processing — you'll need this during debugging
  • Monitor your endpoint's uptime — if your webhook receiver goes down, you'll miss events and your suppression list won't update
  • Set up alerting for unusually high complaint or bounce webhook volumes — these are leading indicators of a deliverability problem

MailDog's SMTP relay includes webhook event delivery for all the standard event types, with signed payloads and retry logic built in. You can find the full event schema and setup guide in the MailDog documentation. For related reading on how bounce handling affects deliverability, see the bounce management guide. If you're evaluating sending infrastructure, compare plans to see what's included at each tier.

Related articles