# Idempotency

Make write requests safe to retry with the Idempotency-Key header.


Send an `Idempotency-Key` header (1 to 255 characters, kept 24 hours) on a write, and a retry of the same request returns the original response instead of applying it twice. If a write times out, you cannot tell whether it happened, so this is how you retry safely.

```bash
curl -X POST https://kleiobase.com/api/v1/workspaces/WORKSPACE_ID/people \
  -H "Authorization: Bearer kb_live_YOUR_KEY" \
  -H "Idempotency-Key: 6f1c2a4e-create-john-smith" \
  -H "Content-Type: application/json" \
  -d '{"given_name": "John", "surname": "Smith"}'
```

Use any unique string of 1 to 255 characters, such as a UUID. A key outside that range returns `422 validation_failed`.

## What happens on a retry

Keys are kept for 24 hours.

- **Same key, same request:** you get the original response again, including the original body and its original `request_id`. The write is not repeated. Other headers are not replayed, but a replay carries `Idempotent-Replayed: true` so you can tell.
- **Same key, different request:** `409 conflict`. A key belongs to one request.
- **Same key while the first request is still running:** `409 conflict`. Wait and retry. If the first request never finished (for example, our server restarted mid-request), the key stops blocking after 30 minutes and the retry runs.

## Which responses are stored

- A success, or an error that means the request was understood and refused for good (for example `404` or `403`), is stored and replayed.
- `402`, `409` and `429` responses and `422 validation_failed` do not use up the key: nothing changed, so retry with the same key once the cause is fixed. For example, buy credits after a `402`, wait for `Retry-After` after a `429`, or wait for the record to finish processing after a `409`.
- A `5xx` releases the key, so a retry runs again.

## Where it applies

All write endpoints honor `Idempotency-Key`, with one exception:

- **Uploads are not idempotent.** Retrying `POST /records` creates another record, and retrying `POST /gedcom/imports` uploads the file again. See [Uploads](/developers/docs/uploads) and [GEDCOM import and export](/developers/docs/gedcom).

Without a key, a retry of some writes will fail on its own. For example, confirming a record twice returns `409` because it is already confirmed.

Canonical: https://kleiobase.com/developers/docs/idempotency
