Skip to main content

Signature Verification

Every webhook delivery is signed, so you can confirm it actually came from CELITECH before acting on it. Never process a webhook payload without verifying its signature first.

Your Signing Secret

Each endpoint has its own signing secret, available under Developers → Webhooks in the dashboard. Treat it like any other credential — keep it out of client-side code, logs, and version control. If a secret is ever compromised, rotate it from the same page — just remember to update your verification code with the new secret afterward.

Request Headers

Every delivery includes the following headers:

HeaderDescription
svix-idA unique identifier for this delivery. Every retry attempt of the same delivery carries this same identifier — use it to de-duplicate if you receive it more than once.
svix-timestampThe Unix timestamp (in seconds) the delivery was sent.
svix-signatureOne or more space-delimited signatures for this delivery, used to verify authenticity.

Verifying the Signature

Verification works by computing an HMAC-SHA256 signature over the delivery's svix-id, svix-timestamp, and raw body using your signing secret, then comparing it — with a constant-time comparison, to avoid leaking timing information — against the value in svix-signature. Requests with a svix-timestamp too far in the past or future should also be rejected, to protect against replay attacks.

An official verification library, available for most languages, handles all of this for you — see Example Verification Code below. If the signature doesn't verify, reject the request (e.g. with a 401) and don't process the payload.

warning

Always pass the raw, unparsed request body to the verification library. Re-serializing a parsed JSON object before verifying can produce a different byte sequence and cause verification to fail incorrectly.

Example Verification Code

Use an official verification library, available for most languages — it implements the algorithm described above for you.

Using an official verification library (npm install svix):

import { Webhook } from 'svix';

function verifyWebhookSignature(payload, headers, secret) {
const wh = new Webhook(secret);
try {
wh.verify(payload, headers); // headers: { 'svix-id', 'svix-timestamp', 'svix-signature' }
return true;
} catch {
return false;
}
}

Once you've implemented verification, see Delivery & Retries for how to send yourself an example event to test it.