Configuring Request Replay and Idempotency

1. Implementing Idempotency Keys

Example: Idempotent POST

POST /v1/payments HTTP/1.1
Idempotency-Key: a1b2c3d4-5678-90ab-cdef-1234567890ab
Content-Type: application/json

{"amount": 1000, "currency": "USD"}
PropertyValue
FormatUUID v4 or random ≥ 16 bytes
ScopePer-client / per-endpoint
Storage TTL24 hours (Stripe), 7 days (some)
ResponseReplay cached result on duplicate

2. Configuring Idempotent Methods

MethodIdempotent?
GET, HEAD, OPTIONSYes (safe)
PUTYes
DELETEYes
POSTNo (need Idempotency-Key)
PATCHUsually no

3. Using Request Deduplication

Dedup SourceNotes
Idempotency-Key headerExplicit client opt-in
Body fingerprintsha256 of canonical body
Natural keyOrder ID, txn ID
Replay windowSlow expire to catch retries

4. Setting Idempotency Window

ProviderWindow
Stripe24 hours
PayPal72 hours
AWS10 min (some APIs)
Recommended≥ max retry duration (often 24h)

5. Implementing Idempotency Storage

Example: Redis idempotency check

String key = "idem:" + clientId + ":" + idemKey;
String existing = redis.get(key);
if (existing != null) {
  return CachedResponse.from(existing);  // replay
}
// Lock to avoid concurrent execution
if (!redis.set(key + ":lock", "1", "NX", "EX", 60)) {
  return Response.status(409).entity("In progress").build();
}
Response r = execute();
redis.setex(key, 86400, serialize(r));
return r;

6. Using Conditional Requests

HeaderBehavior
If-MatchUpdate only if ETag matches
If-None-MatchCreate only if not exists (*)
If-Modified-Since304 if not modified
If-Unmodified-Since412 if changed

7. Configuring Replay Protection

MechanismPurpose
NonceOne-time random value
TimestampReject if > 5 min skew
Signed requestHMAC includes timestamp+nonce
Used-nonce cacheReject duplicates within window

8. Implementing Request Fingerprinting

Example: Canonical body hash

String canonical = JsonCanonicalizer.canonicalize(body);
String fingerprint = sha256Hex(method + path + canonical);

9. Setting Up Replay Attack Prevention

CheckReject If
Timestamp window|now - req_time| > 300s
Nonce seenAlready in nonce cache
Signature invalidHMAC mismatch
TLS sessionNot from current session

10. Configuring Idempotency Headers

HeaderDirection
Idempotency-KeyRequest (client)
Idempotency-Replayed: trueResponse (server)
Idempotency-ExpiryResponse