Idempotency
Any write accepts an Idempotency-Key header. Send one and a retry cannot create a duplicate.
Generate a fresh key per logical operation. A UUID is ideal. The key must be printable ASCII, 1 to 255 characters.
What happens on a retry
Only 2xx responses are cached. A 4xx or 5xx leaves the key free, so you can correct the payload and retry with the same key.
Why the mismatch error exists
422 idempotency_key_request_mismatch means you reused a key with a changed body. That is almost always a bug on the client — a retry loop that regenerates the payload, or a key derived from something less unique than the operation.
It is deliberately an error rather than a silent overwrite: the alternative is a caller believing they had updated a gift when the API had replayed an older response.
When you need it most
The case that bites hardest is creating a donor without an email address. Email is optional, and uniqueness is what would otherwise catch a duplicate — so an email-less create has no natural protection. A network timeout on that call, followed by a naive retry, produces two donor records that are hard to tell apart afterwards.
Send an Idempotency-Key on every donor create, and treat it as mandatory when email is omitted.
Interaction with dry runs
A dry run never consumes a key. You can validate a request and then send it for real using the same Idempotency-Key.