An idempotency key is a unique value that a client sends with a request to allow the server to detect and safely ignore duplicate submissions. If a payment request times out and the client retries, the server uses the idempotency key to recognise the duplicate and return the original response without charging the card twice.

UUIDs are the standard choice for idempotency keys because they can be generated client-side without coordination. The version matters for this use case.

Which UUID Version to Use

Use UUID v4 for idempotency keys — never UUID v7.

Idempotency keys must be:

  1. Unique — no two requests should share a key
  2. Unguessable — an attacker should not be able to predict or reconstruct a valid key

UUID v4 satisfies both requirements. Its 122 bits come entirely from a CSPRNG, making the key computationally infeasible to guess.

UUID v7 fails requirement 2. The high 48 bits encode the Unix timestamp in milliseconds. An attacker who knows approximately when a request was made can reduce the search space from 2¹²² to 2⁷⁴ — still large, but meaningfully weaker. For payment APIs and financial workflows, this tradeoff is not acceptable.

The Standard Pattern

POST /payments
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
Content-Type: application/json

{
  "amount": 9900,
  "currency": "usd",
  "customer_id": "cus_abc123"
}

The server workflow:

  1. Look up the idempotency key in the store
  2. If found and complete: return the stored response immediately (no re-processing)
  3. If found and in-flight: return 409 Conflict (another request is processing)
  4. If not found: process the request, store the key + response, return the response

Generating Idempotency Keys

JavaScript:

const key = crypto.randomUUID(); // UUID v4, built-in to all modern runtimes

Python:

import uuid
key = str(uuid.uuid4())

Go:

import "github.com/google/uuid"
key := uuid.New().String() // uuid.New() generates v4

Java:

String key = UUID.randomUUID().toString(); // v4

Storage Strategies

Idempotency keys should be stored in a fast, atomic store:

The Stripe API documentation is the most cited reference implementation. Stripe stores keys for 24 hours and returns a 409 Conflict for concurrent requests with the same key.

Header Naming

No single standard defines the idempotency key header name, but these are the most common conventions:

HeaderUsed by
Idempotency-KeyStripe, PayPal, most fintech APIs
X-Idempotency-KeySome internal APIs
X-Request-IDGeneral request deduplication (slightly different semantics)

The IETF draft for the Idempotency-Key header is working toward standardisation.

Frequently asked questions

Which UUID version should I use for idempotency keys?

Always use UUID v4 for idempotency keys. An idempotency key must be unguessable — UUID v7 embeds a millisecond timestamp in the high bits, which narrows the guessability space. UUID v4's 122 bits of CSPRNG randomness (from crypto.randomUUID() or equivalent) provides the unpredictability that idempotency keys require.

Are these UUIDs cryptographically secure?

The randomness is, yes — it comes from the Web Crypto API. That said, a UUID is an identifier, not a secret; don't use one as a password or an unguessable capability token on its own.

Should I use v4 or v7?

Use v7 for database primary keys (time-sortable, index-friendly) and v4 for anything where creation order could leak information, like tokens or share links.

Should I use UUID v4 or UUID v7 for idempotency keys?

Use UUID v4 for idempotency keys. An idempotency key must be unguessable — if an attacker can predict or reconstruct your key, they can replay requests as if they were legitimate. UUID v7 embeds a millisecond timestamp in the high bits, which narrows the search space for guessing. UUID v4's 122 bits of CSPRNG randomness provides the unpredictability that idempotency keys require.

How long should I store idempotency keys?

Store idempotency keys for at least 24 hours, matching the retry window you expose to clients. Stripe's idempotency documentation recommends a 24-hour window. Payment systems and financial APIs typically retain keys for 7–30 days to cover delayed retries and dispute workflows.