| 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 waits1s 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 withwebhook_delivered_at unset. The scan itself is not affected —
results remain available via
GET /api/v2/scans/{scan_id}.
Skipping delivery
If a scan is submitted with nocallback_url and the organization has
no default_callback_url set, Tumban runs
the scan to completion but sends no webhook. Read the result by
polling GET /api/v2/scans/{scan_id} 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 viaGET /api/v2/scans/{scan_id}
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 samescan_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.
