Skip to main content
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

{
  "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:
{
  "detail": [
    {
      "type": "missing",
      "loc": ["query", "ticker"],
      "msg": "Field required"
    }
  ]
}

Status code reference

StatusWhenWhat to do
200 OKSuccess.
201 CreatedResource created (POST).
204 No ContentSuccess, body intentionally empty.
400 Bad RequestYour request is malformed (e.g. invalid event_type).Read detail, fix the input.
401 UnauthorizedMissing / bad Bearer token, or token revoked.Mint a fresh key.
403 ForbiddenToken valid but tier doesn’t permit this endpoint.Upgrade tier or pick a free-tier endpoint.
404 Not FoundNo such market / job / strategy / etc.Verify the ID.
409 ConflictResource already exists (e.g. duplicate paper-strategy name).Pick a different identifier.
422 Unprocessable EntityValidation failed on a typed field.See per-field detail array.
429 Too Many RequestsRate limit hit.Back off, see Rate limits.
500 Internal Server ErrorBug on our side.Retry once; if it persists, email us.
502 Bad GatewayUpstream (ClickHouse / Postgres / Redis) temporarily unreachable.Retry with exponential backoff.
503 Service UnavailableMaintenance 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 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 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.