# Deliveries and retries

Each event becomes one delivery per webhook. A delivery succeeds when your endpoint answers with a `2xx` status within the timeout.

## Request

| Header | Version 3 | Versions 2 and 1 |
|---|---|---|
| `Content-Type` | `application/json` | `application/json` |
| `User-Agent` | `Cademi-Webhooks/3` | `cademi` |
| `Cademi-Signature` | `t=<unix>,v1=<hex>`, see [Signatures](https://cademi.dev/webhooks/signatures.md) | Same |
| `Cademi-Webhook-Id` | The webhook, `whk_…` | Same |
| `Cademi-Delivery-Id` | The delivery, `whd_…` | Not sent |
| `Cademi-Event-Type` | The event type | Not sent |
| `Cademi-Signature-Version` | `1` | Not sent |

## Timeout and connection

- Your endpoint must answer within the timeout of the webhook: 5 seconds for versions 2 and 1, and the `timeout_ms` of a version 3 webhook, 10 seconds by default. The connection must be accepted within 5 seconds, or within the timeout if it is shorter. A slower answer counts as a failure.
- The TLS certificate is verified. A self-signed or expired certificate, or one issued for another host, fails the delivery.
- Version 3 does not follow redirects: point the webhook to the final URL. Versions 2 and 1 follow up to 5 redirects: a `301`, `302`, or `303` redirect is followed with a `GET` without the body, and a `307` or `308` redirect repeats the `POST` with the body. Every redirect goes through the same address checks, and the certificate is verified on every `https` hop.
- Hosts that resolve to a private, loopback, link-local, or shared address, or that do not resolve, are not delivered to.

## Retries

A delivery that fails (an answer other than `2xx`, a timeout, or a connection error) is retried with a growing wait, from 2 minutes up to 6 hours between attempts. A delivery gets up to 10 attempts within 72 hours of being created. After the last attempt, or once 72 hours have passed, it stops being retried and can only be resent from the delivery history.

- A `429` answer does not use an attempt: the delivery waits for `Retry-After` and tries again.
- When a URL fails several times in a row, its deliveries wait without using attempts, and a single test delivery goes out every few minutes until the URL answers again.
- A disabled or deleted webhook cancels its pending deliveries.

## Automatic deactivation

A webhook whose deliveries keep failing (10 different deliveries failing within 24 hours, or 30 failures in a row on its URL) is disabled automatically. Its pending deliveries are cancelled, and the administrators of the account receive an e-mail. Only webhooks with that URL are affected.

To turn it back on, open the webhook at **Settings > Integrations > Webhooks** and select **Reactivate**, or **Reactivate and resend the last 48 hours** to also send again the deliveries from the last 48 hours that failed or were cancelled by the deactivation.

Every retry carries the same `event_id`. Deliveries are not guaranteed to arrive in order.

Events caused by a sale, an import, or a delivery can arrive a few minutes later than events for changes made in the dashboard or through the API.
