Idempotency and retries
Every POST create and PATCH update endpoint in the Developer Platform
API requires an Idempotency-Key header. Sending the same key twice with
the same request body returns the stored response, so a network retry
never creates duplicate resources.
Sending the key
Generate one UUID per logical operation (not per network attempt). Send it on the initial request and on every retry of that operation.
Code example
IDEMPOTENCY_KEY=$(uuidgen)
curl -X POST "https://api.carebit.co/v1/bookings" \
-H "Authorization: Bearer $CAREBIT_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $IDEMPOTENCY_KEY" \
-d '{
"patient_id": "00000000-0000-4000-8000-000000000004",
"start_time": "2026-01-01T09:00:00Z",
"service_id": "00000000-0000-4000-8000-000000000005",
"service_variant_id": "00000000-0000-4000-8000-000000000006"
}'Header contract
| Condition | Response |
|---|---|
Missing or blank Idempotency-Key |
400 idempotency_key_required |
| Key longer than 255 characters | 400 idempotency_key_too_long |
| Same key + same request body | Original status and body, plus Idempotency-Replayed: true |
| Same key + different request body | 422 idempotency_key_reused |
| Same key while an earlier request is in flight | 409 idempotency_conflict with Retry-After: 1 |
The Idempotency-Replayed: true response header indicates that the body
was replayed from storage rather than freshly computed. The status code
and body are byte-for-byte identical to the first successful response.
Retention
Idempotency records are retained for 24 hours and then purged. A retry after 24 hours is treated as a fresh request.
Retry policy
Retry 5xx responses and network failures with exponential backoff (for
example: 1s, 2s, 4s, 8s, 16s, 30s, then every minute for 15 minutes).
Send the same Idempotency-Key on every retry so a duplicate request
never mutates state twice.
Do not retry 4xx responses other than:
409 idempotency_conflict- retry after the value in theRetry-Afterheader (defaults to 1 second).429 rate_limited- retry after the value in theRetry-Afterheader (defaults to 60 seconds).
These recipient-side retry guidelines are separate from the webhook delivery retry schedule described in Webhook retries.