Webhooks

Configure a webhook URL per verified sender domain to receive real-time HTTP POST callbacks when email events occur. Configure from the Domains page under the Webhook button on any verified domain.

EventFired when
email.sentMessage accepted by our mail server
email.deliveredMessage delivered to recipient mail server
email.bouncedMessage permanently rejected (hard bounce)

Payload shape

{
  "event": "email.delivered",
  "messageId": "71688732-3522-48fe-a86a-b3bdd19540ae",
  "timestamp": 1716163741,
  "data": {
    "recipientEmail": "user@example.com",
    "senderDomain": "yourdomain.com"
  }
}

Verifying the signature

Every request includes an X-Altermail-Signature header. Verify it using the signing secret shown in the Domains page after saving your webhook.

const crypto = require("crypto");

function verifyWebhook(rawBody, signature, secret) {
  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");
  return expected === signature;
}

// In your Express handler:
app.post("/webhook", express.raw({ type: "*/*" }), (req, res) => {
  const sig = req.headers["x-altermail-signature"];
  if (!verifyWebhook(req.body, sig, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send("Invalid signature");
  }
  const event = JSON.parse(req.body);
  console.log(event.event, event.messageId);
  res.sendStatus(200);
});

Webhook delivery notes

  • •Webhooks time out after 3 seconds. Return a 2xx quickly and process async.
  • •Failed webhook deliveries are not retried. Use the events API as a fallback.
  • •You can select which event types to receive per domain.