Back to all terms
key-abc-123key-abc-123key-abc-123Server1 charge(not 3)
APIadvanced

Idempotency Keys

Client-generated unique keys sent with mutating requests to ensure that retrying the same operation produces the same result without side effects.

Also known as: Idempotent Requests, Request Deduplication

Description

Idempotency keys allow clients to safely retry mutating API requests (POST, PATCH) without risk of duplicate side effects. The client generates a unique key (typically a UUID v4) and sends it in a request header (e.g., Idempotency-Key). The server stores the key alongside the response; if the same key is sent again, the server returns the stored response instead of re-executing the operation. This is critical for payment APIs, order creation, and any operation where duplication would cause real-world harm.

The server-side implementation stores the idempotency key, request fingerprint (method + path + body hash), and complete response (status code, headers, body) in a database or cache with a TTL (typically 24-48 hours). On subsequent requests with the same key, the server must verify that the request fingerprint matches -- if the same key is used with different parameters, it should return a 422 error to prevent misuse. The storage lookup and response creation must be atomic to handle concurrent retries correctly.

Idempotency keys interact with database transactions: the key should be recorded within the same transaction as the business operation to ensure consistency. If the transaction fails, the idempotency key should not be stored, allowing a genuine retry. The Stripe API is the canonical reference implementation for this pattern, and their approach of locking on the idempotency key during processing handles race conditions from concurrent requests with the same key.

Prompt Snippet

Require an Idempotency-Key header (UUID v4 format) on all POST endpoints that create resources or trigger side effects. Store the key, request body SHA-256 hash, and serialized response in a PostgreSQL table with a 48-hour TTL and a UNIQUE constraint on (api_key_id, idempotency_key). Use SELECT FOR UPDATE on the idempotency record to serialize concurrent requests with the same key. Return 422 if the same key is reused with a different request body hash. Return the stored response with the original status code on replay, and include an Idempotent-Replayed: true header so clients know it was a cached response.

Tags

idempotencyreliabilitypaymentsdeduplicationsafety