Skip to main content
A delivery is considered successful when your endpoint returns any 2xx status. Anything else — a non-2xx response, a connection failure, or a timeout — marks the delivery failed and schedules a retry.

Retry schedule

Failed deliveries are retried with backoff: 30s, 2m, 15m, 1h, 4h, 12h, then 24h — up to 8 attempts (the original plus 7 retries) over about 41 hours. After the last attempt the delivery is marked permanently failed. A retry re-POSTs the delivery’s entire events array under the same delivery_id, re-signed at send time — so a late retry carries a fresh signature timestamp and whichever secrets are valid at that moment.

Special cases

  • 410 Gone — Kit stops retrying immediately and marks the delivery failed. Return 410 when an endpoint no longer exists so Kit doesn’t keep trying.
  • 429 / 503 with Retry-After — Kit honors the Retry-After header when deciding when to try again (clamped between 1 second and 24 hours), so you can slow Kit down without failing outright.

Designing for retries

  • Be idempotent. Your handler may see the same event more than once — a retried delivery repeats every event in it, and an upstream re-emit can carry the same event under a new delivery. Deduplicate on each event’s UUID id, which stays the same across re-sends — see idempotency.
  • Acknowledge fast. Return 2xx as soon as you’ve safely received the payload and do heavier work asynchronously, so a slow handler doesn’t time out and trigger an avoidable retry.