Webhooks & Events

Testing Webhooks Locally

You cannot wait for real events to test a receiver. Tunnels, mocks, and replays let you iterate on your laptop.

What you'll learn

  • Expose a local endpoint so a provider can reach it
  • Simulate deliveries without depending on real events
  • Test verification, idempotency, and failure paths
  • Capture real payloads as fixtures for repeatable tests

6 min read

The local development gap

Webhooks present an awkward problem for everyday development. The provider needs to reach a public URL, but your code is running on a laptop tucked behind a firewall with no public address of its own. On top of that, you really do not want to keep triggering real events over and over in some upstream system just to exercise the handler you are working on. Both of these obstacles, fortunately, have practical and well-worn workarounds.

The goal you are aiming for is a fast feedback loop: fire a delivery at your local receiver on demand, inspect exactly what it does with a debugger attached, change the code, and try again — all without deploying anything or waiting for the real world to happen to produce a suitable event. Get that loop tight and webhook development stops being painful.

Tunnelling to your machine

A tunnelling tool exposes a port on your machine through a temporary public URL and forwards any incoming requests straight to your local server. You register that public URL as the webhook endpoint with the provider, and then real or test deliveries arrive directly in your running code, where you can set breakpoints and step through them just as you would any other request.

This lets you exercise the genuine path end to end, including signature verification against the provider's real headers rather than ones you guessed at. Remember that the tunnel URL is ephemeral and will change, so point the provider back at your properly deployed endpoint once you are done testing. Check the developer portal for any sandbox or test-mode guidance that makes this easier.

Simulating deliveries

For tighter, fully dependency-free tests, the simplest approach is to send the requests yourself. Craft a representative payload by hand and POST it directly to your endpoint with a tool like curl or a test HTTP client in your test suite. This runs entirely offline, needs no tunnel, and is ideal for the unit and integration tests you want running fast on every change and in continuous integration.

curl -X POST http://localhost:3000/hooks \
  -H 'Content-Type: application/json' \
  -d '{"id":"evt_test","type":"resource.updated"}'

Simulating deliveries this way lets you deliberately exercise the awkward cases on demand — duplicate events, unknown event types, malformed bodies — that you would otherwise have to wait and hope to see arrive naturally from a real provider.

Fixtures and edge cases

Capture a few real deliveries once, when you do have access to genuine events, and save them as fixtures — stored sample payloads you can replay in tests as often as you like. Real captured fixtures keep your tests honest, because they match the exact shape the provider actually sends rather than the slightly idealised shape you might imagine it sends from reading the docs.

Use those fixtures to cover the specific paths that tend to bite in production: a valid signature and an invalid one, a duplicate event id, and a pair of events that arrive out of order. Testing verification and idempotency thoroughly on your laptop, exactly as described in verifying webhook signatures, catches a great many bugs long before they ever have a chance to reach production traffic.

Key takeaways

  • A tunnelling tool gives the provider a public URL to your laptop
  • POST crafted payloads yourself for fast, offline tests
  • Deliberately test duplicates, bad signatures, and malformed bodies
  • Save real deliveries as fixtures for repeatable, honest tests

FAQ

How can a provider reach my local machine?

Use a tunnelling tool that creates a temporary public URL forwarding to your local port. Register that URL as the endpoint and deliveries arrive in your running code.

How do I test without triggering real events?

Send the requests yourself. POST a representative payload to your endpoint with curl or a test client, which runs offline and lets you control exactly what arrives.

What should local webhook tests cover?

The edge cases: valid and invalid signatures, duplicate event ids, unknown event types, and malformed bodies. Real captured fixtures keep those tests faithful to production.

Integrate with Merion

Ready to build?

Read the API reference, grab the OpenAPI spec, and ship a resilient integration.