Skip to main content
Tumban delivers each webhook with up to three attempts. Behaviour by response:
ResponseAction
2xxDelivered. No further attempts.
429 Too Many RequestsRetry. 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 4xxNot retried. Tumban gives up — fix your endpoint and replay manually if needed.
5xxRetry with exponential backoff.
Connection error or timeoutRetry 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}.

Skipping delivery

If a scan is submitted with no callback_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 via GET /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 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.