Back to Blog
April 8, 2026Developer

Testing Webhooks: A Developer Guide

A practical guide to testing webhook endpoints, structuring payload headers, securing webhooks with HMAC signatures, and debugging CORS issues.

Webhooks are the backbone of real-time communication between services. Instead of polling an API every few seconds, a webhook lets one server push data to another the moment something happens — a payment is completed, a commit is pushed, or a form is submitted. For developers building integrations, knowing how to test webhooks locally and in staging environments is an essential skill.

What Makes Webhook Testing Hard

Unlike a standard REST API call that you initiate from your code, a webhook requires the sending server to reach your endpoint. During local development, your machine is not publicly accessible on the internet. This means the sending service cannot deliver the payload to localhost:3000. You also need to simulate the exact headers, signature format, and JSON structure that the real service sends, otherwise your handler logic will fail silently.

Tools for Local Webhook Testing

Several tools bridge the gap between localhost and the public internet. ngrok creates a secure tunnel to your local server and provides a public HTTPS URL. Cloudflare Tunnel offers a similar capability integrated with the Cloudflare network. localtunnel is a lightweight open-source alternative. Each of these tools forwards incoming webhook requests to your local development server, letting you debug the full request-response cycle without deploying.

Securing Webhooks with HMAC Signatures

A webhook endpoint exposed to the internet can receive requests from anyone. To verify that a request truly comes from the expected sender, production webhooks use HMAC (Hash-based Message Authentication Code) signatures. The sending server computes a hash of the payload body using a shared secret and includes it in a header such as X-Hub-Signature-256 (GitHub) or Stripe-Signature (Stripe). Your server must recompute the hash and compare it to the header value. If they do not match, reject the request. Never trust webhook data without verifying the signature first.

Handling CORS in Browser-Based Testing

When testing webhooks from a browser-based tool, CORS (Cross-Origin Resource Sharing) becomes an obstacle. Browsers enforce a policy that blocks responses from servers that do not explicitly allow your origin via the Access-Control-Allow-Origin header. Most production webhook endpoints are designed to receive requests from backend servers, not browsers, so they do not set this header. To work around this, route your test requests through a server-side proxy or use our cURL command export to test from your terminal instead.

Ready to test your webhooks?

Open Webhook Tester