Examail Webhooks

Configure a webhook in the Sendexa dashboard under Developers → Webhooks and subscribe to delivery events instead of polling /v1/email/status/:messageId.

Real-time delivery

Get notified the moment a message is sent, delivered, bounces, or is marked as spam.

Signed payloads

Every webhook is signed with HMAC-SHA256 in the X-Sendexa-Signature header — verify it before trusting the body.

One pipeline, two sources

Events land the same way whether the message was sent via the REST API or picked up as a bounce/DSN by Examail's own mail node.

Configuring your webhook

Sendexa POSTs signed JSON to your endpoint whenever a message's status changes.

Example payload

JSON
{
"channel": "EMAIL",
"event": "email.delivered",
"messageId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"to": ["user@example.com"],
"subject": "Welcome to Sendexa",
"status": "DELIVERED",
"cost": 0.0001
}

Events

Sendexa eventFires whenMeaning
MESSAGE_SENTProvider accepts the messageHanded off for delivery
MESSAGE_DELIVEREDDelivered / opened / clickedReached the inbox, optionally engaged
MESSAGE_FAILEDHard bounce, DSN failure, or complaintRecipient auto-added to your suppression list

Emails submitted via SMTP relay currently only fire MESSAGE_SENT — bounce-back tracking for that path is on the roadmap (see the SMTP relay docs for the full list of current limitations).

Verify signature

Header:

X-Sendexa-Signature
(HMAC-SHA256 hex of the raw body with your webhook secret).

JavaScript
const crypto = require("crypto");
function verifyWebhook(rawBody, signature, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature || ""),
);
}
Related APIs

POST /v1/email/send — send a message

GET /v1/email/status/:messageId — poll status, history, and stats

GET /v1/email/suppressions — see who's been auto-suppressed from bounces/complaints