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

# Webhook Retries

> Five delivery attempts with exponential backoff, terminal 4xx handling, and the deliveries log.

Return any `200–299` status within 10 seconds and the delivery is complete. Anything else — a `5xx`, a timeout, a DNS failure, a refused connection — is retried automatically.

## Schedule

A maximum of **5 attempts** per delivery: the initial POST plus up to 4 retries with these delays:

| Attempt | Delay after previous attempt |
| :------ | :--------------------------- |
| 1       | Immediate (initial delivery) |
| 2       | 30 seconds                   |
| 3       | 2 minutes                    |
| 4       | 10 minutes                   |
| 5       | 1 hour                       |

After the 5th failed attempt the delivery is recorded as failed and no further retries are scheduled. Each attempt fetches your endpoint with a **10-second timeout**.

## Terminal failures are not retried

A `4xx` response is your endpoint's explicit rejection — bad URL, auth failure, gone — so it is recorded as terminal and never retried. If your handler throws before reading the body (unknown route, missing auth), fix the endpoint rather than waiting for a retry that will not come.

Retires also halt permanently when the webhook is deleted or deactivated mid-retry. That produces a final delivery row with the error `Webhook was deleted or deactivated; retries halted`, so the log always ends in a terminal state instead of going silent.

<Note>
  Because redelivery is possible, handlers must be idempotent. Dedupe on the `X-Gork-Delivery` header: it is deterministic per webhook, event, and attempt, so a repeated delivery of the same attempt carries the same id.
</Note>

## Inspect deliveries

Every attempt — headers sent, status received, response body (truncated to 1000 characters), and error — is logged. Query the log to debug a silent endpoint:

```bash cURL theme={null}
curl "https://api.gork.email/v1/webhooks/deliveries?limit=20" \
  -H "Authorization: Bearer gork_live_YOUR_KEY"
```

```json Response theme={null}
{
  "data": [
    {
      "id": "del_9f2c41ab77d04e1c90ab33de12",
      "webhookId": "whk_71a09ef2bc14000000000001",
      "eventType": "email.received",
      "responseStatus": 500,
      "isSuccessful": false,
      "error": "Your server returned a 5xx error.",
      "attempt": 1,
      "createdAt": "2026-09-22T12:34:57.000Z"
    }
  ]
}
```

`GET /v1/webhooks/deliveries` requires `webhooks:read` and accepts `limit` from 1 to 100 (default 50), newest first.

## Debugging checklist

1. Confirm the endpoint is subscribed to the event (`GET /v1/webhooks` → `subscribedEvents`).
2. Check the deliveries log for `responseStatus` and `error` — a `4xx` means your side rejected it; a timeout means the handler took over 10 seconds.
3. Verify the URL is still correct and the webhook is active. Rotate the secret (`POST /v1/webhooks/{id}/rotate-secret`) only if verification — not delivery — is failing.
