Any HMAC-SHA256 with Hookwatch Webhook Tester
This inbox opens the Generic HMAC check for senders that are not built in: the signature header, HMAC-SHA256, SHA-1 or SHA-512, hex or base64 output, a prefix such as sha256=, how the secret is encoded and a template for the signed string. It starts on X-Signature with a hex SHA-256 digest of the body; change any field and the result updates as you type.
- Copy the inbox URL, paste it into the sender as the webhook endpoint and trigger an event.
- Select the request and open the Headers tab to find the signature header, for example X-Signature, X-Hub-Signature or X-Webhook-Signature, and any timestamp header next to it.
- In the Signature tab, Generic HMAC is selected. Set the header, then the digest encoding: 64 hex characters or 44 base64 characters for SHA-256.
- If the value starts with something like sha256= or v1=, enter it as the prefix to strip. If the sender signs a timestamp too, set the timestamp header and a template such as {timestamp}.{body}.
- Paste the secret. Valid confirms the recipe; copy the exact signed string to reproduce it in your own code. Press Send a signed test request to see a known-good example first.
What to know
Almost every webhook sender that is not on a built-in list uses some variation of the same recipe: HMAC over the raw body, or over the body joined with a timestamp or id, keyed with a shared secret, sent in a header. The variations are where verification fails. The digest can be hex (64 characters for SHA-256) or base64 (44 characters ending in =). The header can carry a prefix like sha256= or a list like t=…,v1=…. The secret can be plain text or itself hex or base64 encoded, in which case the HMAC key is the decoded bytes.
The length of the header value tells you a lot before you read any docs. 64 hexadecimal characters is SHA-256 in hex, 40 is SHA-1, 128 is SHA-512. 44 characters with a trailing = is SHA-256 in base64, 28 is SHA-1, 88 is SHA-512. If the value is longer than that, look for a prefix or for several comma or space separated parts. If the sender also sends a timestamp header, the timestamp is almost always part of the signed string, typically as {timestamp}.{body} or {timestamp}:{body}.
Whatever the recipe, hash the raw request bytes before any parsing, because a JSON parser and serialiser round trip changes spacing, key order and unicode escapes. Compare with a constant-time function: crypto.timingSafeEqual in Node, hmac.compare_digest in Python, hmac.Equal in Go, MessageDigest.isEqual in Java. When there is a timestamp, reject values older than a few minutes, and store a delivery id if the sender provides one so retries are not processed twice.
The template field accepts {body}, {timestamp} (the value of the timestamp header you name), {id} (webhook-id or X-Request-Id) and {url} (the full URL the request was sent to, for senders like Square that sign the URL plus the body). When the check is Valid, Show the exact signed string displays the bytes that were hashed, which is the quickest way to find the difference from what your own code builds.
Updated · Cosmovex
Questions
How do I know if a signature is hex or base64?
Hex uses only 0-9 and a-f and is 64 characters for SHA-256. Base64 uses letters of both cases, digits, + and / and usually ends with =; a SHA-256 digest is 44 characters. Pick the matching Digest encoding in the Signature tab.
My secret looks like base64. Is that the key?
Only if the sender says to decode it. Some senders use the secret text as the key, others decode it first. Try Secret encoding text first, then base64 or hex; the one that turns the result Valid is the one your code needs.
What should be in the signed payload template?
Start with {body}. If the sender sends a timestamp header, try {timestamp}.{body} and {timestamp}:{body}. If it signs the URL, use {url}{body}. Show the exact signed string reveals what was hashed for each attempt.
Can I check HMAC-SHA1 or HMAC-SHA512?
Yes. The Algorithm field offers HMAC-SHA256, HMAC-SHA1 and HMAC-SHA512, each with hex or base64 output. Asymmetric signatures such as RSA or ed25519 are not supported.
Is my secret sent anywhere?
No. The HMAC is computed with WebCrypto in your browser and the secret is kept only in this browser's storage. The webhook request itself is stored on our server so it appears in your inbox.
The free plan covers everything on this page. Hookwatch Webhook Tester Pro ($5/mo, billed monthly) is described on the Hookwatch Webhook Tester page.