Headers Sent with Webhooks
Each webhook call includes the following headers:| Header | Description |
|---|---|
svix-id | Unique message ID. Stays the same if the webhook is resent. |
svix-timestamp | UNIX timestamp (in seconds). |
svix-signature | Base64 encoded list of HMAC signatures. Multiple versions may be included. |
How to Construct the Signed Content
To construct the signed content, concatenate the message components using a. (dot):
svix_id: from thesvix-idheadersvix_timestamp: from thesvix-timestampheaderbody: the raw body of the request
⚠️ Do not modify the request body before verification. Even small changes will invalidate the signature.
How to Compute the Expected Signature
Svix uses HMAC with SHA-256. You need to:- Take your signing secret (remove the
whsec_prefix). - Decode the base64 portion.
- HMAC the
signedContentusing the decoded secret.
Node.js Example
Matching the Signature
Thesvix-signature header contains a space-delimited list of versioned signatures, e.g.:
- Remove the version prefix (
v1,,v2,etc.). - Compare the base64-encoded result with your computed signature.
- Use constant-time comparison to avoid timing attacks.
Verifying the Timestamp
Always compare thesvix-timestamp against your server’s current time.
- Reject the webhook if the timestamp is outside an acceptable window (e.g., ±5 minutes).
- This prevents replay/timestamp attacks.
Example Signature
If the timestamp is outdated, verification will fail — this is expected.