Signed webhook deliveries backed by the real event model
Bavimail emits outbound lifecycle events, inbound receipt events, domain verification events, and test pings. Verification should match the actual SDK helper and header contract.
Last updated May 7, 2026
Event Types
These event names come from the backend enum and should be treated as the public contract for webhook subscriptions.
| Event | Description |
|---|---|
email.inbound.received | Inbound email accepted and parsed. |
email.outbound.sent | Outbound delivery or engagement lifecycle event. |
email.outbound.failed | Outbound delivery or engagement lifecycle event. |
email.outbound.opened | Outbound delivery or engagement lifecycle event. |
email.outbound.clicked | Outbound delivery or engagement lifecycle event. |
email.outbound.scheduled | Outbound delivery or engagement lifecycle event. |
email.outbound.cancelled | Outbound delivery or engagement lifecycle event. |
email.outbound.delivered | Outbound delivery or engagement lifecycle event. |
email.outbound.bounced | Outbound delivery or engagement lifecycle event. |
email.outbound.complained | Outbound delivery or engagement lifecycle event. |
domain.verified | Domain verification state update. |
domain.failed | Domain verification state update. |
webhook.test | Webhook test delivery. |
Verification flow
Verify the raw JSON payload against the exact signature headers before trusting the event body. The webhook secret is hex-encoded and is used as the HMAC key.
import { verifyWebhookSignature } from 'bavimail'
app.post('/webhooks/email', async (req, res) => {
const payload = JSON.stringify(req.body)
const event = await verifyWebhookSignature(
payload,
req.headers['x-webhook-signature'],
req.headers['x-webhook-timestamp'],
process.env.BAVIMAIL_WEBHOOK_SECRET!,
)
switch (event.eventType) {
case 'email.outbound.delivered':
case 'email.outbound.opened':
case 'email.outbound.clicked':
case 'email.outbound.bounced':
await reconcileEmailState(event)
break
}
res.status(200).end()
})Delivery contract
Headers
x-webhook-signaturex-webhook-timestampStore the event id, event type, and timestamp so retries can be handled idempotently in your own system.
Do not document suppression updates as webhook events. The current emitted set is outbound lifecycle, inbound receipt, domain verification, and test traffic only.
Verify x-webhook-signature and x-webhook-timestamp before parsing the body as a trusted event.