Help API

    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 body409 idempotency_key_conflict. The server fingerprints the request body and refuses to associate one key with two different requests.
    • Same key, request still in flight409 idempotency_in_progress with Retry-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-Match is 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.