Docs

Idempotency

Retry any POST safely with an Idempotency-Key: the same key and body never repeat the work, and a replay shows the current state.

A request whose answer never arrives may or may not have run. For reads that is harmless: retry it, and set max_age to the seconds since the first attempt so the retry is served free from the cache. For requests that create something, such as a job, send an idempotency-key header and retry with the same key: the work is done once, whatever the number of attempts.

How it works

  • Every POST accepts the header. Use a new random value for each new request (a UUID is ideal), up to 255 printable ASCII characters, and reuse it only to retry that same request.
  • Keys belong to your account and to one route, and are kept 1 day.
  • The first request with a key runs normally. Once it has succeeded, a retry with the same key and the same body doesn't run again: it answers with the first request's status and the resource's current state (a job created then is shown as it is now), with the header idempotent-replayed: true. Routes that show a secret once (a new webhook endpoint, a rotated secret) answer exactly what they answered the first time.
  • The body is compared after parsing, so key order and whitespace don't matter.
SituationAnswer
The same key with another body, or on another routeidempotency_key_reused (422): send a new key
The same key while its first request is still runningidempotency_key_in_progress (409): retry after the retry-after seconds
A key whose first request was refused or failedNothing is kept: retry with the same key once the request is fixed

The SDKs send a key with every POST and reuse it for their automatic retries.