> For the complete documentation index, see [llms.txt](https://docs.shredpay.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.shredpay.xyz/developers/reference/error-codes.md).

# Error Codes

Every error response carries a stable `code` field. Use it for programmatic handling — the human `message` may change.

```json
{
  "error": {
    "code": "LIMIT_EXCEEDED",
    "message": "Daily USD limit reached",
    "request_id": "req_01HRZK..."
  }
}
```

Outline of codes (full reference to come):

| HTTP | Code                   | Meaning                                          |
| ---- | ---------------------- | ------------------------------------------------ |
| 400  | `BAD_REQUEST`          | Malformed body or missing required field.        |
| 400  | `INVALID_CHAIN`        | Unknown `chain_id`.                              |
| 400  | `ROUTER_NOT_AVAILABLE` | Sponsored op called on a chain without Router.   |
| 401  | `UNAUTHENTICATED`      | Missing `X-Api-Key`.                             |
| 401  | `INVALID_KEY`          | Key not found or revoked.                        |
| 403  | `PERMISSION_DENIED`    | Key lacks `trade` permission.                    |
| 403  | `CHAIN_NOT_ALLOWED`    | `chain_id` not in key's `allowed_chains`.        |
| 403  | `LIMIT_EXCEEDED`       | Daily or monthly USD cap hit.                    |
| 403  | `ADDRESS_BLOCKED`      | Counterparty failed screening.                   |
| 403  | `SUB_WALLET_FROZEN`    | Wallet under manual review.                      |
| 404  | `NOT_FOUND`            | Unknown `tx_id`, `market_id`, etc.               |
| 429  | `RATE_LIMITED`         | Too many requests; back off.                     |
| 500  | `INTERNAL_ERROR`       | Server-side failure; safe to retry with backoff. |
| 502  | `UPSTREAM_ERROR`       | Chain RPC or Privy unreachable; retry.           |
