The four states
Everything shows unattempted
No provider secret is registered for the endpoint, so nothing is verified. Register the provider’s
signing secret — see verify inbound signatures — and new events
arrive with a real state.
A signature shows failed
A signature was checked and rejected. The usual causes:
- The wrong secret — a test secret against live traffic, or a stale one after a rotation. Confirm it matches what the provider actually signs with.
- A proxy altered the body — anything between the provider and
wbhk.mythat rewrites the payload breaks the signature, because it’s computed over the exact bytes. - A URL-signing provider (Square, Twilio, HubSpot) — these sign the request URL too, so the URL configured at the provider must match your ingest URL character-for-character.
Verifying webhook.co’s outbound signature yourself won’t match
Almost always one of two things: you’re verifying over a re-serialized body instead of the raw bytes, or you’re using== instead of a constant-time compare. Verify over the exact bytes you
received and compare with crypto.timingSafeEqual / hmac.compare_digest. See
sign outbound webhooks.
Related
Verify inbound signatures
Register a provider secret.