Skip to main content

Signature validation

Rewrite signs every webhook delivery before it reaches your endpoint. You should verify the signature before parsing the JSON body or running any business logic.

Signed headers

Every signed delivery includes these headers:
  • svix-id Unique delivery id for the webhook attempt.
  • svix-timestamp Timestamp used when the request was signed.
  • svix-signature Signature header used for verification.

What Rewrite signs

The signature is computed from this exact string:
Important details:
  • payload must be the exact raw request body.
  • Do not JSON.parse(...) before verification.
  • Do not re-stringify the payload before verification.
  • Do not trim whitespace or change encoding.
If the body changes by even one byte, the computed signature will not match.

Which secret to use

Use the webhook signing secret returned by:
  • POST /webhooks
  • GET /webhooks/{id}
Do not use your Rewrite API key for webhook verification. The public secret format normally starts with whsec_....

Verification flow

  1. Read the raw request body as a string.
  2. Read svix-id, svix-timestamp, and svix-signature.
  3. Decode the webhook secret into key bytes.
  4. Compute an HMAC-SHA256 over ${svix-id}.${svix-timestamp}.${payload}.
  5. Base64-encode the digest.
  6. Compare the received signature and the computed signature with a constant-time check.
  7. Only after that should you parse the JSON and process the event.

Verification function examples

The functions below are framework-agnostic. Pass the raw body string and the original svix-* header values exactly as they arrived. The Node tab follows the same verification pattern used by the Rewrite Node library.
Signature verification proves integrity, but you can also enforce your own acceptable timestamp window using svix-timestamp when your threat model requires stricter replay controls.
Persist svix-id or the webhook event id and ignore duplicates safely. Delivery is at-least-once and retries can happen.
Return a 2xx quickly after verification and move slow work into background jobs, queues, or workers.
Log enough context to debug invalid requests, but avoid logging secrets or raw sensitive payloads in unsafe places.

Common mistakes

  • Using express.json() or another parsed body before verification.
  • Verifying against the API key instead of the webhook secret.
  • Re-stringifying parsed JSON before computing the signature.
  • Dropping or renaming the svix-* headers in proxies or middleware.
  • Using a normal string comparison instead of a constant-time comparison.