Security
Because webhook events can carry patient-derived signals, every delivery is signed. Verify the signature before trusting a payload — it proves the request came from Voxtar and was not altered in transit.
Signature header
Each delivery includes a Voxtar-Signature header: a timestamp and an HMAC-SHA256 of {timestamp}.{raw_body}, keyed with your endpoint's signing secret (shown once when you create the webhook).
Verifying
Recompute the HMAC over the raw request body and compare in constant time. Reject if the timestamp is more than five minutes old to prevent replay.
import { createHmac, timingSafeEqual } from "node:crypto";function verify(rawBody, header, secret) {const [t, sig] = header.split(",").map((p) => p.split("=")[1]);if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;const expected = createHmac("sha256", secret).update(t + "." + rawBody).digest("hex");return timingSafeEqual(Buffer.from(sig), Buffer.from(expected));}
Good practice
Verify against the raw body (not a re-serialized object), serve your endpoint over HTTPS, rotate the signing secret if it may have leaked, and scope the receiving service so it can only enqueue work — never expose it publicly beyond what Voxtar needs to reach.