Webhooks
Outbound HTTP callbacks that push event notifications to external systems — covering payload signing, retry policies, at-least-once delivery, consumer idempotency, and webhook management platforms.
What it is
A webhook is an HTTP POST request sent by a provider to a consumer-specified URL when a triggering event occurs — a payment captured, a repository pushed to, a form submitted. Unlike polling (the consumer repeatedly asks "did anything change?"), webhooks invert the flow: the provider pushes a notification the moment the event happens. The consumer registers a callback URL during setup; the provider stores it and makes the HTTP call when needed. The payload is typically a JSON document describing the event. The consumer must respond with 2xx within a timeout (commonly 5–30 seconds) to acknowledge receipt. If the provider receives a non-2xx response or times out, it retries using an exponential backoff schedule.
Webhooks are the dominant integration mechanism for SaaS platforms: Stripe, GitHub, Shopify, Twilio, Slack, and hundreds of others expose webhooks as their primary real-time event delivery mechanism to third-party systems. They require no message broker infrastructure, just an HTTPS endpoint on the consumer side.
Why it exists
Before webhooks, integrators polled provider APIs on a schedule — every minute, every hour — wasting bandwidth, adding latency, and hammering APIs even when nothing changed. Webhooks replaced polling with push, reducing integration latency from O(poll interval) to near-real-time and eliminating wasted API calls. For SaaS providers, webhooks enable a platform ecosystem: any developer can subscribe to events and build integrations without the provider needing to know about them in advance, removing the need for bespoke integrations per customer.
When to use
- SaaS-to-SaaS integration — notifying a CRM when a payment completes, or triggering a CI build when code is pushed to a repository.
- Low-volume, event-driven notifications — events are infrequent and the consumer just needs to react, not process high-throughput streams.
- External system integration without shared infrastructure — the consumer cannot connect to your internal message broker; an HTTPS endpoint is the only viable interface.
- Customer-defined integrations — allowing customers or partners to subscribe to events from your platform and route them to their own systems.
When not to use
- High-throughput event streams — hundreds or thousands of events per second over webhooks become a thundering herd of HTTP calls; use a message broker or streaming platform instead.
- Internal service-to-service communication — internal services should communicate over a message broker or direct RPC; webhooks add HTTP overhead and endpoint management burden.
- When the consumer endpoint is unreliable or behind a firewall — if the consumer cannot expose a stable public HTTPS endpoint, webhooks won't work without a relay service (ngrok for development, Hookdeck or Svix for production).
Typical architecture
The consumer registers a URL and receives a shared secret. The provider stores both. On event, the provider constructs the JSON payload, computes HMAC-SHA256(secret, payload), includes the signature in a header (X-Signature-256: sha256=abc...), and POSTs to the URL. The consumer verifies the signature before processing. On non-2xx or timeout, the provider retries with exponential backoff (e.g., 5 s, 30 s, 2 min, 10 min). A webhook management service like Svix or Hookdeck sits between the provider and consumer to handle retries, fan-out, and observability.
Event occurs in Provider
│
▼
Webhook dispatcher
│ payload = JSON event
│ sig = HMAC-SHA256(secret, payload)
│ POST /webhook
│ Header: X-Signature-256: sha256={sig}
│
▼
Consumer HTTPS endpoint
│
├─ Verify signature (constant-time compare)
├─ Return 200 immediately
└─ Enqueue to internal queue for processing
│
[Worker processes event]
Retry schedule (on non-2xx or timeout):
5s → 30s → 2min → 10min → 1hr → 6hr → 24hr (then give up)
Pros and cons
Pros
- Simple integration — consumer just needs an HTTPS endpoint, no broker client libraries needed.
- Real-time delivery — events arrive within seconds of occurring, no polling lag.
- Push model — no wasted polling requests; provider calls only when something happens.
- Wide adoption — virtually every SaaS platform supports webhooks as a first-class feature.
- Easy customer extensibility — customers register their own URLs and own the integration logic.
Cons
- At-least-once delivery — providers retry on failure; consumers must be idempotent.
- Consumer must be publicly reachable — complicates development (use ngrok) and private deployments.
- No ordering guarantee between retried and new events — a retried event may arrive after a newer event.
- Operational management — tracking endpoint health, secret rotation, and delivery history across many subscribers requires dedicated tooling.
- Synchronous response required — consumer must respond within a timeout; long processing must be deferred to a background queue.
Implementation notes
Payload signing (HMAC-SHA256): Always sign webhook payloads and verify on receipt. The provider computes sig = HMAC-SHA256(shared_secret, raw_body_bytes) and sends it in a header. The consumer recomputes the signature and uses a constant-time comparison (e.g., hmac.compare_digest in Python) to prevent timing attacks. Never use string equality comparison for signatures. Include a timestamp in the signed payload and reject events with timestamps older than 5 minutes to prevent replay attacks.
Respond immediately, process asynchronously: The consumer endpoint should acknowledge receipt with 200 OK within 5 seconds, then push the payload to an internal queue for actual processing. Long-running processing risks timeout and spurious retries from the provider.
Idempotency: Store the event ID in a deduplification table with a TTL. Before processing, check if the event ID was already processed within the deduplication window. At-least-once delivery means the same event may arrive multiple times, especially after retries and during provider deployments.
Secret rotation: Support a rotation window where both the old and new secret are accepted simultaneously. This allows rotation without a blackout period. Invalidate the old secret after confirming deliveries are working with the new secret.
Webhook management platforms: Svix and Hookdeck provide webhook infrastructure as a service — reliable delivery, fan-out, per-endpoint rate limiting, retry management, event history, and test event replay. Use them if your platform needs to send webhooks to many customers reliably without building this infrastructure yourself.
Common failure modes
- Missing signature verification: Consumer accepts any POST without verifying the HMAC signature, allowing an attacker to forge events.
- Synchronous processing causing timeouts: Consumer processes the event in the request handler, exceeds the timeout, provider marks it a failure and retries — causing duplicate processing.
- No idempotency handling: Provider retries a successfully-delivered event (consumer returned 500 due to a downstream failure post-processing); duplicate side effects result.
- Endpoint URL hardcoded per environment: Webhook URL registered for staging receives production events during misconfiguration.
- Abandonment after max retries: Provider stops retrying; the consumer never receives the event and the integration silently stalls without an alert.
Decision checklist
- Is the webhook payload signed (HMAC-SHA256) and the signature verified with constant-time comparison?
- Does the endpoint respond with 2xx within 5 seconds, deferring processing to an internal queue?
- Are incoming webhook events deduplicated by event ID with a deduplication window?
- Is the shared secret rotatable with a dual-secret grace window?
- Is there an alert when the provider reports delivery failures for this endpoint?
- For high-volume providers or many subscribers: is a managed webhook platform (Svix, Hookdeck) justified?
Example use cases
- Payment confirmation: Stripe fires
payment_intent.succeededto the e-commerce platform's webhook endpoint; the platform upgrades the order to "paid" and queues fulfilment. - CI/CD trigger: GitHub fires a
pushwebhook to a CI platform on every commit; the CI platform queues a build job. - Customer integration hub: A SaaS platform allows enterprise customers to register webhook URLs for events like
user.createdandsubscription.cancelled, routing them to the customer's internal CRM.
Related patterns
- Event Notification — lightweight event broadcast, similar intent to webhooks but typically internal.
- Inbox Pattern — deduplicate at-least-once webhook deliveries safely.
- Correlation IDs — propagate event IDs across services to trace webhook-triggered processing.
Further reading
- Why Verify Webhook Signatures — Svix guide on signature verification.
- Stripe Webhooks Guide — canonical example of production-grade webhook design.
- Webhook Security Best Practices — Hookdeck comprehensive security guide.