Webhook signature tester
Check whether a FormDoc webhook signature is valid, and find out why it isn’t. Paste the signing secret, the X-Formdoc-Signature header and the raw body from your logs, and the tester recomputes the HMAC in your browser. It can also sign a sample request and give you a curl command, so you can test your receiver before any real submission arrives.
Test a signature
Paste a delivery from your logs to check its signature, or sign a test request for your receiver. Your secret never leaves your browser.
How to use the webhook signature tester
- Paste the signing secret FormDoc showed when you added the webhook (it starts with whsec_). Lost it? Rotate it in FormDoc to get a new one.
- Paste the X-Formdoc-Signature header and the raw request body from your server’s logs.
- Press Check signature to see whether they match, and why not if they don’t.
- To test your receiver, enter its address and press Sign a test request.
- Run the curl command: your receiver should accept it, and reject it if you change the body.
How FormDoc signs webhooks
Every webhook request has a header like X-Formdoc-Signature: t=1767225600,v1=5f2b…. The t value is the time in Unix seconds. The v1 value is the hex HMAC-SHA256 of the text <t>.<raw body>, using your webhook’s signing secret as the key. Your receiver recomputes it and compares, and rejects requests whose timestamp is more than about 5 minutes from its own clock, so a captured request can’t be replayed later.
| Problem | What the tester shows |
|---|---|
| The body was parsed and re-serialised before checking | It matches the compact JSON, so verify the raw bytes instead |
| Extra spaces or a line break at the end | It matches once they’re removed |
| A different webhook’s secret, or a mixed-up header and body | No match, with the signature it expected |
| An old timestamp | A warning with the request’s age |
Code to verify signatures in Node.js and Python is in the webhooks guide. Want Claude to read each submission as it arrives? Try the Claude lead triage generator.
Common questions
Is it safe to paste my signing secret here?
The secret stays in your browser: the tester uses the browser’s built-in Web Crypto and sends nothing anywhere. Even so, if a secret has been shared or pasted somewhere you don’t trust, rotate it in FormDoc.
Why does my signature never match?
Most often the body was changed before checking. Frameworks that parse JSON first, such as express.json() before your route, change spacing and key order. Read the raw body, check the signature, then parse it.
Are webhooks available on the Free plan?
Webhooks are part of the Pro plan, which is opening soon. Email notifications work on every plan today. See pricing and integrations.
Does the tester work with other services’ webhooks?
It follows FormDoc’s format, t=…,v1=… over “timestamp.body”. Other services that use the same scheme will work, but many sign differently, so check their documentation.