> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kordless.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Idempotency

> Prevent duplicate operations with idempotency keys.

Idempotency keys prevent duplicate operations when you retry a request. If a network timeout or transient error occurs, you can safely retry with the same key and the operation will replay instead of creating a duplicate.

## When idempotency is required

The `Idempotency-Key` header is required on write operations that create or mutate state:

| Endpoint                                                     | Required                        |
| ------------------------------------------------------------ | ------------------------------- |
| `POST /v1/accounts/{id}/quotes`                              | Yes                             |
| `POST /v1/accounts/{id}/quotes/{quoteId}/commitment`         | No (idempotent by quote ID)     |
| `POST /v1/accounts/{id}/quotes/{quoteId}/commitment/confirm` | No (idempotent by quote ID)     |
| `POST /v1/accounts/{id}/quote-simulations`                   | Not applicable (non-persistent) |
| `GET` endpoints                                              | Not applicable (read-only)      |

<Info>
  Commitment creation is idempotent by the quote ID — the same quote can only have one commitment. Confirming a commitment is idempotent by the quote ID and external reference.
</Info>

## How to use it

Pass an `Idempotency-Key` header on every quote creation request:

```bash theme={null}
curl -X POST https://your-kordless-instance.com/v1/accounts/acct_abc123/quotes \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: my-unique-key-123" \
  -d '{
    "context": {},
    "services": [
      { "service": "oil_change", "selections": { "vehicle_type": "sedan" } }
    ]
  }'
```

## Key rules

* **Format**: Any string up to 200 characters. Trimmed of whitespace.
* **Uniqueness**: Use a unique key per logical operation. A UUID, a nanoid, or a deterministic hash of your request payload all work.
* **Scope**: The key is scoped to your account. Two different accounts can use the same key without conflict.
* **Replay**: Retrying with the same key returns the original response. The quote is not duplicated.
* **Expiry**: Idempotency keys are retained for a reasonable window. If you retry days later, a new quote may be created.

## Missing key error

If you omit the `Idempotency-Key` header on a write operation that requires it, the API returns:

```json theme={null}
{
  "error": {
    "type": "invalid_request",
    "code": "missing_idempotency_key",
    "message": "Provide an Idempotency-Key header (≤200 chars) so retries replay instead of duplicating.",
    "request_id": "req_abc123"
  }
}
```

## Retry pattern

When a request fails due to a network error or a `5xx` response, retry with the same `Idempotency-Key`:

1. Generate a unique key for the logical operation.
2. Send the request with the key.
3. If you receive a timeout or `5xx`, retry with the same key.
4. If you receive a `4xx`, the request was processed — do not retry blindly. Check the error code.
5. If you receive a `2xx`, the operation succeeded. Retrying with the same key returns the same response.

<Warning>
  Do not generate a new idempotency key on every retry. The entire point is that the same key replays the same operation. A new key creates a new quote.
</Warning>
