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

# Idempotency

> Safe retry behavior for create, cancel, and replace order requests.

`Idempotency-Key` is required for order create, cancel, and replace requests.

```http theme={null}
Idempotency-Key: 0198b730-7cc2-79e4-b04e-5b5c41a50221
```

Generate the key in your backend as a UUID. Reusing the same key for the same intent is safe. Reusing the same key for a different intent is rejected.

If `idempotency_key` appears in the JSON body, it must match the `Idempotency-Key` header.

## What Counts As The Same Intent

Use one idempotency key for one business action:

| Action        | Same intent                                         |
| ------------- | --------------------------------------------------- |
| Create order  | Same pair, side, type, quantity, price, and account |
| Cancel order  | Same order ID and cancel attempt                    |
| Replace order | Same original order ID and replacement values       |

If you change the order quantity, price, side, or pair, generate a new key. If you are only retrying because the network failed or the response was uncertain, reuse the original key.

## Storage Pattern

Store the idempotency key before sending the API request.

```json theme={null}
{
  "local_action_id": "order-create-2026-05-24-0001",
  "idempotency_key": "0198b730-7cc2-79e4-b04e-5b5c41a50221",
  "request_hash": "sha256-of-your-local-intent",
  "remote_order_id": null,
  "status": "submitted"
}
```

When the API returns an `order_id`, attach it to the local action. If the request times out, retry with the same key and then reconcile the returned order state.

## Response Handling

| Response | Meaning                                                | Recommended action                                |
| -------- | ------------------------------------------------------ | ------------------------------------------------- |
| `2xx`    | Request accepted or previous matching request replayed | Store returned IDs and read status                |
| `400`    | Request is malformed or invalid                        | Fix the request before retrying                   |
| `401`    | API key missing or invalid                             | Stop and rotate or correct credentials            |
| `409`    | Key or current resource state conflicts                | Read the existing resource or create a new intent |
| `429`    | Too many requests                                      | Back off and retry with the same key              |
| `5xx`    | Outcome may be uncertain                               | Retry with the same key, then reconcile           |

## Checklist

* Store the key with your local order action before sending the request.
* Retry uncertain responses with the same key.
* Generate a new key only for a new intent.
* Treat `409` as an idempotency or current-state conflict.
* Never use timestamps alone as idempotency keys; use a UUID or similarly unique value.
* Keep idempotency keys out of logs if your logs are widely accessible.
