Skip to main content
A network can fail after Darwin has done the work but before you get the answer. Send an Idempotency-Key header on every write (POST, PATCH, DELETE) and you can retry without doing it twice.

How it works

  • The first request with a key runs normally. Darwin stores its response for 24 hours.
  • A retry with the same key, method, path and body gets the stored response back, with the same status and body, plus the header Idempotent-Replayed: true. Nothing runs a second time.
  • A refused request (a 4xx) is a final answer and is replayed like a success. Fix the request and send it with a new key.
  • A Darwin-side failure (a 5xx) is not stored, so a retry with the same key runs the request again.
  • While the first request is still running, a retry with the same key gets 409 idempotency_key_in_use. Wait a few seconds and retry.
  • The same key with a different method, path or body gets 422 idempotency_key_reused.
Keys are scoped to the API key that sent them, and must be 1 to 255 visible ASCII characters. A UUID v4 per logical operation is a good choice.

Retry pattern

A 409 with the code conflict is not a retry case: read the object again and resolve it. The loop above retries every 409 for brevity; check code in production code.

Writes that are safe without a key

Some writes give the same result however often you send them: PATCH with the same fields, or DELETE of something already gone (it returns 404). POST /contacts is an upsert by email, so a repeat updates the same contact. A key still protects you from a retry racing the original, so sending one on every write is the simplest rule.