Webhooks, explained properly
What they are, what breaks, and the vocabulary that shows up in every provider's documentation. Written by people who run a delivery pipeline, not as a definition to rank for.
In short
- A webhook is an HTTP POST from the system that knows something to the system that wants to know.
- The hard parts are not the request: retries, signatures, ordering, idempotency and visibility are.
- A signature proves origin and integrity; the delivery id is what stops double-processing.
- Anything undeliverable should be kept and replayable, never dropped.
The vocabulary
| Term | What it means |
|---|---|
| Event | The thing that happened, with a type and a payload. Published once, delivered many times |
| Endpoint / destination | A URL belonging to a consumer, usually one of your customers |
| Fan-out | Turning one event into one delivery per subscribed endpoint |
| Attempt | A single HTTP request to a destination, with a status and a latency |
| Retry schedule | The intervals between attempts after a failure, usually widening |
| Dead letter | A delivery whose schedule is spent, kept for inspection and replay |
| Circuit breaker | Automatically disabling a destination that keeps failing |
| Signature | An HMAC over the raw body, proving origin and integrity |
| Idempotency key | A stable id that lets the receiver ignore something it has already handled |
| Replay | Sending a stored event again, deliberately |
The problems, one page each
Each guide is written against a real implementation, with code you can run.
Your first delivery
Account, destination, publish, and the timeline that proves it arrived.
Verifying webhook signatures
The three headers, a verification function, and the mistake everyone makes once.
Retries and idempotency
What a retry preserves, and how a consumer stops processing the same event twice.
Dead letters and recovery
What happens when the schedule is spent, and how to get the events back.
Testing webhooks
How to exercise a consumer without waiting for real traffic.
Debugging a failing delivery
Reading the timeline: what each status code usually means and what to do about it.
Webhooks and SSRF
Why a delivery service is an SSRF machine by construction, and how to contain it.
Receiving from a platform
Verification differs per provider. These pages give the exact header and scheme for each.
GitHub
Repository, organisation and app events, verified with the signature GitHub already sends.
Shopify
Orders, products, customers and app lifecycle events, verified with Shopify’s own HMAC.
Stripe
Payment, subscription and payout events, with the timestamp tolerance Stripe specifies.
Standard Webhooks
Anything on the open Standard Webhooks specification, including Svix-sent traffic.
Alibaba Cloud EventBridge
CloudEvents pushed from an EventBridge HTTPS target, authenticated by a header token.
Auth0
Log-stream and tenant events, authenticated by a header token.
Questions
What is a webhook?
A webhook is an HTTP request one system sends to another to say that something happened. Instead of the receiver asking "anything new?" on a timer, the sender posts the event as soon as it occurs. It is a push, and the receiver is an ordinary HTTP endpoint.
What is the difference between a webhook and an API call?
Direction and who starts it. An API call is made by the party that wants something; a webhook is made by the party that knows something. The mechanics are identical — both are HTTP requests — which is why the hard parts of webhooks are not the request but everything around it: retries, ordering, signatures and knowing what happened.
Why do webhooks need signatures?
Because the endpoint receiving them is public. Anyone can post JSON to it. A signature lets the receiver prove the body came from the sender that holds the shared secret and was not modified on the way, which is the difference between a webhook and a form anyone can fill.
How many times should a webhook be retried?
Enough to cross a deploy or a short outage, and not so many that a dead endpoint is hammered for a week. A schedule that starts in seconds and widens to hours, spanning roughly a day, covers the overwhelming majority of real failures. What matters more than the count is that unretryable failures stop early and that whatever is finally undeliverable is kept.
What is a dead-letter queue?
Where a delivery goes when its retry schedule is exhausted. The alternative is dropping it, which turns a delivery problem into missing data that nobody can reconstruct. A dead letter should be inspectable and replayable once the destination is fixed.
Should I build webhooks myself?
The first version is a table and a background job, and it works. What accumulates after that is the reason services exist: per-destination rate limits, circuit breakers, signature rotation, replay, a queue that cannot be trusted alone, and a support surface for customers asking "did you send it?". Build it if delivery is your product. Otherwise it is plumbing that never stops asking for attention.