> ## Documentation Index
> Fetch the complete documentation index at: https://relay-demo.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook delivery and retries

> What counts as delivered, and what Relay does when your endpoint is down.

For every event your endpoint subscribes to, Relay sends one `POST` request with the event as a JSON body:

```http theme={null}
POST /webhooks HTTP/1.1
Host: yourapp.example
Content-Type: application/json
Relay-Event-Id: evt_2Lk9xQ
Relay-Delivery-Id: dlv_8Hc1Rm
Relay-Signature: t=1729600000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

{"id": "evt_2Lk9xQ", "type": "invoice.paid", "created": 1729600000, "data": {"invoice_id": "inv_123", "amount": 4900}}
```

Any `2xx` answer within 10 seconds counts as delivered. Anything else is a failed attempt: a `3xx`, `4xx` or `5xx`, a timeout, a refused connection or a TLS error. Redirects are not followed.

## Retries

A failed delivery is retried on a fixed schedule, up to 8 attempts in all, until one succeeds.

![Sequence diagram between Relay and a customer webhook endpoint: attempt 1 fails with 503, Relay waits 1 minute, attempt 2 fails, Relay waits 5 minutes, attempt 3 succeeds with 200. If all 8 attempts fail, the delivery is marked failed and can be replayed.](https://mintcdn.com/relay-demo/EZNTzLZZIWlaFK8l/images/webhook-retries.png?fit=max\&auto=format\&n=EZNTzLZZIWlaFK8l\&q=85\&s=0c0c5d466e036c5d1377cb55d72d0ce1)

The endpoint fails twice and answers 200 on the third attempt, so retries stop. After 8 failed attempts the delivery is marked failed.

| Attempt | Sent after the previous failure |
| - | - |
| 1 | Immediately |
| 2 | 1 minute |
| 3 | 5 minutes |
| 4 | 30 minutes |
| 5 | 2 hours |
| 6 | 6 hours |
| 7 | 12 hours |
| 8 | 24 hours |

All 8 attempts take about 45 hours. Each wait has up to 10% random jitter, so retries from many events don't arrive at once.

## Failed deliveries

When the last attempt fails, the delivery is marked `failed` and shows up under **Webhooks → Failed** in the dashboard. Fix your endpoint, then replay one or all of them:

```bash theme={null}
relay deliveries replay dlv_8Hc1Rm
relay deliveries replay --endpoint ep_42 --status failed --since 48h
```

If every delivery to an endpoint has failed for 5 days, Relay disables the endpoint and emails your account's owners.

## Order

Relay doesn't guarantee order. A retried `invoice.created` can arrive after `invoice.paid`.

![Sequence diagram between Relay and your webhook endpoint: at 10:00:01 invoice.created gets a 503 and is scheduled for retry in 1 minute; at 10:00:06 invoice.paid is delivered with 200; at 10:01:01 invoice.created is retried and delivered with 200. Each event keeps its created time, 10:00:00 and 10:00:05.](https://mintcdn.com/relay-demo/EZNTzLZZIWlaFK8l/images/delivery-order.png?fit=max\&auto=format\&n=EZNTzLZZIWlaFK8l\&q=85\&s=cc186b159b51e6c69a49d7d01cf52c22)

invoice.created fails its first attempt and is retried a minute later, after invoice.paid has already been delivered.

Use the event's `created` time, or fetch the current state from your own database, rather than assuming the last event you received is the latest.

## Answer fast

Answer `200` as soon as you have stored the event, then do the work in a background job. A handler that takes longer than 10 seconds fails even if it finishes the work, and the event is delivered again. See [Idempotency](https://relay-demo.mintlify.site/idempotency.md) for handling those duplicates.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.