Need the #1 custom application developer in Brisbane?Click here →

Webhooks: Event-Driven Integrations

9 min read

Webhooks are HTTP callbacks. Instead of your system polling an external service asking "has anything changed?", the external service sends a POST request to your URL when something happens. Event-driven rather than pull-based.

Webhooks vs Polling

Polling: your system queries an API every N minutes. "Has anyone paid?" "Did the email send?" "Has the order shipped?" If nothing changed, you've wasted an API call and received no useful data.

Webhooks: the service calls you when something happens. You're notified immediately. No wasted API calls. Real-time or near-real-time updates.

Webhooks are more efficient, have lower latency, and scale better. They're the right pattern for integrations.

Webhook Use Cases

Stripe sends a webhook when a payment succeeds. GitHub sends a webhook when code is pushed. Twilio sends a webhook when an SMS is received. Payment providers, code hosts, communication platforms—all use webhooks for integration.

Your application needs a public HTTPS endpoint that can receive POST requests. When an event happens, the service sends a POST to that endpoint with data about the event.

Receiving Webhooks

Define an endpoint: POST /api/webhooks/stripe. When Stripe has an event for you, it sends a POST request to that URL with JSON data describing the event.

Your endpoint must be public and reachable over HTTPS. For development, use ngrok—it exposes your local server via a public URL, allowing you to test webhooks locally.

Verifying Webhook Signatures

Anyone with your webhook URL can send requests to it. How do you know the request came from the claimed service and not an attacker?

Services include a signature in webhook requests. Stripe includes an X-Stripe-Signature header. You use the service's public key and the request body to verify the signature. Only a request signed with Stripe's private key will verify correctly.

Always verify signatures. A webhook without signature verification is vulnerable to spoofed events.

Idempotency

Services may deliver the same webhook multiple times. Network errors, timeouts, retries—a webhook might be delivered twice. Your system must handle this gracefully.

Design webhook handlers to be idempotent. Processing the same webhook twice should have the same effect as processing it once. Use the webhook's unique ID to detect and skip duplicate deliveries.

Responding Quickly

Return a 200 OK response immediately. Don't do expensive work inside the webhook handler. Do that in a background job.

Services retry on non-2xx responses. If your webhook handler takes 10 seconds, the service might timeout and retry. Return 200 immediately, queue the work, and process it asynchronously.

Webhook Delivery Failures

If your endpoint returns non-2xx, the service retries. Usually exponential backoff: immediately, 5 seconds, 30 seconds, 5 minutes, 30 minutes, hours. After N retries, the service gives up.

Make webhook endpoints robust. Handle errors gracefully. Return 200 when you've queued the work, even if processing will fail.

Debugging Webhooks

Services provide webhook logs. Stripe shows every webhook sent, whether it succeeded, and what the response was. Use these logs to debug issues.

For development, ngrok logs show the HTTP requests and responses. Use these to verify signatures and response handling work locally.

Webhook Payload Structure

Different services structure webhook payloads differently. Stripe sends event objects with type, data, and metadata. GitHub sends push events with repository and commit info. Read the documentation for each service to understand the structure.

Validate the payload structure. If a field you expect is missing or has the wrong type, log it and alert. Don't assume the payload is as documented.

Processing Webhooks Safely

Webhook handlers should be simple. Verify the signature. Validate the payload. Queue the work. Return 200. All processing happens in background jobs where errors can be handled and retried.

Use a job queue (Bull, Celery, Sidekiq). This decouples webhook receipt from processing. If processing fails, retry.

Warning
Always verify webhook signatures. A webhook without signature verification is a critical security vulnerability. An attacker can spoof events to your system.
Tip
Use ngrok during development to test webhooks locally. It's invaluable for debugging integration issues before deploying to staging or production.