Quick answer
There's no single "right" way to test a webhook. A tunnel (ngrok) exposes your local server but breaks on restart. A hosted capture URL shows you the raw payload instantly but doesn't run your handler code. A mock server simulates the provider's API back to your app. CI automation replays saved payloads on every deploy. Most teams end up using two or three of these at different stages, not one tool for everything.
Webhook Testing Methods Compared
Four ways developers test webhooks, what each is actually good for, and how to decide which one fits the stage you're at.
Why "webhook testing" means different things to different people
Ask five developers how they test webhooks and you'll get five different answers, because the phrase covers four genuinely different problems: getting a provider's request to reach your machine at all, seeing exactly what a payload looks like, simulating a provider's behavior without waking up the real provider, and making sure a handler that worked yesterday still works after today's deploy. Each problem has a different tool built for it. Reaching for the wrong one is why "webhook testing" has a reputation for being annoying.
The four methods, compared
| Method | Best for | Setup | Main limitation |
|---|---|---|---|
| Local tunnel (ngrok, Cloudflare Tunnel) | Running your real handler code against a real provider, right now | ~2 min | URL changes on every restart on the free tier; nothing to share with teammates |
| Hosted capture URL (Requex.me) | Seeing the exact payload a provider sends before writing any parser | 0 min | Doesn't execute your application's own code |
| Mock API server | Simulating a provider's API responses back to your app (not just capturing what it sends) | ~5 min | You're defining the behavior yourself, not observing the provider's real quirks |
| CI-automated replay | Catching regressions in a webhook handler on every pull request | ~15 min once | Needs real fixture payloads captured up front to replay against |
Local tunnel: fastest way to hit your real code
A tunnel like ngrok punches a public URL through to localhost:3000, so a provider's real servers can reach your machine while you develop. It's the right call when you want to step through your actual handler in a debugger while a real webhook hits it. The tradeoff: the free-tier URL isn't stable across restarts, and it only works while your laptop and the tunnel process are both running. See the ngrok alternative comparison if the free-tier limits are the problem, or the local webhook testing guide for a tunnel-free way to get a payload onto your machine.
Hosted capture: fastest way to see the payload
A hosted capture URL, like the one Requex.me generates instantly with no signup, exists for a narrower job than a tunnel: it doesn't run any of your code at all. Point a provider at it and every request, headers, query params, and raw body, shows up in real time. That's the fastest path to answering "what does this payload actually look like," which matters because provider docs are frequently incomplete about edge cases. It's also the tool for testing how a provider reacts to failure: configure the endpoint to return a 500 or add a delay, and watch the provider's retry behavior. See the webhook simulator for the failure-simulation side of this, and the video below for the capture flow end to end.
Mock server: simulating the provider, not just capturing it
Capture tools show you what a provider sends. A mock server flips that around: it lets your app call something that behaves like the provider's API, with responses you control, useful when you want your integration tests to run without hitting Stripe or Shopify's real sandbox, or when you need to reproduce a specific edge case (a paginated response, a rate-limit error) on demand instead of waiting for the provider to send it. See setting up a mock API server and, if you already have an OpenAPI spec, generating a mock server from it.
CI automation: making sure it stays working
The other three methods are for building and debugging a handler. This one is for keeping it working: capture a handful of real payloads once (using a hosted capture URL), save them as fixtures, and replay them against your handler on every pull request. A refactor that silently breaks signature verification or payload parsing gets caught before it ships instead of in production three weeks later. See the CI/CD webhook testing walkthrough for the full setup.
Picking the right one for where you're at
"I just want to see what Stripe/GitHub/Shopify actually sends"
Hosted capture URL. Zero setup, and you don't need your app running at all.
"I need to debug my actual handler against a live webhook"
Local tunnel, or a tunnel-free local replay if you don't want to expose your machine.
"My integration tests keep hitting the real provider's sandbox"
Mock API server, self-contained, fast, and you control every edge case.
"A webhook handler broke in production and I don't know why"
That's a debugging problem, not a testing-method problem, start with the debugging webhook errors guide.
"Testing works, now I want it to react automatically"
That's automation, not testing, see how to automate webhooks.
Start with a hosted capture URL
Generate your unique webhook URL in seconds. No signup, no setup, completely free.
Open Webhook Tester →Related Guides & Resources
Local Webhook Testing
Test webhooks on localhost without tunneling
Ngrok Alternative for Webhooks
When tunnel free-tier limits get in the way
Mock API Server
Simulate a provider's API responses for integration tests
CI/CD Webhook Testing
Catch webhook regressions on every deploy
Debug Webhook Errors
Fix common 400, 401, 500 errors in webhook handlers
Webhook Security Best Practices
HTTPS, signatures, and production-ready security
Stripe Webhook Testing
Test payment and subscription webhooks
GitHub Webhook Testing
Capture push, PR, and issue events
Free Webhook.site Alternative
Custom response simulation without a Pro plan