API Styles Deep Dive · 6 of 7

Webhooks — Reverse APIs

A webhook flips the usual direction of an API call. You register a URL with a third party; when an event happens on their side, they POST a JSON payload to your URL. No polling, near-real-time delivery, and a pile of operational details that separate "works in dev" from "survives Black Friday."

HTTP CallbacksEvent NotificationsPushStripeGitHub
← Back to APIs & Networking
Quick Facts

What a Webhook Is

Basic Concepts

  • Direction: the third party is the client; you are the server. They call your URL when an event fires.
  • Transport: almost always POST with a JSON body, sometimes form-encoded for legacy providers.
  • Registration: you give the third party a URL and select which events to receive. Stripe, GitHub, Slack, Shopify, Twilio — all let you configure webhooks per resource.
  • Public URL required: the third party has to reach you. For local dev, use a tunnel (ngrok, cloudflared, localtunnel).
  • Delivery semantics: at-least-once. The same event will sometimes arrive twice. Build for that.
  • The third party retries: if you return non-2xx or time out, they back off and retry — usually for hours.
Why It Wins

What You Buy

No Polling

The alternative is calling GET /events?since=... every minute forever. That's expensive, rate-limit-prone, and slow to react. Webhooks turn it into push: you find out about a charge, push, build, or message within seconds of it happening.

Industry Standard

If you integrate with payments (Stripe, PayPal), source control (GitHub, GitLab), messaging (Slack, Twilio, Discord), CRMs, e-commerce (Shopify), or virtually any SaaS, webhooks are the integration mechanism. Knowing how to consume them well is a backend skill that pays off everywhere.

Build It Right

The Five Things to Get Right

1. Verify Signatures

Anyone on the internet can POST to your webhook URL. Without verification, you'll process forged events. Every reputable provider signs the body — Stripe uses an HMAC-SHA256 in the Stripe-Signature header; GitHub uses X-Hub-Signature-256; Slack uses X-Slack-Signature.

Compute the HMAC over the raw body (not the parsed JSON — whitespace and key order matter), compare with constant-time comparison, reject if it doesn't match. This is the line between "secure integration" and "anyone can mark any order paid."

2. Respond Fast

Most providers time out after a few seconds. Don't do real work in the webhook handler — accept it, persist the raw payload to a queue or DB, return 200 OK, then process asynchronously. Slow handlers cause retries, retries cause duplicates, duplicates cause double-charges.

3. Be Idempotent

The same event will arrive twice. Maybe ten times. The provider retried because your handler timed out, or your DB blip returned a 500. Use the event's unique ID (id, event_id, delivery_id) as a deduplication key — record it, refuse to process the same one twice. "Send a refund email twice" is annoying; "charge a card twice" is a phone call.

4. Plan for Out-of-Order Delivery

Webhooks aren't ordered. order.refunded can arrive before order.charged if the network reorders or one retried. Use the event payload's timestamps and resource IDs to reconcile state — when an event arrives, fetch the canonical resource state from the provider's REST API rather than trusting the webhook's snapshot.

5. Monitor and Alert

Most providers expose a webhook log in their dashboard with delivery success/failure. Wire alerts on:

  • Sustained 4xx/5xx responses from your endpoint.
  • Webhook latency creeping up.
  • Provider-side delivery backlog.
  • Signature verification failures (could indicate misconfig — or an attack).
When You're the Sender

Designing Webhooks for Others to Consume

The best practices for shipping webhooks are the inverse of consuming them:

  • Sign every payload with HMAC and a per-tenant secret rotated regularly.
  • Include a unique id on every event so consumers can dedupe.
  • Retry with exponential backoff on non-2xx responses — typically 3 days of retries is industry standard.
  • Provide an admin UI showing delivery attempts, status, and a "retry" button.
  • Document the event types and schemas with versioning. Add fields, never break.
  • Offer a webhook simulator / test event so consumers can wire it up without waiting for a real event.
  • Use a dedicated worker pool — webhook delivery shouldn't share resources with your synchronous API.
Decision

When to Pick Webhooks

Webhooks are the right answer when one system needs to tell another system that something happened — without making the second system poll. They're the standard for SaaS-to-customer notifications, partner integrations, and async confirmations across organizations.

Inside your own platform, prefer a real message broker (Kafka, RabbitMQ, SNS/SQS) — webhooks add HTTP overhead and rely on every consumer running a public endpoint. Webhooks shine across organizational and trust boundaries; brokers shine inside one.

Continue

Other API Styles