# Idempotency

> Safe retries for non-streaming completions.


Official OpenAI SDKs auto-retry failed POSTs (connection errors, 408, 429, ≥500) up to twice. A long agent turn that fails late could otherwise run — and charge — twice. Protect non-streaming requests with an idempotency key:

```bash
Idempotency-Key: <unique-per-logical-request>
```

Replays with the same key return the stored outcome of the original attempt — same body, same charge, exactly once — marked with `x-ravchat-idempotency-replayed: true`.

<Note>
A key is **permanently bound to its first attempt**. There is no expiry and no reclaim: whatever the first attempt produced — including an error — is what that key returns forever. To retry a request that *failed*, send a **new** `Idempotency-Key`; reusing the old one replays the stored failure.
</Note>

- Keys are scoped to your API key.
- Reusing a key with a **different** request body is rejected with 409 `idempotency_key_reused`, not replayed.
- A replay that arrives while the original attempt is still running gets 409 `idempotency_key_in_progress`.
- **Streaming requests must not send this header** — they are rejected with 400 `unsupported_parameter` (SDKs don't auto-retry a stream mid-flight, so there is nothing to protect).

Strongly recommended for every non-streaming integration.
