Error Codes
Response shapes
Section titled “Response shapes”Most API errors are JSON:
{ "error": "Validation failed", "issues": [{ "path": ["email"], "message": "…" }] }Authentication and rate-limit errors from /api/v1/auth/* use the Better Auth shape, { "code": "…", "message": "…" }. KenresoftApiError in @kenresoft-cms/astro exposes status, message, issues (form validation) and code.
| Status | Code | When |
|---|---|---|
| 401 | INVALID_EMAIL_OR_PASSWORD |
Sign-in with the wrong credentials |
| 403 | EMAIL_NOT_VERIFIED |
Sign-in before verifying the email. A fresh link is sent |
| 429 | TOO_MANY_REQUESTS |
An /api/v1/auth/* POST over its limit |
| 400 | TURNSTILE_REQUIRED |
Sign-up without a token, when TURNSTILE_SECRET_KEY is set |
| 403 | TURNSTILE_FAILED |
A bad or reused Turnstile token |
| 503 | TURNSTILE_UNAVAILABLE |
Cloudflare could not verify the token (fails closed) |
The same three TURNSTILE_* codes come from a public form with the human check on, but in the form shape { "code": "…", "error": "…" }.
Status conventions
Section titled “Status conventions”| Status | Meaning |
|---|---|
| 400 | Validation failed (with issues), invalid input, or no email provider configured for a send |
| 401 | No valid session |
| 403 | Signed in without the role the route needs |
| 404 | Not found. Also used deliberately for drafts, disabled plugins, the Owner (to non-Owners), and disabled recovery or bootstrap routes, so they are indistinguishable from missing |
| 429 | Rate limit exceeded. See Rate limiting |
| 502 | An email provider failed to send |
| 503 | A dependency is not configured or reachable, for example payments with no Paystack key |