# Errors

Error format, response codes and what to do about them.

All responses are JSON. Successful ones contain `"status": "success"`, errors contain `"status": "error"` and `message`; some errors also have a machine-readable `code`.

```json
{
  "status": "error",
  "code": "idempotency_key_reused",
  "message": "This idempotencyKey was already used for a different product"
}
```

## Response codes

| Code | When | What to do |
|---|---|---|
| 400 | Invalid ID, body or parameter. | Fix the request. |
| 401 / 403 | No key, invalid key, access or purchases disabled. | See “Authentication”. |
| 402 | Insufficient balance. No order created. | Top up and retry with the same key. |
| 404 | Product or order not found. | Check the ID. |
| 409 | The product can't be purchased. | Refresh the catalog, check availability. |
| 413 / 415 | Body over 10 KB or not JSON. | Fix the request. |
| 422 | idempotencyKey used for a different product. | Use a new key for a new purchase. |
| 429 | Rate limit exceeded. | Wait and slow down. |
| 500 | Internal error or `key_unavailable`. | Retry with the same idempotencyKey / fetch the order later. |
| 502 | The supplier didn't fulfill the order (`failed`). Money returned. | You may buy again with a new key. |
| 503 | Temporarily unavailable or maintenance (`maintenance_mode`). | Retry later. |

## Failure reasons (failureReason)

Returned in the purchase response `message` and in the `failureReason` field of a `failed` or `cancelled` order.

| failureReason | Meaning |
|---|---|
| `insufficient_balance` | Insufficient balance. |
| `purchase_disabled` | Purchases are disabled for the client. |
| `product_unavailable` | The product can't be sold now: out of stock, or the supplier's price is outside the allowed range. |
| `fulfillment_failed` | The supplier didn't fulfill the order. |
| `fulfillment_cancelled` | The supplier cancelled or refunded the order. |
| `client_not_found` | Client not found. |

The list may grow: treat an unknown value as a generic failure.
