Why it matters
When a webhook signature check fails, the usual causes are a body that was parsed and re-serialised before hashing, the wrong secret (test versus live), a missing timestamp in the signed string, or hex where the provider used base64. The error message just says "invalid signature".
This verifier rebuilds the signed message exactly as each provider documents it, computes the HMAC with your browser's WebCrypto, and shows the expected and received signatures side by side along with the timestamp's age. Every built-in sample was signed by a separate Python implementation, so the maths is checked both ways.
How to use it
- Choose the provider.
- Paste the request headers and the raw body.
- Paste the signing secret.
- Read the verdict and compare the signatures.
FAQ
Why does my signature never match?
Most often the body was changed before hashing, for example parsed as JSON and serialised again. Hash the raw bytes exactly as received.
What is the timestamp tolerance for?
It stops replay attacks: a captured request can't be resent later. Stripe's libraries default to 5 minutes.
Is my secret sent anywhere?
No. The HMAC is computed in your browser with WebCrypto.
Which providers use Standard Webhooks?
Svix and the services built on it, including Resend and Clerk, use webhook-id, webhook-timestamp and webhook-signature headers.