Making POST Idempotent with Idempotency Keys

Learn how to use idempotency keys to make POST requests safe to retry, preventing duplicate resource creation and double-charged payments.

Advanced

Detailed Explanation

The Problem with Non-Idempotent POST

POST is not idempotent — sending the same request twice creates two resources. This is dangerous in scenarios like:

  • Payment processing (double charges)
  • Order placement (duplicate orders)
  • Email sending (duplicate notifications)

Idempotency Keys

An idempotency key is a unique identifier sent with a request. The server stores the key alongside the response. If the same key is sent again, the server returns the stored response instead of processing the request again.

Implementation

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

{
  "amount": 5000,
  "currency": "USD",
  "customer_id": "cus_123"
}

First request: Server processes the payment, stores the result keyed by the idempotency key, returns 201 Created.

Retry (same key): Server finds the stored result, returns the same 201 Created response without processing the payment again.

Server-Side Logic

1. Receive request with Idempotency-Key header
2. Check if the key exists in storage
   - If YES: Return the stored response (HTTP status + body)
   - If NO: Process the request normally
3. Store the response with the key (TTL: 24-48 hours)
4. Return the response to the client

Key Generation Best Practices

Approach Example Pros
UUID v4 550e8400-e29b-41d4-a716-446655440000 Simple, universally unique
Composite user-123:order:2026-01-15T10:30:00Z Deterministic, debuggable
Hash sha256(request_body + timestamp) Content-based deduplication

APIs That Use Idempotency Keys

  • Stripe — Required for payment intents
  • PayPalPayPal-Request-Id header
  • AWSClientToken parameter on many services
  • Google CloudrequestId query parameter

Client-Side Retry Logic

1. Generate idempotency key before first attempt
2. Send POST with the key
3. If timeout or network error: retry with the SAME key
4. If 409 Conflict: the operation was already processed
5. If 2xx: success (may be original or replayed response)

Use Case

A payment gateway processes a credit card charge via POST. The client sends the request, but the connection drops before receiving the response. The client retries with the same idempotency key. The server recognizes the key and returns the original successful response without charging the card twice.

Try It — HTTP Method Reference

Open full tool