How to Test Webhooks: The Complete Guide (2026)

A practical guide to testing webhooks: get an instant URL to inspect payloads, receive webhooks on localhost, replay requests, verify signatures, and test providers like Stripe and GitHub.

Webhooks are awkward to test for one simple reason: you don't control the sender, and your code usually runs on a machine the sender can't reach. A provider POSTs to a public URL on its schedule, with a payload shape you have to discover, and your handler is sitting on localhost.

This guide covers the practical ways to test webhooks — from "what is this payload?" to "does my handler work against real events?" — with tools you can use in the next five minutes.

What you actually need to test webhooks

  1. A public URL the provider can call.
  2. Visibility into the exact request (headers, body, query params).
  3. A way to get that request to your code — usually on localhost.

A webhook tester gives you the first two instantly. A tunnel or forwarding agent gives you the third.

Method 1: Inspect the payload with a webhook tester

Before you write a line of handler code, see what the provider actually sends. Open Webhook Bin — you get a unique URL immediately, no signup:

curl -X POST https://your-bin-url \
  -H 'Content-Type: application/json' \
  -d '{"event":"order.created","id":"ord_123"}'

The request shows up in real time with the full method, headers, query string and body. Point Stripe, GitHub, Shopify or any provider at the URL and trigger an event to capture a real payload you can build against.

Method 2: Receive webhooks on localhost

Once you know the shape, you want the webhook to hit your actual handler. Providers can't reach localhost, so run the relay agent and forward incoming webhooks to your local port:

# one-time
relay forward --bucket my-app http://localhost:8080/webhook

Now every webhook sent to your Webhook Relay endpoint is delivered to localhost:8080/webhook. The agent connects outbound, so there are no firewall ports to open, and the public URL is stable — set it once in the provider and keep developing. See the localhost forwarding docs for details.

Prefer a raw tunnel? Webhook Relay also offers general-purpose localhost tunnels if you just need to expose a port.

Method 3: Replay requests and fake responses

Two things make iterating fast:

  • Replay. Capture a request once, then resend it to your endpoint as many times as you like. You re-run your handler without re-triggering the source event (no need to create another Stripe payment to test the payment.succeeded path).
  • Custom responses. Configure the status code, body and delay your endpoint returns, so you can test how a provider reacts to a 500, a slow response, or a specific body.

Verify the signature while you're at it

Most providers sign webhooks with an HMAC so you can confirm authenticity. Test your verification logic with the free HMAC generator & signature verifier: paste the raw body, the secret and the signature header the provider sent, and confirm they match. GitHub uses X-Hub-Signature-256 (SHA256), Stripe and Shopify also use SHA256. See webhook security best practices for the full checklist.

Testing specific providers

The flow is the same for every provider — inspect, forward, replay — but each has its own quirks:

  • Stripe: use the dashboard's "Send test webhook" or the Stripe CLI, and point the endpoint at your Webhook Relay URL. Full walkthrough: receive Stripe webhooks on localhost.
  • GitHub: add the URL under Settings → Webhooks and use "Redeliver" to replay. See the GitHub + Jenkins guide.
  • Shopify / PayPal / Twilio: add the URL in the provider's webhook settings and trigger a test event.

Automated and CI testing

For repeatable tests, save a few captured payloads as fixtures and POST them at your handler in CI. Because Webhook Relay endpoints are stable and support transformations and filtering, you can also route only the events you care about to a test environment.

Common pitfalls

  • Responding too slowly or with the wrong status. Always return 2xx quickly; do heavy work asynchronously, or providers will retry.
  • Verifying against the parsed body. Sign and verify against the raw request body — re-serializing JSON changes bytes and breaks the signature.
  • Assuming ordering. Webhooks can arrive out of order; design handlers to be idempotent.
  • Hard-coding a tunnel URL that changes. Use a stable endpoint so you configure the provider once.

Start testing

Open Webhook Bin to inspect a request now, or create a free account to forward webhooks to localhost and replay them against your code.