Receive transactional email events
Eza posts delivery events to your webhook endpoint and signs every request.
Eza webhooks are not Resend-compatible. Events are also available in the dashboard log, as a CSV export and from a paginated API endpoint.
- Beta
- Sending API
- SMTP relay
Events
Supported events
email.deliveredemail.bouncedemail.complained
Signature
Verify the signature
Request header
Eza-Signature: t=<timestamp>,v1=<signature>Calculate HMAC-SHA256 using the timestamp, a period and the raw request body. Compare it with the signature using the endpoint signing secret. Reject timestamps older than 5 minutes.
verify.ts
import { createHmac, timingSafeEqual } from 'node:crypto' export function verify(header, rawBody, secret) { const parts = Object.fromEntries( header.split(',').map((part) => part.split('=')) ) const age = Date.now() / 1000 - Number(parts.t) if (age > 300) return false const expected = createHmac('sha256', secret) .update(`${parts.t}.${rawBody}`) .digest('hex') const given = Buffer.from(parts.v1 ?? '') return given.length === expected.length && timingSafeEqual(given, Buffer.from(expected))}Pending engineering: confirm the signature encoding (hex) and timestamp unit (seconds) against the implementation.
Retries
Retries and replay
If your endpoint does not return a 2xx response, Eza retries after:
- About 10 seconds
- 1 minute
- 5 minutes
- 30 minutes
- 2 hours
- 6 hours
- 12 hours
Retries stop after 24 hours.
Failed events remain available for replay in the dashboard for 30 days.
Transactional email
