A webhook is an HTTP callback that an external service sends to your application when an event occurs. Rather than polling for updates, you give the service a URL and it sends a POST request to that URL whenever something happens. Stripe sends webhooks on payment events. GitHub sends webhooks on repository events. Shopify sends webhooks on order events.
How Webhooks Differ from APIs
With a regular API, your application makes a request and receives a response. The flow is pull-based: you pull data when you need it.
With webhooks, the external service makes a request to your application. The flow is push-based: the service pushes data to you when something happens. This is much more efficient for time-sensitive events because you receive the notification immediately rather than after your next polling interval.
The Webhook Delivery Process
When the triggering event occurs, the webhook sender constructs an HTTP POST request. The request body is a JSON payload describing the event. The sender includes a signature header (a hash of the payload computed with a shared secret) so your application can verify the request is authentic. The sender delivers the request to your endpoint URL.
Your endpoint should respond with a 2xx status code within a few seconds. If your endpoint takes too long or returns a non-2xx status, most webhook systems retry the delivery (often with exponential backoff) for several hours or days.
The Development Challenge
Webhooks need a publicly accessible URL to deliver to. During local development, your application runs on localhost, which is not accessible from the internet. Solutions include:
Using a tunnel service like ngrok that creates a public URL that tunnels to your localhost port.
Using a webhook test tool like the DevHexLab Webhook Tester that provides a unique public URL, receives webhooks, and displays the payloads so you can inspect them without running any local server.
Using the webhook service's built-in test delivery feature to send sample payloads.
Using the DevHexLab Webhook Tester
Open the tool at /tools/network/webhook-tester. A unique URL is generated for your session. Copy it and configure it as your webhook endpoint in the external service. Trigger the webhook by performing the event (a test payment, a repository push, a new order). The incoming request appears in the tool with the full headers and body. Inspect the payload to understand the data structure.
Frequently Asked Questions
How do I verify webhook authenticity?
Most webhook providers include a signature in a header (like Stripe-Signature or X-Hub-Signature). Your endpoint computes the expected signature using the payload body and the shared secret, then compares it to the provided signature. Reject requests where the signatures do not match.
What if my endpoint is down when a webhook arrives?
Implement a webhook retry mechanism on your side by processing deliveries asynchronously. Store incoming webhook payloads in a queue and process them even if your handler is temporarily unavailable. Most providers also retry failed deliveries.
Test webhooks early in development before writing the handler logic.