Retries
The fixed retry ladder Tanitar walks when your endpoint does not accept a delivery, and when a delivery is marked dead.
A delivery is attempted up to eight times. Each attempt is a separate POST with a fresh
webhook-timestamp and signature, the same webhook-id, and tanitar-delivery-attempt set to its
number. The ladder is fixed; it is the same for every endpoint and cannot be configured.
The ladder
| Attempt | Delay after the previous attempt | Time since the first attempt |
|---|---|---|
| 1 | Immediately | 0 |
| 2 | 1 minute | 1 minute |
| 3 | 5 minutes | 6 minutes |
| 4 | 30 minutes | 36 minutes |
| 5 | 2 hours | 2 hours 36 minutes |
| 6 | 6 hours | 8 hours 36 minutes |
| 7 | 12 hours | 20 hours 36 minutes |
| 8 | 24 hours | 44 hours 36 minutes |
Delays are measured from the start of the previous attempt and are minimums: an attempt can start slightly later than scheduled, never earlier.
What counts as a failure
An attempt succeeds when your endpoint answers with any 2xx status within the timeout. Everything
else is a failure and moves the delivery to the next rung:
| Outcome | Recorded error class |
|---|---|
A non-2xx status other than 410 (including 4xx and 5xx) | status code only |
A 3xx redirect (redirects are never followed) | redirect |
| No response within the timeout (10 seconds by default) | timeout |
| TLS handshake or certificate failure | tls |
| Connection refused or reset, or another network error | network |
| The endpoint's host name no longer resolves | dns |
| Anything else | unknown |
A 410 Gone is different: it settles the delivery as dead immediately, with reason
ENDPOINT_GONE, and no further attempt is made.
Dead deliveries
A delivery becomes dead when it cannot succeed any more. The reason is recorded on the delivery and
shown in the dashboard's delivery log:
| Reason | When |
|---|---|
RETRY_EXHAUSTED | The eighth attempt failed. |
ENDPOINT_GONE | Your endpoint answered 410. |
ENDPOINT_DISABLED | The endpoint was disabled before the next attempt ran. |
ENDPOINT_REVOKED | The endpoint was revoked before the next attempt ran. |
ENDPOINT_UNSAFE | The endpoint's URL no longer passes URL admission (for example, its host now resolves to a private address). |
SIGNING_SECRET_MISSING | The endpoint has no active or retiring signing secret left. |
The last four are decided before any request is sent: nothing reaches your endpoint for that attempt.
A dead delivery stays in the delivery log for 30 days. Once you have fixed the cause, an administrator can replay it: one delivery at a time, or every dead delivery of an endpoint at once.
Designing your receiver for retries
- Make processing idempotent on
webhook-id: an attempt that timed out on Tanitar's side may still have been processed on yours. - Return
5xxfor a temporary problem so the ladder retries it, and2xxonce the event is safely stored, even if your own downstream processing fails later. - Do not return
410for a transient error; it ends the delivery at once. - If your receiver is down for longer than about 45 hours, deliveries in that window go
dead. Use batch replay to recover them.