On this page
Delivery & retries
Design for 11 webhook delivery attempts over roughly 16 hours, deduplicate repeated events, inspect failures, and replay after recovery.
If your endpoint returns a non-2xx status or exceeds the 10-second timeout, Paymos retries with exponential backoff (x2). Up to 11 total attempts (1 initial + 10 retries) over approximately 16 hours.
Backoff schedule
| Attempt | Delay after previous | Cumulative delay |
|---|---|---|
| 1 | immediate | 0 |
| 2 | 1 min | 1 min |
| 3 | 2 min | 3 min |
| 4 | 4 min | 7 min |
| 5 | 8 min | 15 min |
| 6 | 16 min | 31 min |
| 7 | 32 min | ~1 hour |
| 8 | 1 hour | ~2 hours |
| 9 | 2 hours | ~4 hours |
| 10 | 4 hours | ~8 hours |
| 11 | 8 hours | ~16 hours |
After all 11 attempts the event is marked failed. Failed events can be replayed from the dashboard — replaying resets the attempt counter and re-enqueues the event for delivery.
Idempotency
Delivery is at-least-once. Duplicate deliveries are normal during retries — your handler must be idempotent. Every delivery carries the same stable id in the X-Webhook-Id header (and in the body's event_id), unchanged across retries and replays — dedupe on it without parsing the body. Persist processed ids and treat repeats as 200 OK no-ops.
What counts as a successful delivery
- HTTP
2xxresponse within 10 seconds → delivery succeeded - HTTP
4xxor5xx→ counted as a failure, will retry - Connection refused, DNS failure, TLS error → counted as a failure, will retry
- Response after 10 seconds → counted as a failure, will retry (your endpoint may still process the duplicate)
Return 2xx as soon as the event is persisted on your side. Defer expensive processing to a background queue so the webhook handler stays under the timeout.