Launch offer: 50% off.Paid plans only.See pricing
Skip to content

Documentation

Reference

Webhook Signature Verification

Signature headers, HMAC validation flow, and replay protection guidance.


Delivery headers

Webhook deliveries include:

  • X-Lamba-Event
  • X-Lamba-Tenant
  • X-Lamba-Timestamp
  • X-Lamba-Signature

Two signature formats may appear:

  • current format: uppercase hex of HMAC_SHA256(secret, "{timestamp}:{rawBody}")
  • v1 format: v1=<lowercase hex> where input is "{timestamp}.{rawBody}"

Verification algorithm

  1. Read raw request body exactly as received.
  2. Read timestamp and signature headers.
  3. Recompute expected signature with your webhook secret.
  4. Compare signatures using constant-time comparison.
  5. Reject timestamps outside your replay window.

Node.js example

import crypto from "node:crypto";

export function verifySignature(input: {
  secret: string;
  timestamp: string;
  rawBody: string;
  providedSignature: string;
}) {
  const base = `${input.timestamp}:${input.rawBody}`;
  const expected = crypto
    .createHmac("sha256", input.secret)
    .update(base, "utf8")
    .digest("hex")
    .toUpperCase();

  return crypto.timingSafeEqual(
    Buffer.from(expected, "utf8"),
    Buffer.from(input.providedSignature, "utf8")
  );
}

Replay protection

  • Set a max clock skew (for example 300 seconds).
  • Reject old timestamps.
  • Keep idempotency keys for processed delivery IDs.