Webhook Tester: How to Inspect, Debug, and Replay Webhooks
You're integrating a third-party webhook. Maybe Stripe, GitHub, or Shopify. You need to see exactly what the provider sends before you write any handler code. But you can't just point it at your production server while you're experimenting, and your localhost:8000 isn't reachable from the internet.
You need a safe place to catch the webhook first. That's what a webhook tester is for.
What a webhook tester does
A webhook tester gives you a public URL that captures incoming HTTP requests. You register this URL with whatever service you're integrating, trigger an event, and then inspect everything that arrived: the headers, the body, the HTTP method, the timestamps.
The core workflow is always the same. You get a URL, you point the provider at it, and you watch requests come in. Every captured request is stored so you can review it at your own pace, not just in the moment it arrives.
A good webhook tester also keeps a history. If you triggered five test events across an afternoon of development, you want to be able to go back and compare them. That history is what separates a useful tool from a throwaway one.
What to look for in a webhook tester
Not all webhook testers are created equal. The basics (public URL, request capture) are table stakes. Here's what actually makes a difference.
Human-readable payload summaries. Raw JSON is fine if you already know the schema. But when you're first exploring a new integration, a Stripe checkout.session.completed event can be 200+ lines of nested objects. A tool that tells you "Customer [email protected] completed checkout for $49.00" lets you understand what happened in seconds instead of minutes.
Request replay. You should be able to resend any captured request to any URL. This matters more than it sounds. Once you have the payload, you shouldn't have to trigger the original event again every time you fix a bug. Replay it, fix the issue, replay it again.
Local forwarding. For end-to-end testing, you want webhooks to hit your actual handler code running locally. Look for a tool that can forward captured requests to a local URL, so you can test your handler without exposing your machine to the internet directly.
Team access. If you're on a team, sharing a single endpoint URL means everyone can see the same request history. That's useful when debugging an issue that only one person can reproduce.
How to use a webhook tester (with Stripe as the example)
Here's the process from start to finish. The steps are the same for any provider, but Stripe is concrete enough to be useful.
-
Create an endpoint on your webhook tester. With Payloader, you get a URL like
https://hook.payloader.dev/e/abc123def456. - Go to the Stripe Dashboard, open Developers > Webhooks, and click Add endpoint. Paste your Payloader URL and select the event types you want to receive.
-
Trigger an event. In Stripe's test mode, you can send a test event directly from the Dashboard, or use the Stripe CLI:
stripe trigger checkout.session.completed. -
Open Payloader and inspect the result. You'll see the request method, all headers (including the
Stripe-Signatureheader), and the full payload body. - Use what you learned to write your handler. You now know the exact shape of the data, which fields contain the values you need, and which event types map to which actions in your application.
This observation step is worth doing before you write a single line of handler code. The payload often contains fields that aren't documented clearly, or event structures that differ slightly from what the docs imply.
Forwarding to localhost
Inspecting a captured payload and actually running your handler against it are two different things. At some point, you need the webhook to hit your local server so you can test the full flow.
Payloader lets you forward any captured request to a local URL. You run a lightweight forwarder on your machine, and incoming webhooks get proxied to localhost in real time. No separate tunnel tool required, no ngrok account.
The bigger benefit is replay. Once a request is captured, you can send it again to any URL as many times as you want. If your handler throws a KeyError on the first attempt, fix the code and replay the same request. You don't have to go back to Stripe, trigger another test event, and wait for it to arrive. The payload is already there.
This loop (inspect, forward, fix, replay) is significantly faster than the alternative of triggering real events every time you want to test a change.
When raw JSON isn't enough
Every webhook tester shows you the raw payload. That's the minimum. The question is whether it helps you understand what the payload means.
Payloader includes payload intelligence for the platforms developers integrate most: Stripe, GitHub, Shopify, Linear, Vercel, Slack, SendGrid, and Twilio. When a request arrives from one of these services, Payloader identifies the event type and renders a plain-English summary at the top of the request view.
For a GitHub push event, you'd see something like: "Aaron pushed 3 commits to main. Latest: 'fix: handle empty cart state'." For a Stripe payment, you'd see the customer, the amount, and the outcome, without having to trace through data.object.charges.data[0].amount.
The raw JSON is still there. But the summary tells you immediately whether the right event was triggered and whether the data looks correct. That feedback loop is what makes debugging webhook integrations faster.
Start with a tester, finish with confidence
The best time to use a webhook tester is before you write any handler code. Get a URL, point the provider at it, trigger a few events, and understand exactly what you're working with. Then write the handler, forward requests to your local server, and use replay to iterate without re-triggering events from scratch.
Try Payloader free. You get a public endpoint URL in seconds, request history, payload summaries for major platforms, and local forwarding without any additional setup.