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

# Error codes

> Every code, what causes it, and whether retrying helps

Every error has the same two fields. Codes are contractual; messages may be
reworded without notice.

```json theme={null}
{ "code": "VALIDATION_ERROR", "message": "items must be a non-empty array" }
```

## Every code

| Code                              | HTTP  | Retry             | Meaning and remedy                                                                                                    |
| --------------------------------- | ----- | ----------------- | --------------------------------------------------------------------------------------------------------------------- |
| `VALIDATION_ERROR`                | `400` | No                | Malformed body, missing field, bad or mixed currency, unsafe integer, or a missing `Idempotency-Key`. Fix and resend. |
| `QUANTITY_LIMIT_EXCEEDED`         | `400` | No                | An item `qty` above 1000. Split into several items or orders.                                                         |
| `DENOMINATION_NOT_SUPPORTED`      | `400` | No                | That amount cannot be served for that product. Use a published denomination.                                          |
| `PRODUCT_TEMPORARILY_UNAVAILABLE` | `400` | **After a delay** | The product is real but nothing can serve it right now.                                                               |
| `AUTH_INVALID_KEY`                | `401` | No                | Missing headers, unknown key id, or an inactive key.                                                                  |
| `AUTH_BAD_SIGNATURE`              | `401` | No                | Malformed `X-Signature`, wrong signature, or one already used.                                                        |
| `AUTH_TIMESTAMP_SKEW`             | `401` | No                | Timestamp outside ±300 seconds. Fix the clock, not the request.                                                       |
| `SCOPE_FORBIDDEN`                 | `403` | No                | Authenticated, but the key lacks the scope for this route.                                                            |
| `ORDER_NOT_FOUND`                 | `404` | No                | Unknown id, malformed id, or someone else's order — deliberately indistinguishable.                                   |
| `IDEMPOTENCY_KEY_REUSED`          | `409` | No                | Same key, different body. Nothing is created. Use a fresh key for a genuinely new order.                              |
| `PARTNER_ORDER_REF_DUPLICATE`     | `409` | No                | That reference already exists. The response carries the existing `order_id` — treat as already placed.                |
| `ORDER_NOT_IN_RETRIEVABLE_STATE`  | `409` | **Keep polling**  | The order is not retrievable yet. Expected while `PENDING` or `UNDER_REVIEW`; permanent on `FAILED` or `REFUNDED`.    |
| `RATE_LIMITED`                    | `429` | **Yes**           | Honour the `Retry-After` header, in whole seconds, never below 1.                                                     |

A request body above 1 MiB returns `413`. An unexpected server error returns
`500`.

## Retry guidance

| Situation                                     | What to do                                                                                                                                                                                                                          |
| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `429` or `500`                                | Retry with exponential backoff. Honour `Retry-After` when present.                                                                                                                                                                  |
| **`POST /orders` times out or returns `500`** | **Do not assume it failed.** Retry with the same `Idempotency-Key` and byte-identical body, or query `GET /orders?partner_order_ref=…` to find out. Creating a second order with a new reference risks buying the same cards twice. |
| Any other `4xx`                               | Do not retry unchanged. Fix the request.                                                                                                                                                                                            |
| `PRODUCT_TEMPORARILY_UNAVAILABLE`             | Retry after a delay, not immediately.                                                                                                                                                                                               |
| `ORDER_NOT_IN_RETRIEVABLE_STATE`              | Keep polling the order. Expected while fulfilment is in progress.                                                                                                                                                                   |
