Retries & delivery guarantees
We deliver every event at least once, in order of occurrence (best effort — retries may arrive out of order). Anything other than a 2xx response counts as a failure and triggers retry with exponential backoff.
Retry schedule
Up to 8 attempts spread over roughly 24 hours:
| Attempt | Delay since previous | Total elapsed |
|---|---|---|
| 1 | — | immediate |
| 2 | 30 seconds | 30s |
| 3 | 2 minutes | ~2·5m |
| 4 | 10 minutes | ~12m |
| 5 | 30 minutes | ~42m |
| 6 | 2 hours | ~3h |
| 7 | 6 hours | ~9h |
| 8 | 12 hours | ~21h |
After the 8th failure, the delivery is marked dead. We never retry a dead delivery automatically. The full request body, signature, and last error stay on the delivery record so you can investigate.
What counts as a failure
- Any HTTP response status outside the 2xx range
- Request times out (we wait 10 seconds for a response)
- TLS handshake fails or certificate is invalid
- DNS resolution fails or the connection is refused
Auto-disable
After 20 consecutive failures across all deliveries, we disable the webhook automatically. This prevents a permanently-broken endpoint (wrong DNS, dead server) from generating noise indefinitely. Re-enable it manually from the webhook detail page after fixing the upstream issue — that clears the failure counter.
Idempotency
Retries use the same X-Veritus-Delivery UUID as the original. Store
recently-seen delivery IDs (e.g. in Redis with a 48-hour TTL) and skip already-processed
ones. This matters because we'll retry on timeouts even when your handler did the work
but the response got lost.
What we DON'T do
- No webhook ordering guarantees across different events
- No queuing at our end beyond the retry buffer — if your endpoint is down for 24h+, deliveries during that window become dead
- No batching — one event = one HTTP request
Inspecting deliveries
Each webhook's detail page shows the last 50 deliveries with status, attempt count, last HTTP response code, latency, and any error. Use this to confirm your endpoint is healthy and to debug rejections.