send.webforms.toRead the docs →

Webhook signature tester

Debugging a signature mismatch usually comes down to one of three things: the wrong string being signed, the body being re-serialized before verification, or a stringified timestamp. This computes the signature the same way WebForms does, so you can isolate which one it is.

Computed signature (HMAC-SHA256 over timestamp.body)Enter a secret above

Everything is computed with WebCrypto in your browser. The secret never leaves this page - check the network tab if you want proof.

The three classic mismatch causes

Signing the wrong string. WebForms signs `${timestamp}.${body}` - the timestamp, a literal dot, then the raw body. Signing the body alone, or joining with anything but a dot, produces a valid-looking but wrong signature.

Re-serialized JSON. If your framework parses the request body and you re-stringify it for verification, key order or whitespace may differ from what was actually sent, and the HMAC changes completely. Always verify against the raw request bytes.

Timestamp type confusion. The x-webforms-timestamp header is milliseconds since epoch as a string. Parsing it to an integer and back is safe; formatting it as seconds is not.

Full details of the scheme, including replay-window tolerance, are in the webhook signing docs.