Webhooks are deceptively simple looking — just an HTTP endpoint that receives POST requests. But production webhook handlers need signature verification, idempotency, and often async processing. Claude Code gets all of these right when you specify them.
The baseline webhook prompt
Build a webhook handler for [service] events. Requirements:
Security:
- Verify the webhook signature using [service's method]
- Return 401 immediately if signature fails
- Return 200 immediately after signature verification (before processing)
Reliability:
- Idempotent: same event ID should be processed at most once
- Store event ID in webhook_events table to track processed events
- If an event with the same ID arrives twice, return 200 without reprocessing
Processing:
- Handle these event types: [list]
- Unknown event types: log and return 200 (don't fail)
- If processing fails: log error, return 200 (don't retry storms)
Here's the [service] webhook documentation: [paste or link]
The "return 200 before processing" is critical. If you return 200 only after processing, a slow or failing handler causes the sender to retry — which can cause duplicate processing or retry storms.
Signature verification
Don't let Claude guess at signature verification — different services do it differently:
Implement signature verification for [service].
Their method: [HMAC-SHA256/RSA/etc]
Header name: [X-Service-Signature or whatever]
Signing key: from env var [KEY_NAME]
Read the raw body before parsing — signature verification
must use the raw bytes, not the parsed JSON.
The "raw body before parsing" part is the common mistake. Most frameworks read and parse the body automatically. Signature verification needs the raw bytes, so you have to intercept before the parser.
Async processing
The webhook handler should:
1. Verify signature
2. Store event in webhook_events table
3. Return 200 immediately
4. Process event asynchronously via [queue/worker]
The async processor should:
- Retry on transient failures (network, temporary DB errors)
- Give up after [N] retries
- Move to dead letter queue after max retries
- Log all retries and final disposition
Testing webhook handlers
Write tests for this webhook handler. Test:
- Valid signature: handler processes event
- Invalid signature: returns 401, no processing
- Duplicate event ID: returns 200, no reprocessing
- Unknown event type: returns 200, logged
- Valid event of each type: correct processing
- Malformed payload: returns 400, logged
Provide test utilities for generating valid/invalid signatures.
The test utilities for generating signatures are worth asking for separately. Without them, writing webhook tests is painful because you have to manually compute HMACs.
Webhook replay and debugging
Add a replay endpoint for debugging. It should:
- Accept an event ID
- Retrieve the stored event from webhook_events
- Reprocess it (skip idempotency check for replay)
- Require admin auth
- Log that it's a replay, not an original event
Replay is invaluable when a bug in processing caused events to fail silently. You fix the bug and replay the affected events instead of asking the sender to resend.
Webhook patterns — signature verification, idempotency, async processing, testing — are in the Agent Prompt Playbook. $29.