Skip to main content
Each webhook endpoint has a signing secret. We use it to sign every delivery so you can verify that the payload came from Spirii and wasn’t tampered with.

Headers

Every delivery includes:
HeaderDescription
Spirii-SignatureHMAC-SHA256 over timestamp.body, hex-encoded.
Spirii-TimestampUnix epoch seconds when the signature was generated.
Spirii-Event-IdUnique event ID — use for idempotency.

Verifying in Node.js

import crypto from "node:crypto";

function verify(rawBody, headers, secret) {
  const ts = headers["spirii-timestamp"];
  const sig = headers["spirii-signature"];
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${ts}.${rawBody}`)
    .digest("hex");
  return crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}
Reject deliveries with a timestamp more than five minutes old to prevent replay attacks.