Skip to main content
Every POST requires an Idempotency-Key header. Without one, the request is rejected before the handler runs:
This is mandatory rather than optional because the failure it prevents is silent: a request that times out in transit has still been applied, and a client that retries without a key creates a second member, a second group, a second charge. Making the key required means a retry is always safe.

Sending a key

Generate one UUID per logical operation — not per HTTP attempt. All retries of the same operation reuse the same key.

What a reused key does

A replay returns the stored response — the same body and the same status:
Note that it is 201, not 200. The response describes the original operation, not the act of replaying it, so a client can handle both identically.

Keys are scoped to your token

Two tokens can use the same key without colliding. A key from a revoked token carries nothing over to its replacement — after rotating, an in-flight retry runs as a fresh request, so make sure the operation is also naturally deduplicated (a duplicate email returns 409 conflict) if that matters to you.

Body comparison ignores key order

The fingerprint is taken over a canonicalized body: object keys sorted at every depth, undefined dropped. So these are the same request, and the second replays rather than conflicting:
Without that, any client library that serializes keys in a different order would get a spurious 409 on a legitimate retry.
Don’t reuse a key across different operations, and don’t derive keys from something that repeats — “member-import-row-1” every night will replay yesterday’s response for 24 hours instead of importing today’s row.