Signature verification

View as Markdown

Pivotal signs every delivery with the endpoint’s signing secret. The Svix SDK handles verification for you; this page documents what it does so you can implement it manually if you want.

HEADERS ON EVERY REQUEST
HeaderExampleNotes
svix-idmsg_2nQv8c9aZmYHKr1...Delivery id. Different from event.id.
svix-timestamp1748286120Unix seconds. Reject if older than 5 minutes.
svix-signaturev1,EXample...,v1,EXampleSecondary...Space-separated version,signature pairs.
VERIFICATION RECIPE
manual-verify.ts
import crypto from "node:crypto";
function verify(secret: string, id: string, ts: string, sig: string, body: string) {
// signing secret is base64; the value after "whsec_"
const key = Buffer.from(secret.replace(/^whsec_/, ""), "base64");
const toSign = `${id}.${ts}.${body}`;
const expected = crypto.createHmac("sha256", key).update(toSign).digest("base64");
// sig header can hold multiple signatures (rotation)
const ours = sig.split(" ").some((pair) => pair.split(",")[1] === expected);
if (!ours) throw new Error("bad signature");
if (Math.abs(Math.floor(Date.now() / 1000) - Number(ts)) > 300) {
throw new Error("timestamp too old");
}
}
SECRET ROTATION

The Webhooks dashboard lets you rotate the signing secret with a 24-hour overlap. Deliveries during the overlap window carry two signatures so your old key keeps validating while you deploy the new one. The svix-signature header lists both, separated by a space — see the recipe above for how to handle multiple candidates.