Skip to content
Solution

Webhook debugging that shows the request, the response, and the fix

When a webhook fails you need the exact request, the exact response, and the failure reason in one place — not a single log line. HookWatch captures every delivery so you can debug it.

A webhook fails silently more often than it fails loudly. The provider gets a non-2xx response or a timeout, marks the delivery failed, and moves on — and the first you hear of it is a customer asking why their subscription never activated. Debugging it means answering three questions quickly: what was sent, how your endpoint responded, and what to do next. A single log line rarely answers any of them.

Common causes of a failed webhook

Most failed deliveries come down to a short list:

  • Signature mismatch — the payload fails verification and your handler rejects it with 401 or 400 (wrong secret, raw vs parsed body, clock skew).
  • Handler exception — an unhandled error returns 500. See webhook 500 errors for the common backend causes.
  • Timeout — the handler does too much work inline and the provider gives up before you return 200.
  • Rate limiting — a burst trips your limiter and deliveries come back 429. See webhook rate limits.
  • Endpoint down — a deploy window or crash returns 502 or refuses the connection entirely.
  • Bad parsing — the wrong Content-Type or an assumption about JSON shape throws before any real work happens.

What to inspect first

Work from the response back to the request:

  • Response status — a 5xx is your bug; a 4xx usually means the request was rejected (auth, validation, signature); a timeout means no status at all.
  • Response body — the error message your handler returned is the fastest route to the stack trace or the failed assertion.
  • Request headers — the signature header, Content-Type, and any idempotency or delivery-id header the provider sent.
  • Request body — the exact payload, so you can reproduce the failure locally instead of guessing at its shape.
  • Attempts — whether the provider already retried, how many times, and with what timing, so you can tell a flaky handler from a dead one.

How HookWatch helps

HookWatch sits in front of your endpoint and captures every delivery — request, headers, body, response status, response body, and the full attempt timeline. Point a provider’s webhook URL at your HookWatch endpoint and each delivery becomes an inspectable record instead of a line in a log file you have to grep. Repeated failures for the same endpoint are grouped into a single incident, and you can wire Slack or webhook alerts so a spike reaches you before a user does.

Once you have found and fixed the cause, replay re-sends the exact captured payload to your endpoint — no need to ask the provider to resend or to fake the event.

A worked example

A Stripe invoice.payment_failed delivery comes back 500. In HookWatch you open the delivery, read the response body (nil pointer in InvoiceHandler), confirm the signature header was present and valid, and see the payload that triggered it. You fix the handler, deploy, and replay the delivery — the invoice is recorded, no manual reconciliation. Walk the full sequence in how to debug a failed webhook, or see it applied to Stripe webhooks.

Get started

Start debugging your webhooks.

Point one endpoint at HookWatch, capture a failure, and replay it once it’s fixed. Free during beta.