Webhook signature debugger
Paste the signing secret, the exact request body and the headers a webhook sender delivered, pick the sender, and this page recomputes the signature the way that sender documents it. If yours does not match, it tries the usual mistakes (a re-formatted body, a trailing newline, hex instead of base64, a secret with stray whitespace, a missing whsec_ prefix on a Stripe secret) and tells you which one fixes it. Everything runs in your browser with the Web Crypto API: nothing is uploaded, stored or logged. Use a test-mode secret anyway.
Need Twilio, SendGrid or Discord, or the timeout, retry and IP rules for each sender? See the Webhook Spec Atlas ($9) or download the free 5-row sample CSV.
What it checks, per sender
Stripe, GitHub, Shopify, Slack, Zoom, Paddle, Square, Lemon Squeezy, Linear, Twitch EventSub and Svix or Standard Webhooks senders (such as Clerk and Resend). Each follows the sender's own documentation, read on 13 Oct 2026. Twilio, SendGrid, Discord and PayPal use SHA-1 form parameters, public keys or certificates, so they are not in the browser tool; the Webhook Spec Atlas has tested code for the first three.
Why a signature fails
- The body was parsed first. Frameworks that turn JSON into an object change spacing, key order and escapes. Verify against the raw bytes, then parse.
- Hex versus base64. Shopify and Square send base64; GitHub, Stripe and Slack send hex.
- The secret is not what you think. Svix-style secrets are base64 after the whsec_ prefix; Stripe uses the whole whsec_ string as the key.
- The signed string includes more than the body. Stripe and Paddle prepend a timestamp, Slack and Zoom prepend v0 and a timestamp, Square prepends the URL, Twitch prepends the message id and timestamp.
- Textarea line breaks. Browsers read line breaks in a text box as LF. If the original used CRLF, load the body from a file.
A match proves your secret, body and algorithm agree. It does not prove the timestamp is fresh enough or that the sender is genuine unless the secret is private.