Errors

All errors return a JSON body with a detail field. It holds either a plain string (errors raised by the API itself) or the underlying database error object (errors raised by the query engine).

{"detail": "Unauthorized."}
{
  "detail": {
    "code": "PGRST100",
    "message": "\"failed to parse filter (bogus.1)\"",
    "details": "unexpected \"b\" expecting \"not\" or operator (eq, gt, ...)",
    "hint": null
  }
}

HTTP status codes

StatusMeaningTypical cause
200 OKSuccess-
206 Partial ContentPartial resultA Range request that returned fewer rows than the full set
401 UnauthorizedMissing or invalid credentialsAbsent, malformed or revoked client id / secret
404 Not FoundEndpoint does not existA path that is not one of the documented endpoints
405 Method Not AllowedWrite attemptedPOST, PATCH, PUT or DELETE - the API is read-only
408 Request TimeoutQuery exceeded 25sUnbounded read, expensive count, or a wildcard text search
429 Too Many RequestsRate limit exceededToo many requests per second - the limit is shared across all users; back off and retry
500 Internal Server ErrorQuery rejected or unexpected failureMalformed filter, unknown column or table, type mismatch
502 / 504Gateway errorResponse too large, or an upstream timeout - reduce the page size

Note: query errors that are logically client mistakes - a bad filter, an unknown column - currently surface as 500 with the database error object in detail, rather than as 400. Key your error handling on the code field inside detail, not on the HTTP status alone.

Database error codes

CodeMeaningFix
PGRST100Filter could not be parsedCheck the operator.value form, e.g. eq.5 not =5
PGRST103Offset beyond the end of the tableRead the total from Content-Range before paging deep - see Paging past the end
PGRST200No relationship between tablesResource embedding is not supported - join client-side, see Not supported
PGRST205Table not foundCheck the endpoint name against the API reference
42703Column does not existCheck spelling in select, order or the filter
42804Type mismatchUsually is.true on a numeric ind_* column - use eq.1

Debugging checklist

  1. GET /health - no credentials needed. If this fails, the service is down.
  2. GET /whoami - confirms your credentials are valid and shows the project they resolve to. A 401 here means a credentials problem, not a query problem.
  3. Add limit=1 - if a failing query then succeeds, it was a timeout, not a syntax error.
  4. Strip the query back to ?limit=1 and add filters one at a time to find the one at fault.
  5. Read the hint and details fields in the error body; PostgREST often names the exact column or suggests the intended table.

Did this page help you?