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

# Errors

> Standard HTTP status codes, predictable JSON body shape.

Every error response is JSON with a top-level `detail` field. We don't
use opaque error codes — the status code + `detail` string are the full
contract.

## Response shape

```json theme={null}
{
  "detail": "ticker must be one of BTC, ETH, SOL"
}
```

For validation errors emitted by FastAPI's request parsing, `detail`
is an array of field-level reports:

```json theme={null}
{
  "detail": [
    {
      "type": "missing",
      "loc": ["query", "ticker"],
      "msg": "Field required"
    }
  ]
}
```

## Status code reference

| Status                      | When                                                              | What to do                                 |
| --------------------------- | ----------------------------------------------------------------- | ------------------------------------------ |
| `200 OK`                    | Success.                                                          | —                                          |
| `201 Created`               | Resource created (POST).                                          | —                                          |
| `204 No Content`            | Success, body intentionally empty.                                | —                                          |
| `400 Bad Request`           | Your request is malformed (e.g. invalid `event_type`).            | Read `detail`, fix the input.              |
| `401 Unauthorized`          | Missing / bad Bearer token, or token revoked.                     | [Mint a fresh key](/docs/authentication).       |
| `403 Forbidden`             | Token valid but tier doesn't permit this endpoint.                | Upgrade tier or pick a free-tier endpoint. |
| `404 Not Found`             | No such market / job / strategy / etc.                            | Verify the ID.                             |
| `409 Conflict`              | Resource already exists (e.g. duplicate paper-strategy name).     | Pick a different identifier.               |
| `422 Unprocessable Entity`  | Validation failed on a typed field.                               | See per-field `detail` array.              |
| `429 Too Many Requests`     | Rate limit hit.                                                   | Back off, see [Rate limits](/docs/rate-limits). |
| `500 Internal Server Error` | Bug on our side.                                                  | Retry once; if it persists, email us.      |
| `502 Bad Gateway`           | Upstream (ClickHouse / Postgres / Redis) temporarily unreachable. | Retry with exponential backoff.            |
| `503 Service Unavailable`   | Maintenance window or planned outage.                             | `Retry-After` header included.             |

## Idempotency

`GET` is always safe to retry. `POST /v1/backtest` and `POST
/v1/backtest/sweep` are **not** idempotent — retrying creates a second
job. If your backtest POST timed out, query
[`GET /v1/backtest`](/docs/api-reference/backtest/list) to see whether the
first one took.

## Reporting a bug

If you hit a 500 you think shouldn't exist, or a response that
disagrees with the dashboard, email
[contact@polyquantlab.com](mailto:contact@polyquantlab.com) with:

* the request URL + headers (minus the `Authorization`)
* the request body (for POST)
* the response status + body
* approximate UTC timestamp

We can correlate logs back to nanoseconds if you give us a UTC time.
