zoom webhook error: invalid signature for payload on secret token validation
Fixes Zoom webhook handlers that reject deliveries with 'invalid signature for payload on secret token validation'. Use when your Zoom webhook endpoint fails secret-token signature validation. Not for Zoom API auth errors, not for missing webhook deliveries, not for other providers' signatures.
TL;DR
Rebuild the signature as the v0 label joined to the HMAC-SHA256 of the timestamp plus raw body, keyed with your Zoom webhook secret token, and check the timestamp is fresh. Zoom's scheme signs a string that includes the delivery timestamp, so signing just the body, or using the client secret instead of the webhook secret token, always fails. Rebuild it Zoom's way.
zoom webhook error: invalid signature for payload on secret token validationSteps
- Read the timestamp and signature from the incoming webhook headers, and keep the raw body bytes untouched. Expected: you have all three inputs to the signature.
- Reject the delivery if the timestamp is older than your tolerance window (a few minutes). Expected: stale or replayed deliveries are dropped before crypto runs.
- Confirm your code uses the webhook secret token from the Zoom app's webhook settings, not the app's client secret. Expected: the key matches the one Zoom signed with.
- Build the signed string as the v0 label, the timestamp, and the raw body joined in Zoom's documented order, then HMAC-SHA256 it with the secret token and prepend the v0 label to the hex digest. Expected: your computed signature has the same shape as the header.
- Compare with a constant-time comparison and re-test on a fresh delivery. Expected: validation passes.
Use this when
- Zoom validation fails with exactly "invalid signature for payload".
- A generated handler signs only the body, skipping the timestamp.
- Webhooks worked before a secret rotation or app settings change.
Not for this skill when
- Zoom API calls fail with token errors (that is OAuth, not webhooks).
- Webhook events never arrive (check the event subscriptions and URL).
- The signature belongs to another provider with its own scheme.
Variant phrasings
- Zoom webhook signature validation failed
- Zoom secret token validation invalid signature
- Zoom x-zm-signature verification fails
Why it happens
Zoom does not sign the bare payload. It signs a composite string of version label, timestamp, and raw body, keyed with the webhook secret token. Generated clients routinely get one piece wrong: they sign the parsed JSON instead of raw bytes, they omit the timestamp, they use the OAuth client secret instead of the webhook secret token, or they skip the freshness check and then misread the failure. Any single deviation breaks the match.
Edge cases
- URL validation handshakes use a different flow (plainToken echo); do not run event signature validation on the handshake request.
- The webhook secret token is found in the app's webhook settings, separate from API credentials.
- Clock skew between your server and Zoom can false-fail the freshness check; keep server time synced and allow a small tolerance.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_Me6QGJuXr59yF1TpswC1Wg