Error codes#

All errors use the standard envelope:

{
  "success": false,
  "message": "Email must be a valid email address",
  "errors": ["Email must be a valid email address"]
}
JSON

HTTP statuses#

StatusCodeMeaning
400invalid_inputMalformed body, missing/invalid field
401unauthorizedMissing or invalid key / token
403forbiddenAuthenticated but not allowed (scope, RLS, cross-project key)
404not_foundResource or table does not exist
409conflictDuplicate email/phone, conflicting state
429quota_exceededPlan request limit reached
500internal_errorServer error

Friendly messages#

Bare statuses are expanded to helpful messages:

  • 401: "Invalid or missing credentials"
  • 403: "You do not have permission to perform this action"
  • 404: "The requested resource was not found"
  • 409: "The resource already exists or is in a conflicting state"
  • 429: "You have reached your plan's request limit"

Validation messages#

Field validations read naturally and appear in errors:

  • "Email must be a valid email address"
  • "Password must be at least 8 characters"
  • "Password must contain at least one letter and one number"
  • "Full name is required"
  • "Phone is required"
  • "Phone must include a valid country code, e.g. +255712345678 or +254712345678"
  • "API key lacks the records:write scope - update the key under Access -> API Keys"

RLS denials#

Row-level security denials return 403 with the friendly "You do not have permission" message. See Security.