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

# Errors

> The error envelope, what each status code means, why invalid input returns 500, and what is safe to retry.

Errors share one envelope:

```json theme={null}
{
  "message": "Valid access token required.",
  "error": "Unauthorized",
  "statusCode": 401
}
```

Field order varies and `error` is sometimes absent; the unknown-order `500` returns only `statusCode` and `message`. Branch on `statusCode`, read `message` for detail, and treat `error` as optional. One route adds detail: a bad query parameter on `GET /v1/orders` returns `400` with `message: "Validation failed"` plus an `errors` array, one entry per field with `path`, `code`, `expected`, `received`, and its own `message`.

## Status codes

| Code  | When                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `200` | Success on every `GET`. `POST /auth/refresh` is specified as `200` but currently returns `401` for every request; see [Authentication](/api-reference/authentication).                                                                                                                                                                                                                                                                                                          |
| `201` | Success on `POST /v1/orders/create` and `POST /auth/siwx/verify`. Test for `201`, not `200`.                                                                                                                                                                                                                                                                                                                                                                                    |
| `400` | Framework-level validation: a non-numeric token ID, a missing or non-boolean `amountIsDeposit`, a request body that isn't valid JSON, or a bad `GET /v1/orders` query parameter. A non-numeric or missing quote `amount` is not one of these; see the note below.                                                                                                                                                                                                               |
| `401` | Missing or invalid credentials. `Valid access token required.` points at the tenant key on pricing and order calls; `Access token not found in cookies or authorization header.` means a JWT endpoint needs a Bearer token. On `POST /auth/siwx/verify`, `401` also covers every named verification failure (`EVM signature verification failed: ...`, `Nonce not found in the message.`, `Invalid or expired nonce.`) and a wrong tenant key (`x-tenant-api-key not present`). |
| `404` | The route itself doesn't exist, such as the [SSE path](/api-reference/order-status-stream) with `/v1` added. Never returned for a missing order.                                                                                                                                                                                                                                                                                                                                |
| `500` | Invalid input with a descriptive message, unknown order UUIDs, genuine server errors, and `POST /auth/siwx/verify` called with no tenant key header or a body missing required fields.                                                                                                                                                                                                                                                                                          |

<Note>
  `GET /v1/tokens/quote` doesn't validate `amount`. Omit it or send `amount=abc` and you still get `200`, with `depositAmount: null`, `settleAmount: 0`, `exchangeRate: 0`, and `depositTokenUsdValue: null`. Validate the amount before calling, and treat `exchangeRate: 0` as no quote.
</Note>

## Invalid input returns 500

Business validation (an unknown or inactive token ID, a malformed address, a bad amount) fails with `500` and a message naming the problem, so match on the message text:

| `message`                                   | Cause                                                                                                                                                           |
| ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Invalid deposit token id provided: 999999` | Unknown `depositTokenId`; same pattern for the settle side.                                                                                                     |
| `Invalid amount: 0`                         | Zero `amount` on `GET /v1/tokens/quote`. Quotes only: `POST /v1/orders/create` accepts `intendedAmount: 0` and returns `201` with `initialQuote: 0`.            |
| `Invalid ETH address: not-an-address`       | Bad or missing `receivingAddress` (`undefined` when missing). The chain code is the settle token's `blockchain.network`: `ETH`, `BTC`, `SOL`, `TRX`, and so on. |
| `Couldn't find trade path for 86 -> 231`    | A token on either side of a quote or swap-limits call is in the catalog but `active: false`. Filter on `active` before offering a pair.                         |
| `Internal Server Error`, no `error` field   | Unknown or malformed UUID on `GET /v1/orders/{uuid}`.                                                                                                           |

When the message names a field or value, the fix is the input. Surface a correction prompt, not an outage page.

One exception: a `POST /v1/orders/create` body with a missing or string-typed token ID (`{}`, or `"depositTokenId": "231"`) returns `500` with a multi-line message that is raw internal database text (it names a Prisma query). That text can change without notice, so don't match on it; validate the body shape before sending and treat the response as a bad request.

## What to retry

Fix and resend, never retry as-is: `400`, every `401`, and any `500` whose message starts with `Invalid` or `Couldn't find trade path`. Retry idempotent `GET`s with exponential backoff on a generic `500`, a network failure, or a timeout; no rate-limit headers are published, so back off conservatively. Retry `POST /v1/orders/create` with care, because each success creates a new order and deposit address. Record every returned `uuid` before trying again, and deduplicate in your own storage.
