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

# Idempotency

> Retry a transaction create without creating a second transaction: what the idempotency key and reference do, what a duplicate returns, and how to recover after a timeout.

Creating a transaction moves money, so a request that times out leaves you unsure whether it happened. Two fields in `meta` let you retry safely.

| Field | What you send |
| - | - |
| `meta.idempotencyKey` | A unique value you generate for each transaction attempt, such as a UUID. |
| `meta.reference` | Your own order or payment ID. |

Both are required on `POST /transaction`. The API checks each one separately, and each must be unique within your business. A request that reuses either value is a duplicate.

## What a duplicate returns

A duplicate returns `409 DUPLICATE_REQUEST` and creates nothing:

```json theme={null}
{
  "code": "DUPLICATE_REQUEST",
  "error": "Duplicate request",
  "details": {
    "errorMessage": "Duplicate request",
    "friendlyMessage": "A transaction with the same idempotency key or merchant reference already exists"
  }
}
```

* **The API does not return the original transaction.** The `409` tells you the key or reference is taken. To get the transaction, look it up (see below).
* **The rest of the request is not compared.** The same key with a different amount, customer, or currency is still a duplicate. The API does not apply the new request.
* **Two cases return the same code.** The first transaction already exists, or it is still being processed and a second request arrived at the same time. The message says which.
* **Your business only.** Another business can use the same key or reference.

## Keys and references are used once

Any transaction that was created keeps its key and reference, including one that later fails. To try a failed payout again, create a new transaction with a new `idempotencyKey` and a new `reference`.

The one case where you reuse a key is a retry of a request whose outcome you don't know, described next.

## Retrying after an error or a timeout

Decide from what you received:

| What happened | What to do |
| - | - |
| `400` or `422` | The API rejected the request before moving any money. Fix it and send it again. The same key is still free. |
| `429` | The request was not processed. Wait `Retry-After` seconds, then retry with the same key. See [Rate limits](/api-reference/rate-limits). |
| `500` or `503` | Retry with the same key and backoff. If the first attempt went through, you get `409`, which means the transaction exists. |
| Timeout or dropped connection | You don't know whether it was created. Retry with the same key, or look the transaction up first. |
| `409 DUPLICATE_REQUEST` | The transaction exists or is being processed. Don't send it again. Look it up. |

A failure before any money moves frees the key, so retrying a request that the API refused is safe.

### Look up the transaction

Find a transaction by the `reference` you sent:

```bash theme={null}
curl -H "x-api-key: YOUR_API_KEY" \
  "https://sandbox.api.afriex.com/api/v1/transaction?reference=YOUR_REFERENCE"
```

An empty list means no transaction was created with that reference. The result carries the transaction's `status`, and you also receive its [webhooks](/api-reference/endpoint/webhooks/transaction-events). Use whichever you prefer to confirm the outcome.

## Swaps keep their key

A `SWAP` keeps its idempotency key even when it fails, so you can't retry a failed swap with the same key. Check its status with the lookup above. To make a new attempt, send a new `idempotencyKey` and a new `reference`.

## Choosing keys and references

* Generate a new UUID for every transaction attempt, and reuse it only to retry that same attempt.
* Use your own order or payment ID as the `reference`, so you can find the transaction later.
* Store the key with the order before you send the request. After a crash, you can then retry with the same key.
* Don't build keys from values that repeat, such as a customer ID or an amount.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.