Managing Webhooks
1. Configuring Webhook Endpoints
| Property | Recommendation |
|---|---|
| URL | HTTPS only, public reachable |
| Method | POST |
| Body | JSON event payload |
| Response | 2xx within 5s = ack |
| Idempotency | Process by event_id |
2. Implementing Webhook Signatures
Example: HMAC signature header
POST /webhooks HTTP/1.1
X-Webhook-Id: evt_abc123
X-Webhook-Timestamp: 1716000000
X-Webhook-Signature: sha256=hex(hmac_sha256(secret, timestamp + "." + body))
{"type": "payment.succeeded", "data": {...}}
| Check | Required |
|---|---|
| Constant-time compare | Avoid timing attacks |
| Timestamp window | ± 5 min skew |
| Replay cache | Reject duplicate event_id |
| Secret rotation | Support multiple active secrets |
3. Implementing Webhook Authentication
| Method | Detail |
|---|---|
| HMAC signature | Preferred (shared secret) |
| mTLS | Strong, requires cert mgmt |
| Bearer token | Static or short-lived JWT |
| Basic auth | Simple, HTTPS only |
| IP allowlist | Defense in depth |
4. Setting Retry Policies for Webhooks
| Provider | Retry Schedule |
|---|---|
| Stripe | 3d exponential |
| GitHub | 8h up to 8 retries |
| Recommended | 1m, 5m, 30m, 2h, 12h, 24h, 48h, 72h |
| Retry on | 5xx, timeouts, connection errors |
| Stop on | 410 Gone, 401 invalid signature |
5. Configuring Webhook Timeouts
| Timeout | Typical |
|---|---|
| Connect | 3s |
| Read (response) | 5-10s |
| Total deadline | 15s |
| After: treat as failure | Schedule retry |
6. Using Webhook Event Filtering
Example: Subscribe to specific events
{
"url": "https://app.example.com/hook",
"secret": "whsec_...",
"events": ["payment.succeeded", "payment.failed", "refund.created"],
"api_version": "2026-05-15"
}
7. Implementing Webhook Delivery Logs
| Field | Purpose |
|---|---|
| event_id | Identify event |
| endpoint_url | Destination |
| attempt_number | Retry tracking |
| status_code | Receiver response |
| latency_ms | Performance |
| next_retry_at | Schedule |
| request/response body | Debug |
8. Setting Up Webhook Testing
| Tool | Use |
|---|---|
CLI stripe trigger | Send test events |
| ngrok/Cloudflare Tunnel | Expose localhost |
| webhook.site | Inspect payloads |
| Replay endpoint | Re-deliver past events |
9. Configuring Webhook Rate Limiting
| Limit | Reason |
|---|---|
| Per-endpoint concurrency | Avoid overwhelming receiver |
| Per-account RPS | Fair share |
| Burst allowance | Handle event bursts |
| Back off on 429 | Honor Retry-After |
10. Using Webhook Payload Transformation
| Transformation | Use Case |
|---|---|
| Field renaming | Match receiver schema |
| Field stripping | Remove PII per receiver |
| Format conversion | JSON → XML for legacy |
| Template injection | Customer-specific wrapping |