---
title: Idempotency
description: Repeat a request safely. The same key always gives the same answer and never a second charge.
group: concepts
order: 3
---

Every sale (`POST /api/v1/airtime` and `POST /api/v1/data`) needs an `Idempotency-Key` header: any string up to 128 characters, unique to that sale. Your own order id works well. Without it the request is refused with `400 IDEMPOTENCY_KEY_MISSING`.

```bash
-H "Idempotency-Key: order_1042"
```

## What happens on a repeat

| You send | You get |
| --- | --- |
| The same key and the same body, after the first finished | The stored answer, with the same status code and an `Idempotent-Replayed: true` header |
| The same key while the first is still running | `409 IDEMPOTENCY_IN_PROGRESS` |
| The same key with a different body | `422 IDEMPOTENCY_FINGERPRINT_MISMATCH` |

"The same body" means the same bytes. So if a request times out, send it again with the same key and body. You will never be charged twice. Refusals (`4xx`) are stored and replayed too; after a `5xx` the key is free to use again.

## Your own reference

You can also send `client_reference` in the body: 1 to 128 characters, unique per mode. It comes back on the transaction and in every webhook, and is the easiest way to match a sale to your order. A second sale with the same `client_reference` is refused with `409 CONFLICT`, and the message names the first sale's reference.
