Webhooks Cheat Sheet
Webhook concepts, payload formats, signatures, retries, security, and local testing patterns.
Web & Network
webhook
api
callback
A webhook is an HTTP callback: a provider POSTs an event payload to your URL in real time. Unlike polling, the server pushes data to you, so your endpoint must be reliable, fast, and verifiable.
Anatomy of a webhook
code
POST /hooks/payment HTTP/1.1
Host: api.example.com
Content-Type: application/json
X-Signature: sha256=8f3a...
{ "event": "payment.succeeded", "data": { "id": "pi_123" } }
Table
| Component | Purpose |
|---|---|
| Endpoint URL | Your public HTTPS route. |
| Event type | What happened (e.g. payment.succeeded). |
| Payload | JSON body with event data. |
| Signature header | HMAC proof the request came from the provider. |
Verifying signatures (HMAC)
js
const crypto = require("crypto");
const expected = crypto
.createHmac("sha256", process.env.WEBHOOK_SECRET)
.update(rawBody)
.digest("hex");
const received = req.headers["x-signature"];
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received))) {
throw new Error("Invalid signature");
}
Reliability and idempotency
Table
| Practice | Why |
|---|---|
Respond 2xx quickly | Providers retry on non-2xx or timeout. |
| Process async | Decouple receipt from work. |
| Store event IDs | Deduplicate retries (idempotency). |
| Order by timestamp | Handle out-of-order delivery. |
| Verify signature first | Never trust the payload blindly. |
Local testing
Expose a local server with a tunnel, then point the provider at it.
bash
ngrok http 3000
# or
cloudflared tunnel --url http://localhost:3000