Idempotency
Safely retry webhook requests without creating duplicates.
What is Idempotency?
An idempotent operation produces the same result whether it's executed once or multiple times. For webhooks, this means if you accidentally send the same webhook twice, only one delivery is created.
This is critical for handling network failures โ if you don't receive a response, you can safely retry without worrying about duplicate deliveries.
Idempotency Keys
Pass an Idempotency-Key header with your webhook requests:
curl -X POST https://hooksniff-api-1046140057667.europe-west1.run.app/v1/webhooks \
-H "Authorization: Bearer hr_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: unique-order-12345-created" \
-d '{
"endpoint_id": "ep_abc123",
"event": "order.created",
"data": {"order_id": "12345", "total": 99.99}
}'The key should be a unique string per logical operation. Common patterns:
order-{id}-createdโ For order eventspayment-{id}-succeededโ For payment eventsuser-{id}-signup-{timestamp}โ For user events
How HookSniff Handles Duplicates
When you include an idempotency key:
- 1. HookSniff checks if a webhook with the same key was already processed
- 2. If found, the cached response is returned immediately (same delivery ID)
- 3. If not found, the webhook is processed normally and the key is stored
- 4. Keys are retained for 24 hours after the initial request
// First request โ creates a delivery
POST /v1/webhooks
Idempotency-Key: order-12345-created
โ 200 { "id": "wh_abc123", "status": "pending" }
// Second request with same key โ returns cached response
POST /v1/webhooks
Idempotency-Key: order-12345-created
โ 200 { "id": "wh_abc123", "status": "pending" } // Same response!
// Different key โ creates a new delivery
POST /v1/webhooks
Idempotency-Key: order-12345-updated
โ 200 { "id": "wh_def456", "status": "pending" }Best Practices
- Always use idempotency keys for critical webhooks (payments, orders)
- Generate keys from your business logic, not random UUIDs
- Include the event type in the key to avoid collisions across event types
- Retry with the same idempotency key on network failures
- Keys expire after 24 hours โ you can safely reuse them after that