API Architecture and Integration Design · Designing Robust APIs
Idempotency, Retries and Concurrency Control
Make retries safe and prevent lost updates.
Networks fail, so clients retry. GET/PUT/DELETE are idempotent by definition; make POSTs safe with an Idempotency-Key header (store key → response). Prevent lost updates with optimistic concurrency: return an ETag, require If-Match on updates, and respond 412 Precondition Failed when the resource changed. Tell clients how to retry: backoff with jitter, honor Retry-After.
GET /v1/documents/doc_42 → 200, ETag: "v7"
PUT /v1/documents/doc_42
If-Match: "v7" → 200, ETag: "v8" (success)
# another client still holding v7:
PUT /v1/documents/doc_42
If-Match: "v7" → 412 Precondition Failed (reload and merge)
POST /v1/payments
Idempotency-Key: 3c8d... → 201 (first) / same 201 replayed on retry
Common pitfalls
- Retrying non-idempotent POSTs without keys (double charges).
- Last-write-wins updates silently losing edits.
- Idempotency keys not scoped per client.
Key points
- Idempotency keys for unsafe operations
- ETag + If-Match for concurrency
- Clear retry guidance
Further reading: IETF: Idempotency-Key header
Practice questions
How does If-Match prevent lost updates?
Answer
The server only applies the update if the resource's current ETag matches the version the client read; otherwise it returns 412 so the client can reload and merge.
Is DELETE idempotent if the second call returns 404?
Answer
Yes — idempotency concerns the server state (the resource is gone after one or many calls), not identical responses.
Open in the app to mark lessons complete, take notes and track your progress.