> Documentation index: https://beezr.io/developers/api/llms.txt

# Safe retries (idempotency)

## Add an Idempotency-Key

Create and update support `Idempotency-Key`: 1–128 visible ASCII characters. Keep the same key and the same body when you retry the same operation. Use a new key for a new operation.

The same key with the same body returns the stored response with `Idempotency-Replayed: true`. Nothing runs twice. Keys are scoped per API key and operation: `records:create` or `records:update`.

Bulk endpoints and delete don't support idempotency. Don't assume a repeated bulk create will be deduplicated.

## Handle conflicts

| HTTP | Code | What to do |
|---|---|---|
| 400 | `INVALID_IDEMPOTENCY_KEY` | Send one key in the documented format, not two keys |
| 409 | `IDEMPOTENCY_KEY_REUSED` | Don't change the body for an existing key; use a new key for a new operation |
| 409 | `IDEMPOTENCY_IN_PROGRESS` | The first call is still running within 120 seconds; wait `Retry-After: 2` before checking again |
| 409 | `IDEMPOTENCY_RESULT_UNKNOWN` | The first call crashed and its outcome is unknown; reconcile the record before starting another operation |

Conflicts include `error.details` with `operation`, optional `recordId`, and `createdAt`. An unknown result isn't run again with the same key.

## Combine with rate-limit retries

A 429 still needs a wait. Use `Retry-After` seconds for retryable rate limits, while keeping the idempotency key and body unchanged. For `MONTHLY_QUOTA_EXCEEDED`, stop until the 1st. See [Limits](/developers/api/limits/) for code in all three languages.

