Skip to content

Webhooks

Webhooks let you receive real-time notifications when email events occur — delivery, bounce, open, complaint, etc. RelayPost sends an HTTP POST to your endpoint with event details.

Configure webhooks in the RelayPost dashboard under Settings → Webhooks:

  1. Enter your endpoint URL (e.g. https://yourapp.com/webhooks/relaypost)
  2. Select the events you want to receive
  3. Save and copy the signing secret for signature verification
EventFired when
queuedEmail accepted and added to the delivery queue
processingEmail is being sent to the recipient’s mail server
deliveredEmail successfully delivered
openedRecipient opened the email
bouncedRecipient’s mail server rejected the email
deferredTemporary failure — will retry
failedAll delivery attempts exhausted
complainedRecipient marked the email as spam
rejectedRelayPost rejected the email before sending

Each webhook POST contains a JSON body:

{
"event": "delivered",
"email_id": "abc123",
"message_id": "<[email protected]>",
"recipient": "[email protected]",
"timestamp": "2026-02-13T12:00:00.000Z",
"metadata": {
"mx_host": "mx.example.com",
"smtp_code": 250,
"smtp_message": "OK"
}
}

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"),
);
}

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
  • Return a 200 response 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