How-to guide
Reliable webhook delivery
Networks fail, receivers restart, endpoints rate-limit. Queuey turns that into a delivery you can trust: retries with backoff, idempotency so a retry is never a duplicate, a safe Hold-on-timeout default, and a dead-letter queue for whatever truly can't be delivered.
Retries & backoff
Each queue resolves a retry policy. What gets retried is decided by the failure class, not by a counter: a receiver that rejected the event goes straight to the dead-letter queue, while a target that is down is held and probed until it recovers. dlq.afterAttempts is the one attempt budget you set. Retries use exponential backoff with jitter, and what counts as retryable is driven by failure classes (server errors, unavailable, rate-limited) with per-receiver HTTP-status overrides:
Retry policy (resolved system → tenant → queue)
backoff: exponential, base 1s, max 5m, jitter: full
retryOn: failure classes (server error, unavailable, rate-limited)
+ httpStatus fallback / excluded
+ network errors, timeouts
timeoutBehavior: Hold # Retry | Hold (default) | Dlq
dlq: enabled, afterAttempts: 8Idempotency
Send a producer Idempotency-Key and a duplicate retry within the dedup window short-circuits to the already-accepted event — you never double-enqueue:
curl -X POST "$INGRESS/events/ten_yourTenant/orders" \
-H "X-Api-Key: $KEY" \
-H "Idempotency-Key: order-10042-created" \
-H "Content-Type: application/json" \
-d '{ "eventType": "order.created", "payload": { "id": "10042" } }'On the way out, Queuey threads the same key (and an X-Queuey-Path for loop prevention) so an idempotent receiver can dedupe across delivery retries too:
POST /your/webhook HTTP/1.1
Idempotency-Key: order-10042-created
X-Queuey-Path: ten_yourTenant/orders
Content-Type: application/jsonSafe-by-default on timeout
timeoutBehavior is Hold: pause the queue and open an issue rather than risk a duplicate. Switch to Retry only once you've asserted the endpoint is idempotent — or route timeouts straight to Dlq.Dead-letter queue
When retries are exhausted (or after a configured attempt count), the event lands in the DLQ instead of disappearing. From the console you can inspect the failure, fix the target, and replay — single events or in bulk.
Related
- Core concepts — the event lifecycle and where retries fit.
- Quickstart — send your first event.