> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fortary.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Delivery & retries

<Info>
  **Pre-release** — contact your Fortary account team for access.
</Info>

## What counts as delivered

A delivery succeeds when your endpoint returns **any `2xx` status within 10 seconds**. Anything else — another status code, a timeout, a TLS or connection error — is a failed attempt.

* Redirects are **not** followed.
* Your response body is read up to **1 KB** and stored as a diagnostic snippet, visible in the [delivery history](/api/reference/webhooks/list-webhook-deliveries).

## Retry schedule

Failed deliveries are retried with growing spacing (each delay carries ±20% jitter):

| Attempt | Delay after previous attempt      |
| ------- | --------------------------------- |
| 1       | immediate — when the event occurs |
| 2       | 5 s                               |
| 3       | 30 s                              |
| 4       | 2 min                             |
| 5       | 10 min                            |
| 6       | 30 min                            |
| 7       | 1 h                               |
| 8       | 2 h                               |
| 9       | 4 h                               |
| 10      | 6 h                               |
| 11+     | every \~6 h                       |

Retries continue for **24 hours** from the first attempt (about 12 attempts). A delivery that never succeeds is marked **exhausted** — it remains visible in the delivery history and can be [redelivered](#redelivery) manually.

If your endpoint is overloaded, include a `Retry-After` header (in seconds) on your failure response — typically with a `429`: the next retry honors it, up to a maximum of 1 hour.

## Automatic disabling

When a delivery exhausts its 24-hour budget as the **10th consecutive exhausted delivery** and the webhook has had **no successful delivery in 72 hours**, the webhook is disabled and Fortary emails its notification address.

To recover:

1. Fix your endpoint, and verify it with a [test ping](/api/reference/webhooks/ping-webhook) — pings work while the webhook is disabled.
2. [Re-enable](/api/reference/webhooks/update-webhook) the webhook (this resets the failure counter).
3. Events that occurred while disabled are **not** delivered retroactively — no deliveries exist for them to [redeliver](/api/reference/webhooks/redeliver-webhook-delivery). They remain browsable in the [event log](/api/reference/webhooks/list-webhook-events) (31-day retention) for manual reconciliation.

## Redelivery

Any delivery can be [redelivered](/api/reference/webhooks/redeliver-webhook-delivery). A redelivery is a **fresh delivery**: new `x-fortary-delivery-id`, attempt counter restarted, a full new retry budget, signed with the webhook's **current** secret. The event body is byte-identical to the original.

## Handling deliveries reliably

* **Acknowledge fast, process async.** The 10-second window is for receipt, not processing.
* **Deduplicate on the event `id`.** Retries and redeliveries can hand you the same event twice.
* **Don't rely on ordering.** Order by the envelope's `date` when sequence matters.
* **Tolerate unknown fields.** Additive payload changes ship under the same `schemaVersion`.
* **Alert on [signature failures](/api/reference/webhooks/verifying-signatures).** They mean a secret mismatch or traffic that isn't from Fortary.
