ngrok is great but overkill when you just want to see what Stripe or GitHub is sending. A hosted webhook inspector gives you a URL, a live request log, and zero setup.
Workflow
Open YoBox's Webhook Tester.
Copy the unique URL it generates.
Paste it into the third-party service's webhook field.
Trigger the event. Watch headers and body stream into the log.
When to graduate
Once you've inspected the payload shape, switch to a local tunnel (ngrok, cloudflared) so your dev server can actually respond. Webhook inspectors are for understanding, not handling.
Why "without ngrok" is the right default
ngrok is an excellent tool, but it solves a slightly different problem than most developers think. ngrok is for handling an inbound request on your laptop — your local Express app actually responds. A hosted webhook inspector is for understanding the request — you want to see what Stripe, GitHub, Shopify, or Clerk is actually sending before you bother writing handler code.
Most webhook integrations start with the second problem, not the first. You do not yet know what fields the payload contains, what headers are signed, or how the provider retries on failure. Solving "see the payload" with ngrok is overkill and slow: you have to install a binary, authenticate, expose your machine, and start a server that does nothing but console.log(req.body).
If you only need to read a payload, a hosted inspector wins. If you need to respond in a way that affects the provider's behavior, a tunnel wins. Most integrations need the inspector first and the tunnel later.
A clean workflow with the YoBox Webhook Tester
The YoBox Webhook Tester gives you a unique URL, a live request log, and zero install steps. The end-to-end loop:
Open the tool. A unique endpoint is generated immediately.
Copy that URL into the provider's webhook configuration (Stripe, GitHub, Linear, Clerk, etc.).
Trigger the event from the provider — a test webhook, a real signup, a push to a branch.
Watch the request appear in the YoBox log, with full headers, body, and timing.
Copy a real payload from the log into your unit tests so your handler is exercised with realistic data.
That five-step loop replaces fifteen minutes of ngrok wiring on day one of a new integration.
Webhook inspector vs. tunnel vs. mock server
┌─────────────────────────────────────────┐
│ 📦 YoBox Webhook Tester │
├─────────────────────────────────────────┤
│ • Inbound requests: ✅ Yes │
│ • Local handler responds: ❌ No │
│ • Replay: ⚠️ Manual│
│ • Best for: Inspecting payloads, │
│ capturing fixtures │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ 📦 ngrok / cloudflared │
├─────────────────────────────────────────┤
│ • Inbound requests: ✅ Yes │
│ • Local handler responds: ✅ Yes │
│ • Replay: ❌ No │
│ • Best for: Live handler │
│ development │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ 📦 webhook.site │
├─────────────────────────────────────────┤
│ • Inbound requests: ✅ Yes │
│ • Local handler responds: ⚠️ Limited│
│ • Replay: ⚠️ Manual│
│ • Best for: Same as YoBox, │
│ third-party │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ 📦 Mock server (msw, Prism) │
├─────────────────────────────────────────┤
│ • Inbound requests: ❌ No (outbound only) │
│ • Local handler responds: N/A │
│ • Replay: ✅ Yes │
│ • Best for: Testing your code in │
│ isolation │
└─────────────────────────────────────────┘
Integrating with your test suite
Once you have a captured payload, the next step is shipping reliable webhook tests. Two patterns work well.
- Snapshot the payload, replay in unit tests Save the JSON body to fixtures/stripe-customer-created.json and feed it into your handler in a Vitest or Jest test. You get the real shape without depending on Stripe's network in CI.
import { handleStripeWebhook } from "../src/webhooks/stripe";
import fixture from "./fixtures/stripe-customer-created.json";
it("creates a local user when Stripe customer.created fires", async () => {
const res = await handleStripeWebhook({ headers: {}, body: fixture });
expect(res.status).toBe(200);
});
- End-to-end with Cypress or Playwright For signup-to-webhook flows, combine the inspector with YoBox Temp Mail. A worked example is in Cypress E2E with YoBox and Playwright Automation with YoBox.
When you do need ngrok
There is a clear moment to graduate from inspector to tunnel:
The provider requires a 2xx response within N seconds and you want to verify your handler meets the deadline.
You need to test idempotency by responding with a non-2xx and watching the provider retry.
You are debugging a signature verification function and need to feed it the raw, unmodified body your server receives.
For those, run ngrok http 3000 (or cloudflared tunnel) and point the provider at the tunnel URL. The inspector workflow has already taught you what to expect, so wiring the handler takes minutes instead of hours.
Provider-specific notes
Stripe
Use the Stripe CLI for local event triggering, but use YoBox when you want to see what production-shaped events look like (CLI events are slightly simplified). Verify signatures by capturing the Stripe-Signature header from a real event.
GitHub
GitHub webhooks include X-Hub-Signature-256 and a delivery ID. Capturing both lets you replay deliveries deterministically and write signature-verification tests against realistic data.
Clerk, Auth0, WorkOS
Auth providers send sensitive events (user.created, session.revoked). A disposable inspector URL keeps those payloads off any shared logging infrastructure during early integration work.
Shopify
Shopify retries aggressively. Inspecting payloads before writing your handler tells you exactly which topics are noisy and which deserve idempotency keys.
Key takeaways
Use a hosted inspector to understand a webhook; use a tunnel to handle it.
Capture real payloads early and freeze them as test fixtures.
Combine the Webhook Tester with Temp Mail for end-to-end auth flow debugging.
Graduate to ngrok or cloudflared only when you need the provider to see your response.
Real use cases
Auditing third-party providers before signing a contract
Before committing to a SaaS, point its webhook at YoBox and trigger every event type. You learn the real payload quality in fifteen minutes.
Debugging missing fields in production
When a payload field "sometimes" goes missing, ask the provider to copy a webhook to the inspector URL. Compare side-by-side with what your production logs captured.
Onboarding new engineers
Hand a junior engineer the inspector URL on day one. They learn the integration's vocabulary by watching live traffic, not by reading docs.
FAQ
Do I need an account?
No. The Webhook Tester generates a URL instantly with no signup.
How long does the URL stay alive?
As long as the tab is open. For longer captures, keep the tab pinned or rotate URLs daily.
Can I respond with a custom status code?
The hosted inspector returns 200. For custom responses, switch to a tunnel.
Is the payload stored anywhere?
Requests live in your browser session. There is no database backing the inspector.
What about HMAC signature verification?
Capture the signature header from a real request, then use it in your unit tests against the same body. See the Stripe and GitHub notes above.
A short checklist for new webhook integrations
Before writing a single line of handler code, run through this list. It takes ten minutes and saves hours.
[ ] Generate a fresh URL in the Webhook Tester.
[ ] Configure the provider to send to that URL.
[ ] Trigger every event type the provider supports — not just the one you care about today.
[ ] Inspect the headers: which ones are signed, which include a delivery ID, which include retry metadata.
[ ] Save at least one payload per event type as a JSON fixture in your repo.
[ ] Note the provider's retry policy (interval, max attempts, backoff).
[ ] Note the provider's timeout (often 5–10 seconds).
[ ] Decide on idempotency keys before you start coding.
That last point is the one most teams skip. Almost every webhook provider retries on non-2xx responses, and almost every handler is non-idempotent on day one. Designing the idempotency story up front — usually a unique constraint on the provider's event ID — prevents a class of bugs that are extremely painful to debug in production.
When the provider does not have a test event
Some providers (older billing systems, certain ERPs) cannot trigger test events on demand. In those cases, set up the inspector URL, run a real low-value action in the provider, and capture the payload. You only need one good fixture to start writing realistic tests.
Replaying captured webhooks against a local handler
Once you have ten or twenty real payloads saved as fixtures, you can replay them against your handler with a one-line curl loop. This is the closest thing to production traffic you can get without a tunnel, and it runs in CI for free. Pair this with the Postman testing guide for assertions on the response, and you have a webhook test pipeline that catches regressions before they reach staging.
Conclusion
ngrok is a great tool, but reaching for it on minute one of a new webhook integration is like firing up Docker to read a CSV. Most of the time you just want to see what the provider is sending. A hosted inspector like the YoBox Webhook Tester closes that loop in seconds, captures fixtures for your test suite, and stays out of your way until you are ready to write a real handler — at which point a tunnel is the right next step.
YoBox Team
Builder behind YoBox — a privacy-first toolbox for developers and QA engineers covering disposable email, webhook capture, regex, secure passwords, Docker, and end-to-end testing.
Top comments (0)