POST request is sent with an idempotency key header, Sail stores the reservation alongside the resulting response record. Retrying the same request with the same key returns the previously reserved response — Sail does not re-run inference. This makes client retries safe across transient network failures, timeouts, and ambiguous 5xx responses.
Sending an idempotency key
Generate a key per logical request (UUIDs or any unique string ≤ 255 chars work well) and attach it to the first attempt and every retry.Behavior
- Scope. Reservations are keyed by
(organization, API key, idempotency key). The same key sent under a different API key is a distinct reservation — rotating keys does not break replay, but sharing an idempotency key across keys won’t dedupe. - Body fingerprint. Sail fingerprints the request body with SHA-256. Reusing a key with a materially different body returns
400 idempotency_errorrather than replaying the earlier response. This prevents a retry from silently returning the wrong answer if the client changed the request. - Validation failures don’t consume the key. A request that fails validation (any
4xxbefore the reservation is written) does not reserve the key. You may retry with a corrected body using the same key. - Replays reflect current state. A replay reads the current state of the underlying response record, not a frozen snapshot. For background requests, the returned
statusreflects the task’s most recent transition (e.g.queued→in_progress→completed).
Retrying with an idempotency key
The key only pays off when you actually retry. The first attempt reserves the key. Subsequent attempts hit the same reservation and get the stored response back without re-running inference.When to retry
| Signal | What it means | What to do |
|---|---|---|
| Network error / timeout | Ambiguous — the server may or may not have received the request | Retry with the same idempotency key |
5xx on a POST | Transient server-side failure | Retry with the same idempotency key |
429 + Retry-After | Rate limit | Wait the Retry-After value, then retry |
body.status: "failed" | Inference genuinely failed | Investigate the cause; do not blind-retry |
How to retry
See also
- Sending Requests at Scale — batch and background patterns where idempotent retries are most useful.
- Webhooks — pair idempotent retries with webhook delivery so clients can re-drive submission without re-running inference.