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

# Idempotency

> Safely retry POST requests without duplicating side effects.

Use idempotency keys when retrying create or money-moving `POST` requests. If your first request times out, retry with the same key and the same body.

<CodeGroup>
  ```ts TypeScript theme={null}
  import { Ionic } from "@ionicfi/sdk";

  const ionic = new Ionic({ token: process.env.IONIC_SECRET_KEY });

  const session = await ionic.checkout.sessions.create({
    "Idempotency-Key": "order_1001_checkout",
    mode: "payment",
    line_items: [
      { name: "Starter plan", amount: 2900, currency: "usd", quantity: 1 },
    ],
    success_url: "https://example.com/success",
    cancel_url: "https://example.com/cancel",
  });
  ```

  ```bash curl theme={null}
  curl https://api.ionicfi.com/v1/checkout/sessions \
    -H "Authorization: Bearer sk_v1_test_..." \
    -H "Idempotency-Key: order_1001_checkout" \
    -H "Content-Type: application/json" \
    -d '{
      "mode": "payment",
      "line_items": [
        {
          "name": "Starter plan",
          "amount": 2900,
          "currency": "usd",
          "quantity": 1
        }
      ],
      "success_url": "https://example.com/success",
      "cancel_url": "https://example.com/cancel"
    }'
  ```
</CodeGroup>

## How it works

1. Send a stable `Idempotency-Key` for one business operation.
2. Reuse that key only when retrying the same request.
3. If the original request completed, Ionic returns the original result.
4. If the same key is reused with a different body or endpoint, Ionic rejects the request.

Replayed responses include:

```http theme={null}
Idempotent-Replayed: true
```

## Conflict behavior

| Status | Code                            | Meaning                                         |
| ------ | ------------------------------- | ----------------------------------------------- |
| `400`  | `IDEMPOTENCY_KEY_TOO_LONG`      | Header is longer than 255 characters.           |
| `409`  | `IDEMPOTENCY_KEY_IN_PROGRESS`   | Another request with this key is still running. |
| `422`  | `IDEMPOTENCY_BODY_MISMATCH`     | Same key, different body.                       |
| `422`  | `IDEMPOTENCY_ROUTE_CONFLICT`    | Same key, different endpoint.                   |
| `503`  | `IDEMPOTENCY_STORE_UNAVAILABLE` | The API cannot safely deduplicate the request.  |

## Key design

Use a key derived from your own operation ID, not a random key generated per retry.

Good:

```text theme={null}
order_1001_create_checkout_session
```

Avoid:

```text theme={null}
checkout
```
