For developers
Webhook signature verifier
Paste the three webhook headers, the raw body and the secret, and see whether the recomputed signature matches - and whether the timestamp is still inside the tolerance window.
Free, no accountIn your browser
The id a delivery carries in its webhook-id header, used as-is in the signed content.
Unix seconds, exactly as the webhook-timestamp header carries it.
One or more space-separated "v1,<base64>" values - several appear during secret rotation.
The exact raw bytes your endpoint received - not a pretty-printed or re-parsed copy.
Starts with "whsec_" - the one the dashboard showed once when the endpoint was created.
Unix seconds, same units as webhook-timestamp. Left blank, the window's own bounds are shown instead.
Result
Signature verified
Recomputing the signature with this secret, id, timestamp and body gives exactly what is in the webhook-signature header below. No time was given to check the timestamp against, so nothing here is judged against a clock: a verifying library would accept webhook-timestamp (1760000000) at any current time between 1759999700 and 1760000300 Unix seconds.
- Passed
Computed signature matches the pasted header
Recomputing HMAC-SHA256 over "evt_01JABCDEFG1234567890ABCD.1760000000.<body>" with this secret and base64-encoding the result gives "v1,ylDLAl/oATQHyJkqEBj/V/NapUVnEzhl+qlVutkSAzI=", which is exactly one of the values in the webhook-signature header you pasted.
Signature you pasted
Signature we computed
- This checks the arithmetic only - that this exact id, timestamp, body and secret produce this exact signature. It cannot confirm a request actually travelled over the network from ResellerHQ, was not replayed, or was not altered before being pasted here; only your own server, checking the live connection and headers itself, can do that.
What this is
This webhook signature verifier recomputes HMAC-SHA256 over the exact id, timestamp and body of a delivery and compares the result, byte for byte, to the webhook-signature header you pasted - so a mismatch is something you see next to the pasted value, not something a library simply tells you happened.
Every delivery ResellerHQ sends is signed the way the Standard Webhooks specification defines, not a scheme invented for this feature alone: `packages/events/src/signing.ts` computes an HMAC-SHA256 over the exact bytes `id.timestamp.body`, base64-encodes the result, and prefixes it `v1,` before it ships as the `webhook-signature` header next to `webhook-id` and `webhook-timestamp`. Because the construction is the published specification's own, any existing Standard Webhooks library can verify it too - this page simply does the same arithmetic in the open.
A header can carry more than one `v1,<base64>` value separated by a space, which the specification allows so a secret can be rotated without a gap: an old and a new secret can both sign the same delivery for a while, and a receiver accepts whichever one it still holds. This page checks every value in the header and says which one, if any, matched.
How to read the result
Two values are shown side by side so a mismatch is visible rather than asserted: "Signature you pasted" is the webhook-signature header exactly as given, and "Signature we computed" is what HMAC-SHA256 over your id, timestamp and body produces with your secret. A single differing byte anywhere in those four inputs changes the whole computed value, so when the two do not match, comparing them by eye usually finds nothing in common - that is expected, not a sign the check is broken.
The timestamp finding is separate from the signature one on purpose: a header can be correctly signed and still be stale. Leave "time to check the timestamp against" blank to see the window a verifying library would currently accept; fill it in with a specific Unix-seconds value to ask whether that exact moment falls inside it.
"Verifying one of our webhooks" walks the same arithmetic this page runs, by hand, in bash with openssl, in Python and in Node, against one worked example with the exact expected signature, then goes on to the retry schedule, the request-building and error-code tools this one does not cover.
Common mistakes
What goes wrong most often, and how to tell.
- Pasting a reformatted copy of the body instead of the exact raw bytesA pretty-printed, re-indented or re-encoded copy of a JSON body is not the same bytes the signature was computed over, even when it parses to the same value - paste exactly what your server received on the wire, whitespace and all.
- Treating the 300-second tolerance as a rule ResellerHQ setThe Standard Webhooks specification itself states no figure, only that a timestamp must fall within "some allowable tolerance" - 300 seconds is the JavaScript reference library's own default, and a different verifying library is free to choose a different one.
Questions
What people ask about this tool.
- HMAC-SHA256 has no partial credit: changing even one byte anywhere in the id, the timestamp, the body or the secret produces a completely different output, with nothing in common with the correct one. A mismatch almost always traces back to a body that was reformatted, re-parsed or had a trailing newline added or removed before it reached this page.
- It belongs to the Standard Webhooks JavaScript reference library, not to ResellerHQ: its constant `WEBHOOK_TOLERANCE_IN_SECONDS` is set to `5 * 60`, and it raises "Message timestamp too old" or "Message timestamp too new" outside that window. The specification itself only requires "some allowable tolerance" and leaves the exact figure to each library.
- Yes - the Standard Webhooks specification allows several space-separated `v1,<base64>` values in one header, which is how a secret rotation keeps working while both the old and new secret are still valid: a delivery signed with either one is accepted, and this page checks every value present and reports which one matched.
- No - it only proves the arithmetic: that this exact id, timestamp and body, combined with this secret, produce this exact signature. It cannot see whether the request travelled over the real network, arrived once rather than being replayed, or was altered before being pasted here; only your own server, checking the live connection itself, can establish that.
Sources
Every fixed value here comes from the provider’s own documentation. These pages change, so each says the day it was last read.
- Standard Webhooks, “Standard Webhooks specification” read 13 October 2026
- Standard Webhooks, “standard-webhooks/standard-webhooks - JavaScript reference library” read 13 October 2026
Use it from the API
The same check, as one request.