Documentation

Ship webhooks
with confidence.

Everything you need to receive events, verify signatures, route deliveries, and recover from failures — without operating a queue.

API v1 · Updated October 28, 2026
Browse documentation

Security

Verify signatures

Every request includes an X-Hooks-Signature header. Verify it against the raw body using your endpoint’s signing secret before acting on the event.

The header contains a timestamp and one or more signatures: t=1739980800,v1=8f2c…. Compute HMAC-SHA256(secret, timestamp + "." + rawBody) and compare it in constant time.

verify.js
const crypto = require("node:crypto");

function verify(rawBody, header, secret) {
  const parts = Object.fromEntries(
    header.split(",").map((part) => part.split("="))
  );
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${parts.t}.${rawBody}`)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(parts.v1),
    Buffer.from(expected)
  );
}
Constant-time comparisonReject timestamps older than 5 minutes

Never compare signatures with ==. Use a constant-time function and reject requests whose timestamp is more than five minutes old to limit replay attacks.

Ready to try it?Create a free workspace and send your first event.