Core Concepts
Before diving into the API, understand the building blocks of HookSniff. These concepts are the foundation for everything else.
Why These Concepts Matter
Webhook systems look simple on the surface — just send an HTTP POST. But in production, you quickly run into questions:
- What happens when the receiver's server is down?
- How do you prove the webhook really came from you?
- How do you handle thousands of webhooks without overwhelming the receiver?
- How do you debug when something goes wrong?
HookSniff's core concepts solve each of these problems. Here's how they fit together.
Endpoints
An endpoint is a URL where HookSniff delivers webhooks. Think of it as a mailing address for your webhooks.
Why endpoints matter: Instead of hardcoding URLs in your application, you register endpoints in HookSniff. This lets you change the destination without code changes, add event filters, and track delivery health per destination.
Each endpoint has:
- URL — The target that receives webhook POST requests
- Signing secret — HMAC-SHA256 secret for payload verification (whsec_ prefix)
- Event filter — Optional: only deliver specific event types (e.g., order.*)
- Status — Active or inactive; inactive endpoints skip delivery
- Retry policy — Custom retry behavior per endpoint
{
"id": "ep_abc123",
"url": "https://myapp.com/webhook",
"description": "Order notifications",
"signing_secret": "whsec_abc123xyz789...",
"is_active": true,
"event_filter": "order.*",
"created_at": "2026-01-15T10:30:00Z"
}Webhooks & Deliveries
A webhook is an event you send via the API. A delivery is HookSniff's attempt to deliver that webhook to an endpoint.
The distinction matters: One webhook can have multiple deliveries (retries, multiple endpoints). Each delivery is tracked independently with its own status, attempts, and timing.
- Event types — String identifiers like order.created, user.updated
- Payloads — JSON data sent as the request body
- Delivery status — pending, delivered, or failed
- Attempt tracking — Each delivery attempt is recorded with status code, response body, and duration
- Idempotency — Use the Idempotency-Key header to prevent duplicate deliveries
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" \
-d '{
"endpoint_id": "ep_abc123",
"event": "order.created",
"data": { "order_id": "12345", "total": 99.99 }
}'Retries
The problem: Servers go down, networks hiccup, deployments happen. If a webhook delivery fails, you don't want to lose the event.
The solution: HookSniff automatically retries failed deliveries using exponential backoff with jitter. Each retry waits longer than the last, preventing thundering herd problems.
Default schedule (5 attempts, configurable per endpoint):
| Attempt | Delay | Cumulative |
|---|---|---|
| 1 | ~1 saniye | ~1s |
| 2 | ~2 saniye | ~3s |
| 3 | ~4 saniye | ~7s |
After all 5 retries are exhausted, the delivery moves to the Dead Letter Queue. Retries & DLQ
Dead Letter Queue (DLQ)
The problem: After all retries fail, what happens to the event? Without a DLQ, it's silently lost.
The solution: Failed deliveries are preserved in the DLQ with full context — the original payload, every attempt's status code, response body, and timing. You can inspect them, understand what went wrong, and replay with one click.
- Original payload preserved
- All attempt details (status codes, errors, timestamps)
- Ability to replay — re-queue the delivery for another attempt
- Retention based on plan (Developer: 7 days, Startup: 14 days, Pro: 180 days, Enterprise: 365 days)
API Keys
The problem: How do you authenticate API requests without sharing your password?
The solution: API keys are long-lived tokens prefixed with hr_live_. You can create multiple keys (one per service or team member) and rotate them without downtime.
Authorization: Bearer hr_live_abc123xyz789- Keys are Argon2 hashed in the database — plaintext is never stored
- Multiple keys per account — rotate without downtime
- Scoped to your plan's rate limits
- Each key shows only its prefix in the dashboard — full key shown once at creation
FIFO Delivery
The problem: If you send webhooks for order.created and order.updated in quick succession, the updated event might arrive before the created event. Your consumer processes them out of order.
The solution: HookSniff delivers webhooks in FIFO (first-in, first-out) order per endpoint. Each delivery includes a sequence number so consumers can detect gaps or reorder events.
{
"delivery_id": "wh_xyz789",
"sequence_number": 42,
"event": "order.created",
"data": { "order_id": "12345" },
"timestamp": "2026-01-15T10:30:00Z"
}How It All Fits Together
Here's the complete flow:
- 1. You create an endpoint with a URL and signing secret
- 2. You send a webhook via API with an event type and payload
- 3. HookSniff creates a delivery and signs the payload with HMAC-SHA256
- 4. The worker delivers it to your endpoint in FIFO order
- 5. If it fails, retries kick in with exponential backoff
- 6. If all retries fail, the delivery goes to the DLQ for inspection
- 7. You can replay failed deliveries after fixing the issue
All of this is visible in the dashboard with real-time delivery tracking, analytics, and alerting.