You’re building an integration that listens for webhooks. A payment provider, a Git platform, a messaging service. Your handler runs on localhost, and the external service can’t reach http://localhost:3000/api/webhook.
So you reach for a tunneling tool. You get a temporary public URL, configure the provider to send webhooks there, and watch your terminal. The webhook arrives. Your handler processes it. You check the database. Looks right. Done.
Or is it?
What if the payload was malformed and your handler returned a 200 anyway? What if two webhooks arrived out of order and you never noticed? What if the response body was wrong but the status code looked fine?
Most webhook testing stops at “did the request arrive?” That question is the starting line, not the finish line. This guide walks through the standard webhook testing stack, what it misses, and how to test webhooks locally with live visibility into every request, every response, and every failure as it happens.
The Standard Webhook Testing Stack
There are three common approaches to testing webhooks during local development. Each solves part of the problem. None solves the whole thing.
Provider CLIs
If you’re testing one platform, the provider might have a CLI utility. Stripe offers stripe listen, GitHub has gh webhook, and Shopify includes webhook forwarding in its CLI.
stripe listen --forward-to localhost:3000/api/webhook
This works for basic Stripe testing. It forwards events from your Stripe account to your local endpoint. But it only works for Stripe. If your application handles Stripe payments, GitHub push events, and Slack slash commands, you now have three different CLI tools running in three terminal tabs, each with its own configuration syntax and log output.
Provider CLIs also introduce a subtle problem: the webhook payloads they forward are often simplified or normalized versions of production events. They do not always match what your application will receive at runtime.
Tunneling Tools
Tunneling tools like ngrok and localtunnel create a public URL that forwards to your local server. You get a real inbound connection from the internet rather than a simulated CLI event.
ngrok http 3000
This is closer to production. Any provider can send webhooks to your ngrok URL. But ngrok gives you raw request logs in a separate web dashboard, disconnected from your code. You’re switching between your terminal, your browser, and the ngrok dashboard to piece together what happened.
Cloud Relay Services
Services like Hookdeck and Svix sit between the provider and your local server. They receive the webhook, log it, optionally transform the payload, and forward it to your endpoint. They add useful features like automatic retries, rate limiting, and event filtering. For a detailed comparison, see our guide on webhook proxies versus localhost tunnels.
These tools give you a clean console for inspecting webhook payloads. But they add a dependency to your dev workflow. You’re now relying on an external service that may have its own rate limits, queue delays, and pricing tiers even during local development.
What Standard Tools Do Not Tell You
Each of these approaches answers the same question: “did the webhook arrive?” But testing webhooks is about more than arrival. It’s about outcomes.
You cannot see failures in real time
Suppose your webhook handler silently catches an error and returns a 200 with a generic { "status": "ok" } body. The ngrok dashboard shows a 200. The Hookdeck console shows a 200. Everything looks fine. But your database was never updated, and the failure message is buried in a log file you’re not watching.
Most tools tell you the HTTP status code. They won’t tell you the response body was wrong, that the handler timed out internally, or that a downstream API call failed inside the handler.
Multi-provider testing is disjointed
Testing Stripe webhooks alongside GitHub webhooks means juggling two separate CLIs or two separate ngrok endpoints. Each provider has its own logs, its own dashboard, and its own failure states. You have no single place to see every incoming webhook across all providers.
When webhooks from different services interact, a Stripe payment triggers a Slack notification. Debugging these chains without a unified view of all incoming webhook traffic means switching between four different windows and reconstructing a timeline from memory.
The review handoff is a black box
When a colleague or client tests your integration, there’s no way to see what happened during their session. They report back: “the webhook didn’t work.” Which webhook? What was the response? Did the endpoint even receive the request? You are debugging from hearsay.
If you’re not watching the ngrok dashboard when a tester sends a webhook, that event is gone. Most tunneling tools won’t give you a persistent session log that captures every request, response, and failure during the entire testing window. This gap in feedback loops is the same reason session awareness matters across all developer workflows, not just webhook testing.
Testing Webhooks with Session Visibility
Here’s where the workflow changes. Instead of asking “did it arrive?” you see every outcome as it happens.
Start a WireMaven tunnel
npm install -D wiremaven
npx wiremaven init
npm run dev
WireMaven gives your local dev server a temporary encrypted public URL. No account. No configuration file. The URL auto-expires after your chosen session duration.
When your dev server starts, WireMaven injects a floating overlay into your browser. It’s not a separate dashboard. It lives inside your running application, right next to the feature you’re building.
Configure any webhook provider
Point Stripe, GitHub, Slack, or any other service at your WireMaven relay URL. No provider-specific CLI needed. No separate forwarding configuration per service. One URL handles everything.
Stripe webhook endpoint https://relay.wiremaven.com/abc123/api/webhook
GitHub webhook endpoint https://relay.wiremaven.com/abc123/api/webhook
Slack slash command endpoint https://relay.wiremaven.com/abc123/api/slack
Different paths on the same tunnel URL route to different handlers in your application. The overlay tracks them all.
Watch the overlay in real time
Every incoming webhook appears as a log entry in the WireMaven overlay. You see the HTTP method, the path, the response status code, and the response time for each request. The log updates live as events arrive.
Successful requests show green. Failed requests show red. A 500 error, a connection timeout, or a malformed response is visually distinct from a clean 200. You catch failures without tailing a log file or switching to a dashboard in another browser tab.
The overlay also shows session metadata: how many viewers are connected, how many requests have come through, and a rolling event log for the entire session. You know at a glance whether your tunnel is active and whether traffic is flowing.
Multi-provider testing, one session
Send webhooks from Stripe, GitHub, and Slack in one session. All of them appear in the same overlay, in chronological order. You can see the full sequence: a GitHub push webhook arrives, triggers your handler, your handler calls Stripe, and Stripe sends a separate webhook back. The overlay shows the chain end to end.
No more switching between terminal tabs to piece together a timeline. You stop guessing whether the second webhook arrived before or after the first.
Close the tunnel when done
Stop your dev server and the tunnel dies. The public URL stops resolving. No exposed endpoint left running. No stale URL floating around with your local server still mapped behind it.
Your session data lives for the duration of the tunnel and disappears when it closes. For the next test, start a new session with a clean overlay.
Tool Comparison
| Tool | Public URL | Request Logs | Real-Time Error Visibility | Multi-Provider | No Account Required |
|---|---|---|---|---|---|
| Stripe CLI | Stripe only | CLI output | No | No | Yes |
| GitHub CLI | GitHub only | CLI output | No | No | Yes |
| ngrok | Yes | Web dashboard | Separate tab | Yes | No |
| Hookdeck | Yes | Web console | Yes | Yes | No |
| WireMaven | Yes | In-browser overlay | Yes, live | Yes | Yes |
Cloud relay services like Hookdeck give you solid webhook inspection tools with retry logic and payload transformation. They’re worth using if your workflow needs those features. They add overhead if all you want is a tunnel with session awareness.
The difference WireMaven introduces is the overlay itself. Instead of glancing at a separate dashboard or scrolling through terminal output, you see request outcomes in the same browser window as your application. You interact with your app and watch webhook traffic simultaneously.
Pick the Right Tool for the Visibility You Need
Webhook testing during local development shouldn’t feel like operating blind. You should know which requests arrived, which ones failed, and what the response looked like, all without switching between five different tools.
The standard stack handles the mechanics. Provider CLIs, tunneling tools, and cloud relays all give you a way to receive webhooks. What they don’t give you is a clear, real-time view of every outcome during the test session.
If you’re comfortable with separate dashboards, ngrok or Hookdeck work well. If you want to see request outcomes inline while you work, start a WireMaven tunnel and keep your eyes on the thing you are building.
npm install -D wiremaven
Run your first webhook test with full session visibility. No account needed. Free during beta.