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

# Idempotency

> Retry a request safely, so one order never becomes two.

A request can time out after we've acted on it. If you send it again, you need to know it won't place a second order. An `Idempotency-Key` gives you that: we tie the key to the first request, and every retry with the same key returns that first result.

## Which requests need a key

| Request                 | Key      |
| ----------------------- | -------- |
| `POST /v1/orders`       | Required |
| `POST /v1/applications` | Required |
| `POST /v1/allocations`  | Required |
| Every other request     | Not used |

## Choose a key

* Generate one key for each order, application or allocation, such as a UUID.
* Save it with your own record before you send the request, so a crash on your side can't lose it.
* Send the same key on every retry of that request.
* Use 1 to 255 printable ASCII characters, with no spaces. We compare keys byte for byte.
* Send the header once. Two `Idempotency-Key` headers return `400 invalid_request`.

Keys never expire, and each key belongs to one request for good. Your keys are separate from other partners' keys.

## What a retry returns

| You send                                    | We return                                                                                                                   |
| ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| A new key                                   | The result of this request. `201` when it creates something.                                                                |
| A key you've used, with the same request    | `200` and the resource as it is now. We don't send anything again.                                                          |
| A key you've used, with a different request | `409 duplicate_order`, `duplicate_application` or `duplicate_allocation`. The message names the resource that owns the key. |

For an order, we compare `account`, `symbol`, `side`, `quantity`, `type`, `time_in_force` and `price_kobo` after we read them, so a retry with different spacing or field order is still the same request. Account codes and symbols are compared without regard to letter case. For an allocation we compare `account` and `amount_kobo`, and for an application every field.

A retry returns the first result even when the result was a refusal. A retried order that was rejected returns `422 order_rejected` again, and one that was never sent returns `503 order_not_sent` again. Applications and allocations work the same way.

We look up the key before we check the account or contact the broker, so a retry gets its answer even when the broker can't be reached.

## When to use a new key

Whether you can reuse a key depends on whether we stored the request.

| Response                                                               | Stored?                    | What to do                                                                                                     |
| ---------------------------------------------------------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------- |
| `201 Created` or `200 OK`                                              | Yes                        | Nothing. The key now belongs to this resource.                                                                 |
| A timeout, or no response                                              | Maybe                      | Send the same request with the same key.                                                                       |
| `500 internal_error`, `503 service_unavailable`                        | Maybe                      | Send the same request with the same key. Never a new key.                                                      |
| `400`, `413`, `415`                                                    | No                         | Fix the request. You can reuse the key.                                                                        |
| `429 rate_limited`                                                     | No                         | Wait `Retry-After` seconds and send it again with the same key.                                                |
| `503 exchange_unavailable`                                             | No                         | Send it again with the same key.                                                                               |
| `422 unknown_symbol`, `422 limit_exceeded`, `422 wallet_too_low`       | No                         | You can reuse the key.                                                                                         |
| `409 similar_order_unresolved`                                         | No                         | Wait until the earlier order resolves. See [Handling uncertain orders](/handling-uncertain).                   |
| `422 order_rejected`, `application_rejected`, `allocation_rejected`    | Yes, as rejected           | To try again, send a corrected request with a new key.                                                         |
| `503 order_not_sent`, `application_not_sent`, `allocation_not_sent`    | Yes, as never sent         | Send it again with a new key.                                                                                  |
| `502 exchange_error`                                                   | Depends on the request     | Contact us. Sending it again won't help.                                                                       |
| `409 duplicate_order`, `duplicate_application`, `duplicate_allocation` | Yes, under another request | Don't send it with a new key until you've checked the resource the message names. It may be the one you meant. |

<Warning>
  After a timeout or a `5xx`, never retry with a new key unless the error code tells you to. A new key is a new request, and for an order that means a second order at the exchange.
</Warning>
