---
title: Idempotency
description: The Idempotency-Key header lets you safely retry generation requests without double-charging credits.
---

Send an `Idempotency-Key` header with a unique UUID v4 on every `POST` request that submits a generation. If the network drops and you retry with the same key and the same parameters, Clipia returns the **same** `request_id` — no duplicate generation and no second charge. The key is stored for 24 hours.

## Header

<TypeTable
  type={{
    'Idempotency-Key': {
      type: 'string (UUID v4)',
      description: 'A unique key for one logical request. The same key + same parameters returns the same request_id with no second charge. Stored for 24 hours.',
      required: false,
    },
  }}
/>

## How to use it

<Tabs items={['cURL', 'TypeScript', 'Python']}>

<Tab value="cURL">

```bash
curl -X POST https://api.clipia.ai/v1/models/nano-banana-2 \
  -H "Authorization: Key $CLIPIA_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 8f3a1c7e-2b41-4d2a-9c0e-1200304cf45b" \
  -d '{ "input": { "prompt": "a sunset over mountains, cinematic" } }'
```

</Tab>

<Tab value="TypeScript">

```ts
import { createClient } from 'clipia-ai';

const clipia = createClient({ apiKey: process.env.CLIPIA_KEY! });

// The SDK sets an Idempotency-Key (UUID v4) on every submit automatically.
// To reuse one key for a logical request, pass it explicitly:
await clipia.queue.submit('nano-banana-2', {
  input: { prompt: 'a sunset over mountains, cinematic' },
  idempotencyKey: '8f3a1c7e-2b41-4d2a-9c0e-1200304cf45b',
});
```

</Tab>

<Tab value="Python">

```python
import os
from clipia import Clipia

client = Clipia(api_key=os.environ["CLIPIA_KEY"])

# The SDK sets an Idempotency-Key on every submit; pass your own when needed:
client.submit(
    "nano-banana-2",
    input={"prompt": "a sunset over mountains, cinematic"},
    idempotency_key="8f3a1c7e-2b41-4d2a-9c0e-1200304cf45b",
)
```

</Tab>

</Tabs>

Generate a fresh UUID v4 for each **logical** request (not for each network retry).

## Behaviour on retry

| Scenario | Result |
|----------|--------|
| Same key + same parameters | The same `request_id` is returned. No new generation, no charge. |
| Same key + different parameters | `409 idempotency_key_reuse` |
| Retry while the first request is still processing | `409 request_in_progress` |
| Key older than 24 hours | Treated as a new logical request |

<Callout type="info" title="Retention window">
The key-to-result mapping is kept for 24 hours. After that, the same key is treated as a new request and creates a new generation.
</Callout>

<Callout type="warn" title="POST only, no sensitive data">
Idempotency applies only to `POST` (submitting a generation) — it has no effect on `GET`. Never put an email or other sensitive data in the key: use a random UUID v4.
</Callout>
