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

# Errors

> How the API reports failures, and the machine codes you can branch on.

Every error is returned as `application/problem+json` ([RFC 9457](https://www.rfc-editor.org/rfc/rfc9457))
with an HTTP status, a stable machine `code`, and a `request_id` you can quote to
support.

```json theme={null}
{
  "type": "https://developer.sodacards.com/errors/insufficient_balance",
  "title": "Insufficient balance",
  "status": 402,
  "detail": "Your wallet balance does not cover this order. Top up and try again.",
  "code": "insufficient_balance",
  "request_id": "req_9x8y7z"
}
```

Branch on `code`, not on `title` or `detail`: the status frames the category, the
`code` names the exact reason, and several codes can share one status.

## Common codes

| Code                      | Status | Meaning                                                     |
| ------------------------- | ------ | ----------------------------------------------------------- |
| `invalid_request`         | 400    | The request was malformed.                                  |
| `invalid_api_key`         | 401    | The key is missing, malformed, revoked or expired.          |
| `forbidden`               | 403    | The key lacks the scope for this action.                    |
| `insufficient_scope`      | 403    | The key is not authorised for this endpoint.                |
| `product_not_found`       | 404    | The product does not exist or is not available to you.      |
| `order_not_found`         | 404    | The order is not yours or does not exist.                   |
| `order_rejected`          | 400    | The order was not valid (product, quantity or inputs).      |
| `order_amount_exceeded`   | 422    | The order total is above the per-order maximum.             |
| `insufficient_balance`    | 402    | Your wallet does not cover the order.                       |
| `idempotency_key_missing` | 400    | A mutating request needs an `Idempotency-Key`.              |
| `idempotency_key_reused`  | 422    | The key was reused with a different body.                   |
| `request_in_progress`     | 409    | A request with this key is still processing; retry shortly. |
| `order_not_ready`         | 409    | Codes were requested before the order completed.            |
| `codes_unavailable`       | 404    | The completed order has no codes to reveal.                 |
| `reveal_rate_limited`     | 429    | Codes for this order were revealed too often.               |
| `rate_limited`            | 429    | You exceeded the request rate for this key.                 |

A `5xx` never leaks internal detail: its `code` is always `internal_error`. Retry a
`5xx` after a short delay.
