HookSteadBETA

How to test webhooks locally

Get real webhooks to the app on your laptop: tunnels, provider CLIs, replaying captured events, and what to check before you ship.

6 min read · Updated

The problem

Webhook providers need a public HTTPS URL. Your development server runs on localhost:3000, which nothing on the internet can reach. There are three good ways around that, and they work best together.

1. Use the provider's CLI, if it has one

Some providers ship a tool that receives events for you and forwards them to localhost. Stripe's CLI is the best known:

stripe listen --forward-to localhost:3000/api/webhooks/stripe
stripe trigger invoice.paid

stripe listen prints its own signing secret (whsec_…). Use that one locally: it is different from your dashboard endpoint's secret, and mixing them up is the most common cause of Stripe signature errors.

2. Open a tunnel

A tunnel gives your local port a temporary public URL. Popular options are cloudflared (cloudflared tunnel --url http://localhost:3000) and ngrok (ngrok http 3000). Paste the URL they print into the provider's webhook settings.

Tunnels are fine for development, but the URL changes when you restart them, and every restart means updating the provider. Never leave a tunnel pointing at a machine with real data.

3. Capture once, replay as often as you like

The fastest feedback loop is to record real events once and replay them against your handler while you change the code. That also lets you test the awkward cases: the event that arrived out of order, the payload with a missing field, the duplicate.

With HookStead:

  1. Point the provider at a HookStead source. Every event is stored, even before you have an endpoint.
  2. Start a tunnel to your machine and add its URL as a destination.
  3. Open any stored event in the dashboard and replay it to that destination, as often as you need. Each replay is signed fresh, so your local verification code is exercised too.
  4. When you're done, pause or delete that destination. The events stay, and production keeps working.

HookStead only delivers to public addresses (private and local IP ranges are blocked to prevent SSRF), so a tunnel is the way to reach your laptop.

What to test before you ship

  • Signature verification fails closed: a request with a wrong or missing signature gets a 400, and nothing happens.
  • The raw body reaches your verifier, not a parsed and re-serialized one. See Webhook security.
  • Duplicates are harmless: replay the same event twice and check that nothing is done twice. See Retries and idempotency.
  • Slow work happens in the background, and the handler answers in well under a second.
  • Unknown event types are ignored with a 2xx, so a new event type from the provider doesn't cause retries.

Next: set up your first source with the user guide, or read about what a webhook is.