Webhooks
A webhook inverts the usual direction of an API call. Instead of your service repeatedly asking another service "has anything happened yet?", you register a URL with that service once, and it sends an HTTP request to you the moment something actually happens — a payment clears, a file finishes uploading, a build completes. It's "don't call us, we'll call you," implemented as a plain HTTP POST.
Push instead of poll
Without webhooks, finding out about an event on another system means polling: repeatedly calling GET /payments/42 and checking the status field until it changes. This wastes requests (most of them return "still pending"), adds latency (you only find out as fast as your polling interval), and scales badly (checking on 10,000 in-flight payments means 10,000 repeated requests). A webhook flips this into a single push: the payment provider calls your endpoint exactly once, exactly when the status actually changes.
This is the same push-vs-pull idea covered generally in Push vs. Pull Architecture — a webhook is push architecture implemented as one plain HTTP callback, rather than a persistent connection like a WebSocket or a broker-mediated pub/sub topic. It's the lightest-weight of the three: no persistent connection to maintain, and no message broker to run — just a URL and an HTTP client on the sender's side.
The sender doesn't know if you got it
This is the core design problem webhooks introduce: a POST can fail to arrive, or your endpoint can be down, slow, or return an error when it does arrive — and the upstream service has no way to know your business logic actually succeeded beyond the HTTP status code you return. Two things follow directly from this:
- Retries are standard, which means duplicates are guaranteed eventually. A sensible webhook sender retries on timeout or a 5xx response, on the assumption that a failure might be transient — but that means your endpoint will receive the same event more than once sooner or later, whether from a genuine retry or the sender's own bug. Handling that safely means the receiving endpoint must be idempotent: processing the same event twice needs to produce the same result as processing it once, typically by tracking event IDs you've already handled and skipping repeats.
- The receiving endpoint needs to respond fast. A webhook handler is expected to return a
2xxquickly (queue the work and return, don't process synchronously) — a slow handler looks like a failure to the sender and triggers a retry, compounding the duplicate problem instead of avoiding it. The standard pattern is to durably enqueue the event (see Message Queues) and return200immediately, processing the actual business logic asynchronously off that queue.
Security: anyone can find your URL
A webhook endpoint is a public URL that accepts POST requests and triggers real side effects — which makes it an obvious target unless it verifies the request actually came from who it claims to. The standard defense is a signature header: the sender computes an HMAC of the request body using a shared secret and includes it in a header (e.g. X-Signature), and your endpoint recomputes that HMAC and rejects the request if it doesn't match, before processing anything. Skipping this check means anyone who discovers the URL can forge events — a subtle but real gap that's worth naming explicitly if webhooks come up in an interview.
Why this matters in an interview
Webhooks are a small, concrete pattern that packs in three ideas this module already covers: they're push architecture, they demand idempotent handling because delivery isn't exactly-once, and they need to be verified and processed asynchronously rather than trusted and handled inline. Naming all three when a design involves "service A needs to notify service B" is a stronger answer than just saying "we'll use a webhook."
Webhooks vs. polling for cross-service notifications: pros and cons
Pros
- Near-instant notification instead of waiting for the next poll interval
- No wasted requests checking a status that hasn't changed
- Simple to implement — just an HTTP endpoint, no persistent connection or broker needed
Cons
- Delivery isn't guaranteed exactly-once — receivers must handle duplicates idempotently
- The sender needs its own retry and dead-letter strategy for endpoints that are down
- Requires signature verification to avoid accepting forged events from a public URL
Further Reading
- Stripe — Webhooks overview — a production webhook implementation covering retries, signature verification, and idempotent handling in practice.
- Svix — Webhooks: The Definitive Guide — a vendor-neutral guide to designing and consuming webhooks reliably.
Saved locally in your browser — visible in the sidebar as you go.