Playground ↗ Postman ↗ Dashboard ↗

Errors & rate limits

All errors return a consistent JSON envelope:

{
  "error": "ERROR_CODE",
  "message": "Human-readable description",
  "detail": "...",
  "status_code": 400,
  "context": { "field": "..." }
}

Status codes

StatusCommon codesMeaning
400INVALID_REQUEST, NO_CHAPTERSBad input
401MISSING_AUTH, INVALID_KEYAuth failure
403TEST_USAGE_LIMIT, SEAT_LIMIT_REACHED, PLAN_REQUIREDPolicy denied
404NOT_FOUNDResource not found
422(Pydantic validation)Request body / form field invalid
429RATE_LIMITTenant or user rate limit exceeded
500INTERNAL_ERRORServer bug — contact support with X-Request-Id
502/503UPSTREAM_UNAVAILABLELLM or vector DB upstream issue — retry with backoff

When you get rate-limited

Read Retry-After and back off. Don’t retry tighter than the value it returns. If you’re consistently hitting limits, upgrade your tier from the Dashboard.

When the LLM upstream fails

The API surfaces upstream failures as 502/503 with X-Request-Id. Retry with exponential backoff (start at 1s, cap at 30s). If a single course generation fails halfway, use POST /courses/{id}/resume — it only re-runs the missing chapters.