English
English
Appearance
English
English
Appearance
When Zorio pushes a webhook to your receiver and the delivery fails (timeout / non-2xx / network error), the platform retries automatically on an escalating schedule.
A receiver is considered failed when:
Receiver takes a while to process?
Return HTTP 200 as soon as you've verified the HMAC, then process the event asynchronously through your internal queue. Don't run business logic synchronously with Zorio — you'll pile up retries.
| Attempt | Delay since previous | Cumulative |
|---|---|---|
| 1 (first try) | — | 0s |
| 2 | 30 seconds | 30s |
| 3 | 5 minutes | 5m 30s |
| 4 (last try) | 30 minutes | 35m 30s |
After attempt 4 fails → the event moves to deadletter in the audit log.
When an event lands in deadletter:
Because Zorio may retry, the receiver MUST be idempotent — processing the same event multiple times must not cause inconsistent side effects (e.g. don't create two rows with the same UUID, don't deduct money twice).
Every delivery carries X-Zorio-Delivery: <UUID>. Save the UUID in Redis with 24h TTL:
const seen = await redis.set(`zorio:delivery:${deliveryId}`, '1',
'NX', 'EX', 86400);
if (seen === null) {
// Already processed → return 200 and skip
return res.status(200).send('Duplicate');
}
// Process the event...Result: no matter how many times Zorio retries, your business logic only runs once.
Retry-After: <seconds>. Zorio honors this header (the next retry waits at least the time you specified).If a webhook URL fails 50 events in a row without a single success → the platform auto-suspends it to stop wasting resources.