Every API covered so far waits for a client to ask. A webhook flips the direction entirely — the provider calls a URL the consumer registered, the moment something actually happens — and that direction change introduces problems neither REST, GraphQL, nor gRPC need to solve.
3 min read
Without webhooks, finding out "has this payment finished processing yet" means polling — repeatedly calling an endpoint to check, wasting requests on every check that comes back "still pending" and introducing real delay between the actual event and the client noticing it. A webhook inverts this: the consumer registers a URL upfront, and the provider makes an HTTP request to that URL the instant the relevant event actually happens — the same underlying idea as System Design's payments lesson describing why a payment webhook, not a browser redirect, is the real source of truth for whether a charge succeeded.
This reversal creates real problems neither side has to think about when they're the one initiating a normal API call:
A webhook payload faces a real trade-off: including the full resource object saves the consumer a follow-up API call, but makes the payload larger and means the provider commits to a stable shape for every event type indefinitely. A common middle ground sends a lightweight event (the event type, the resource ID, a timestamp) and lets the consumer fetch full details via a normal API call only when it actually needs them — trading one extra request for a smaller, more stable webhook contract.
A webhook handler that does slow, heavy processing (updating a database,
sending emails) before responding risks the provider's delivery timing out
and retrying — producing an unnecessary duplicate delivery for work that
was actually already in progress. The standard pattern: acknowledge
receipt immediately (200 OK, as fast as possible) after minimal
validation, then hand the actual processing off to a background job —
directly connecting to lesson 12's long-running-operation patterns.
Even a well-designed webhook system typically keeps a polling endpoint available as a fallback — a webhook delivery can still be missed entirely (a misconfigured URL, an extended outage past the retry window), and a consumer that only ever relies on webhooks with no way to reconcile state periodically has no way to detect or recover from that silent gap.
Check your understanding
A quick comprehension check — not tracked, not graded, just for you.
1. How does a webhook fundamentally differ from a normal API call?
2. Why must a webhook consumer verify a request's signature before trusting its payload?
3. Why must webhook handlers be designed to be idempotent?
API Design