Skip to content

Idempotency

A network error on a write leaves you not knowing whether it happened. Routes that change many records at once require an Idempotency-Key so a retry cannot apply the change twice.

Route Required
POST /apps/catalog/products/bulk yes
POST /apps/media/imports yes
other app routes no — the header is ignored

A required key that is missing or blank → 400. Longer than 255 characters → 400.

Keys are scoped to your installation — another app can never collide with yours. A request is identified by its key and a fingerprint of METHOD + path + raw body bytes. The query string is not part of the fingerprint, and the body is compared byte for byte: re-serialising the same object with a different key order or whitespace is a different request.

Situation Response
First use of the key The request runs normally.
Same key, same request, finished The original status and body, plus Idempotent-Replay: true. Nothing runs again.
Same key, same request, still running 409 with Retry-After: 1. Retry with the same key.
Same key, different request 422. You reused a key — generate a new one.
Original response was larger than 256 KB 409 saying the work was done and cannot be replayed. Do not retry.
Original request failed with a 5xx The key is released; a retry runs the request again.

Keys are remembered for 24 hours. After that the same key starts a new request.

Derive the key from what you are doing, not from the attempt: one key per logical operation, reused on every retry of it. The reference app uses zugo:{runId}:{vehicle}:{chunk} — unique per sync run and per chunk, stable across retries within the run.