Idempotency beyond the request
What happens when a retry lands after the work completed but before the response arrived?
A client can time out after the server commits a change. If the client retries, the server needs a durable way to recognise the operation and return its result.
For a database-only mutation, persist the idempotency key and the business change in the same transaction. Give the key a uniqueness constraint scoped to the caller and operation. If the caller reuses a key for a different payload, return a conflict.
When the operation calls an external provider, pass a stable idempotency key downstream if the provider supports it. An outbox can make delivery retryable, while the downstream key protects against duplicate effects after an ambiguous response.