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

# Delivery and retries

> How Tumban retries webhook delivery and what HTTP statuses it honours.

Tumban delivers each webhook with up to three attempts. Behaviour by
response:

| Response                    | Action                                                                                                                                                                                                                                                                     |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `2xx`                       | Delivered. No further attempts.                                                                                                                                                                                                                                            |
| `429 Too Many Requests`     | Retry. Tumban honours a numeric `Retry-After` header — decimal seconds are accepted, e.g. `Retry-After: 2.5`. Negative or non-numeric values are ignored; the HTTP-date form is not parsed. Capped at 60 s. Without a parseable header, falls back to exponential backoff. |
| Other `4xx`                 | Not retried. Tumban gives up — fix your endpoint and replay manually if needed.                                                                                                                                                                                            |
| `5xx`                       | Retry with exponential backoff.                                                                                                                                                                                                                                            |
| Connection error or timeout | Retry with exponential backoff. The HTTP timeout per attempt is 30 s.                                                                                                                                                                                                      |

## Backoff

Tumban waits `1s` after the first failed attempt and `2s` after the
second. There is no sleep after the third attempt — the request fails
permanently. Total maximum wall-clock time for a failed delivery is
roughly `3 × 30 s` (timeouts) plus `1 s + 2 s` (backoffs). The 30-second
cap in the backoff formula `min(2^attempt, 30)` is not reached at the
current retry count.

## What gets delivered after the final retry

If all three attempts fail, the scan record is left with
`webhook_delivered_at` unset. The scan itself is not affected —
results remain available via
[`GET /api/v2/scans/{scan_id}`](/api/scans/get).

## Skipping delivery

If a scan is submitted with no `callback_url` and the organization has
no [`default_callback_url`](/api/org/update-settings) set, Tumban runs
the scan to completion but sends no webhook. Read the result by
polling [`GET /api/v2/scans/{scan_id}`](/api/scans/get) instead.

## API-key revocation during a scan

If the API key that authenticated the scan is revoked **after**
submission but before the webhook fires, Tumban skips delivery of
that webhook. The scan still completes server-side and the result
remains readable via [`GET /api/v2/scans/{scan_id}`](/api/scans/get)
to credentials still authorized for the organization. This protects
the up-to-450-second window between scan submission and webhook
delivery from a leaked-then-revoked key.

## Idempotency

Each delivery attempt sends the same body, including the same
`scan_id`. Treat the `scan_id` as the idempotency key in your
handler — repeated deliveries for the same scan should be a no-op
once you've recorded the result.
