Idempotency-Key header tells us “if you have already seen this
request, replay the original response — do not run the work again.”
When to use it
IncludeIdempotency-Key on every POST and PATCH. For GET
requests it has no effect (reads are naturally idempotent).
How to generate one
Use any unique-enough string per request, ≤ 255 characters. A UUID works perfectly:How it works
- First request with that key: the work runs, the response is stored, and the response is returned.
- Second request with the same key (and the same body): the stored
response is replayed verbatim, including the original HTTP status
code. A
Idempotent-Replayed: trueheader is added so you can tell. - Repeat with a different body: returns 409 idempotency_conflict. This catches a real client bug — never silently shadows a prior result.
TTL
Cached responses are kept for 24 hours. After that, the next request with that key runs the work again. Make sure your retry window fits inside 24 hours.What counts as “the same request”
A request is matched by the tuple(organization, method, path, key).
That means:
- You can reuse the same idempotency key across
POSTandPATCHwithout collision. - Two different organisations can use the same key independently — they are isolated.
POST /v1/customerswith keyXandPATCH /v1/customers/abcwith keyXdo not interfere.
Idempotency vs externalId
These are two complementary safeties:
Idempotency-Key— protects against duplicate calls within a 24h retry window. Operational concern.externalId— protects against duplicate records across all of time. Domain concern. The sameexternalIdreused onPOSTperforms a deliberate upsert.

