Webhook retries
If your endpoint fails to respond with a 2xx status within 10 seconds, Aeses retries the delivery. The retry schedule and rules are deterministic so you can build around them.
Retry schedule
A failed delivery is retried up to 7 times with the following backoffs from the original attempt:
| Attempt | Delay from previous | Total elapsed | | ------- | ------------------- | ------------- | | 1 | — | 0 | | 2 | 30 seconds | 30 seconds | | 3 | 2 minutes | ~2.5 minutes | | 4 | 10 minutes | ~12 minutes | | 5 | 1 hour | ~1 hour | | 6 | 6 hours | ~7 hours | | 7 | 24 hours | ~31 hours | | 8 | 72 hours | ~4 days |
After the 8th attempt fails, the delivery is marked exhausted and no further automatic retries occur. The event remains available via the webhook-deliveries API and can be replayed manually.
What counts as a failure
| Response | Retried? |
| -------------------------------------------- | -------------------------- |
| 2xx status | No — success. |
| 408 Request Timeout or no response in 10s | Yes. |
| 5xx status | Yes. |
| 429 Too Many Requests | Yes. Honors Retry-After. |
| Any other 4xx | No — permanent. |
| Connection refused / DNS failure / TLS error | Yes. |
4xx responses other than 408 and 429 are considered permanent. They indicate the payload itself is the problem (signature mismatch, malformed body) and retrying will not help.
Inspecting deliveries
Every attempt — successful or not — is recorded. You can list and inspect deliveries via:
The dashboard surface lives under Developers → Webhooks → Deliveries. Each delivery shows: request payload, signature, your response status and body, and the next retry time.
Manual replay
Aeses lets you replay a delivery on demand — useful after fixing a bug in your endpoint:
- From the dashboard: Deliveries → click delivery → Replay.
- From the API:
POST /v1/webhook-deliveries/:id/replay.
A replay creates a new delivery (with its own id) so the original audit trail is preserved.
Designing for retries
Because the same event may arrive more than once, your handler must be idempotent:
- Read
event.idfrom the payload. - Check whether you have already processed it (e.g. unique index in your DB).
- If new, process the event and persist the
event.id. - If duplicate, return
200 OKimmediately without re-processing.
This pattern also protects you from at-least-once delivery during planned platform deploys.