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.
Every delivery includes:
| Header | Description |
|---|
Spirii-Signature | HMAC-SHA256 over timestamp.body, hex-encoded. |
Spirii-Timestamp | Unix epoch seconds when the signature was generated. |
Spirii-Event-Id | Unique 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.