Webhooks

Webhooks that show their work.

Every lifecycle event, delivered to your server signed and retried — with attempt history you can inspect and replay instead of a black box that fires once into the void.

Event catalog

Eight events. Zero mysteries.

email.queuedYour send was accepted and persisted.
email.sentA provider accepted the message for delivery.
email.deliveredThe recipient's server confirmed receipt.
email.bouncedDelivery failed permanently — reason included.
email.complainedRecipient marked it spam — suppress automatically.
email.failedExhausted retries or permanent provider rejection.
email.openedThe message was opened (tracking pixel).
email.clickedA link in the message was clicked.
Trust, then verify

Signed, timestamped, replay-safe

Every delivery carries an HMAC signature and an idempotent event ID. Verify the signature, dedupe on the ID, and process each event exactly once — even when we retry it three times to get it to you.

  • Failures retry with backoff, visibly, in your dashboard
  • Replay any delivery manually after an outage
  • Per-endpoint history: what we sent, what you answered
verify.js — trust, then verify
import crypto from "node:crypto";

function verify(rawBody, signature, secret) {
  const digest = crypto.createHmac("sha256", secret)
    .update(rawBody) .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(digest),
    Buffer.from(signature),
  );
}

Get started

Go get your first delivery.

Not your first signup form, not your first dashboard tour — your first email, landing in an inbox, with the webhook to prove it. Test keys are free and can’t hurt anything. The only thing standing between you and that little delivered tag is one POST request.