Implementing Webhooks

1. Designing Webhook Payload Structure

Example: Webhook Payload

{
  "id": "evt_abc123",
  "type": "order.completed",
  "createdAt": "2026-05-15T10:30:00Z",
  "apiVersion": "2026-01-01",
  "data": {
    "orderId": 100,
    "amount": 250.00,
    "currency": "USD"
  }
}
FieldPurpose
idUnique event ID for dedup
typeEvent name (dot-notation)
createdAtEvent time
apiVersionSchema version
dataEvent payload

2. Implementing Webhook Registration

Example: Register Webhook

POST /webhooks
{
  "url": "https://client.example.com/hooks",
  "events": ["order.created", "order.completed"],
  "secret": "auto-generated-or-client-supplied",
  "active": true
}

3. Implementing Event Filtering

Filter TypeExample
Event typeevents: ["order.*"]
Resource attributesfilter: {currency: "USD"}
Account scopePer-tenant subscriptions

4. Securing Webhooks

MechanismImplementation
HMAC signatureHeader: X-Signature: sha256=...
Timestamp + replay windowReject if >5 min old
HTTPS onlyReject http:// URLs at registration
IP allowlistOptional second factor
mTLSMutual cert auth (enterprise)

Example: HMAC Verification (Java)

String expected = "sha256=" + hmacSha256(payload, secret);
if (!MessageDigest.isEqual(
        expected.getBytes(),
        request.getHeader("X-Signature").getBytes())) {
    return ResponseEntity.status(401).build();
}

5. Implementing Retry Logic

SettingTypical
Max attempts5-10
Success2xx within 30s
Retry on5xx, 408, 429, network errors
Skip on4xx (except 408, 429)

6. Using Exponential Backoff

AttemptDelay
1Immediate
21 min
35 min
430 min
52 hours
6+Up to 24 hours
Note: Add jitter (±20%) to avoid thundering herd.

7. Implementing Webhook Timeouts

SettingValue
Connection timeout5s
Read timeout30s (Stripe), 10s (GitHub)
Total budgetDocument explicitly

8. Providing Webhook Logs

Log FieldContent
Event IDUnique event reference
Endpoint URLTarget hook URL
AttemptsEach attempt with status, latency
Response bodyFirst N bytes for debugging
Replay actionManual replay button

9. Implementing Webhook Deactivation

TriggerAction
N consecutive failuresAuto-disable after N (e.g. 50)
Email notificationAlert webhook owner
Manual disablePATCH /webhooks/{id} {active:false}

10. Testing Webhooks

ToolUse
ngrok / localtunnelExpose local dev to public URL
RequestBin / BeeceptorInspect incoming hooks
Webhook test endpointPOST /webhooks/{id}/test sends sample event
Stripe CLIForward live events to localhost

11. Documenting Webhook Events

Per EventDocument
Event type nameorder.completed
When firedTrigger condition
Payload schemaJSON Schema or example
IdempotencyUse event id for dedup
OrderingNOT guaranteed across events