Skip to content
← Notes

Webhooks

Sending, signing, retries, idempotency

  1. 00 Webhooks — Roadmap Ten chapters that go from 'webhooks are just HTTP POST requests' to a self-hosted, signed, retried, idempotent webhook system that survives the receiver being down for hours.
  2. 01 What webhooks are and when to use them A webhook is an HTTP POST you make to somebody else's server when something happens. The protocol is trivial; the failure modes are not.
  3. 02 Event contract design The shape of your event payload becomes a contract with everyone who integrates. The decisions you make in the first afternoon are the ones you live with for years.
  4. 03 Sending webhooks End-to-end producer in Go in sixty lines. By the end you have a binary that POSTs JSON to a URL, handles non-2xx, and times out cleanly. Signing, retries, and the outbox come later.
  5. 04 Signing payloads An unsigned webhook is a public POST endpoint. Anyone who guesses the URL can forge events. HMAC over a canonical string with a timestamp is the simple, correct fix.
  6. 05 Verifying signatures The receiver's job is to read the raw body, recompute the HMAC, compare in constant time, and reject events older than the replay window. Tiny code, easy to get wrong.
  7. 06 Retries and backoff A delivery that fails once is normal. A delivery that fails ten times in a hot loop takes down your service and your customer's. Exponential backoff with jitter and a hard deadline is the simple, correct fix.
  8. 07 Idempotency on the receiver At-least-once delivery means duplicates. The receiver's job is to process exactly once anyway. The inbox pattern — dedupe keys, atomic claim, idempotent side effects — is how.
  9. 08 Delivery guarantees and the dead-letter queue Some events never deliver. The dead-letter queue is where they go, the dashboard is where humans see them, and the manual replay is how you recover. None of these are optional.
  10. 09 Observability and replay Webhooks are not a fire-and-forget feature. They are an operated feature. The dashboards, metrics, and traces you build for debugging are the difference between a feature you maintain and one that maintains you.
  11. 10 Self-host The outbox pattern bridges your domain transactions and the webhook queue. The worker pool drains it. Behind nginx with TLS, on a VPS, with all the operational pieces from chapter 9 wired in.