Webhooks
What Is an Email Webhook?
Section titled “What Is an Email Webhook?”An email webhook is an HTTP callback that delivers real-time notifications when email events occur, such as delivery, bounce, open, or spam complaint. Instead of polling an API for status updates, the email service sends a POST request to your endpoint with event details as soon as each event happens.
RelayPost webhooks deliver real-time HTTP POST notifications when email events occur. Each payload is HMAC-SHA256 signed for verification.
Set up a webhook
Section titled “Set up a webhook”Configure webhooks in the RelayPost dashboard under Settings → Webhooks:
- Enter your endpoint URL (e.g.
https://yourapp.com/webhooks/relaypost) - Select the events you want to receive
- Save and copy the signing secret for signature verification
Event types
Section titled “Event types”| Event | Fired when |
|---|---|
queued | Email accepted and added to the delivery queue |
processing | Email is being sent to the recipient’s mail server |
delivered | Email successfully delivered |
opened | Recipient opened the email |
bounced | Recipient’s mail server rejected the email |
deferred | Temporary failure — will retry |
failed | All delivery attempts exhausted |
complained | Recipient marked the email as spam |
rejected | RelayPost rejected the email before sending |
Webhook payload
Section titled “Webhook payload”Each webhook POST contains a JSON body:
{ "event": "delivered", "email_id": "abc123", "message_id": "<uuid@yourapp.com>", "recipient": "user@example.com", "timestamp": "2026-02-13T12:00:00.000Z", "metadata": { "mx_host": "mx.example.com", "smtp_code": 250, "smtp_message": "OK" }}Verifying webhook signatures
Section titled “Verifying webhook signatures”Each webhook request includes a signature header for verification. Validate it to ensure the request came from RelayPost and wasn’t tampered with.
import { createHmac, timingSafeEqual } from "node:crypto";
function verifyWebhook(payload, signature, secret) { const expected = createHmac("sha256", secret).update(payload).digest("hex"); return timingSafeEqual( Buffer.from(signature, "utf-8"), Buffer.from(expected, "utf-8"), );}Retry policy
Section titled “Retry policy”If your endpoint returns a non-2xx status code, RelayPost retries the delivery:
- Up to 3 retry attempts
- Exponential backoff between retries
- After all retries fail, the delivery is logged as failed
Best practices
Section titled “Best practices”- Return a
200response quickly — do heavy processing asynchronously - Use webhook signatures to verify authenticity
- Store events idempotently — you may receive the same event more than once
- Monitor your webhook endpoint’s uptime — missed events aren’t replayed automatically
Frequently Asked Questions
Section titled “Frequently Asked Questions”What email events can I receive via webhooks?
Section titled “What email events can I receive via webhooks?”RelayPost webhooks support these events: queued, processing, delivered, opened, bounced, deferred, failed, complained, and rejected. You select which events to receive when configuring your webhook endpoint.
What is the webhook payload format?
Section titled “What is the webhook payload format?”Each webhook sends a JSON POST request with the event type, email ID, message ID, recipient address, timestamp, and metadata (MX host, SMTP code, SMTP message). All payloads are signed with HMAC-SHA256.
What is the webhook retry policy?
Section titled “What is the webhook retry policy?”If your endpoint returns a non-2xx status code, RelayPost retries up to 3 times with exponential backoff. After all retries fail, the delivery is logged as failed. Missed events are not replayed automatically.
How do I verify webhook signatures?
Section titled “How do I verify webhook signatures?”Each webhook request includes a signature header. Compute an HMAC-SHA256 hash of the raw request body using your webhook signing secret, then compare it to the signature header using a timing-safe comparison function.