Idempotency
Every write endpoint on
/v1/bookings requires an
Idempotency-Key header. The key lets you safely
retry a request after a network failure without creating a
duplicate booking or applying the same mutation twice.
When it's required
| Endpoint | Required? |
|---|---|
POST /v1/bookings |
yes |
POST /v1/bookings/:uid/cancel |
yes |
POST /v1/bookings/:uid/reschedule |
yes |
PATCH /v1/bookings/:uid |
yes |
Calling one of these without the header returns
400 missing_idempotency_key.
Picking a key
Any caller-supplied string up to 255 characters. Use something unique per logical operation — a UUID is the safest default:
Idempotency-Key: 1f0a3b6e-7c1d-4a3e-9e91-9b6c0f8b18f4
Reuse the same key on retries of the same operation. Use a different key for a different operation, even when the body looks similar.
What "replay" means
Each (account, Idempotency-Key) pair is
remembered for 24 hours. Within that window:
- Same key, same body → the original response is replayed, including its HTTP status code. The work is not executed twice.
-
Same key, different body →
409 idempotency_key_conflict. The server fingerprints the request body and refuses to associate one key with two different requests. -
Same key, request still in flight →
409 idempotency_in_progresswithRetry-After: 1. The first attempt is mid-execution; retry shortly. - First attempt errored → the key reservation is released so a retry can proceed with the same key. Only successful responses are cached.
Body comparison uses a canonical JSON fingerprint — key order and whitespace don't matter.
What it does not protect against
-
Bumping resource versions. Idempotency is
request-level; optimistic locking via
If-Matchis what guards concurrent edits. - Different keys, same intent. If you retry with a fresh key the server has no way to know it's a retry — you'll create a second booking.
Example
# First attempt
curl -X POST https://api.42min.us/v1/bookings \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: 1f0a3b6e-7c1d-4a3e-9e91-9b6c0f8b18f4" \
-H "Content-Type: application/json" \
-d '{"event_type_id":"…","start":"2026-05-20T15:00:00Z","attendee":{"email":"a@b.com"}}'
# → 201 { "data": { "uid": "abc…", … }, "meta": { "request_id": "req_…" } }
# Network failure on the way back? Retry with the SAME key:
curl -X POST https://api.42min.us/v1/bookings \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: 1f0a3b6e-7c1d-4a3e-9e91-9b6c0f8b18f4" \
-H "Content-Type: application/json" \
-d '{"event_type_id":"…","start":"2026-05-20T15:00:00Z","attendee":{"email":"a@b.com"}}'
# → 201 (replayed) — the SAME booking, no duplicate.
Best practices
- Generate the key before sending the request and store it alongside the pending operation in your own system.
- Use a fresh key for each new operation — never reuse one across semantically different requests.
-
On
409 idempotency_in_progress, sleep briefly and retry — the original request will land or fail within seconds. -
On
409 idempotency_key_conflict, your client has a bug — you're reusing a key for two different requests. Mint a new key.
Last updated May 14, 2026.