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"]
}
JSONHTTP statuses#
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_input | Malformed body, missing/invalid field |
| 401 | unauthorized | Missing or invalid key / token |
| 403 | forbidden | Authenticated but not allowed (scope, RLS, cross-project key) |
| 404 | not_found | Resource or table does not exist |
| 409 | conflict | Duplicate email/phone, conflicting state |
| 429 | quota_exceeded | Plan request limit reached |
| 500 | internal_error | Server 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.