Errors
Error response format and the status codes the API returns.
When a request fails, the API returns a non-2xx status code and a JSON body with an error field describing the problem.
{
"error": "Forbidden - Admin access required"
}
Successful responses instead carry "success": true and a data payload (legacy endpoints), or the resource / { data, pagination } envelope (/api/v1).
Error shapes
The legacy endpoints return a human-readable { "error": "..." } message. The /api/v1 endpoints return a stable machine code in error, optionally with a message and extra fields:
{ "error": "insufficient_scope", "message": "This API key is missing required scope(s): candidates:read.", "requiredScopes": ["candidates:read"], "grantedScopes": ["roles:read"] }
{ "error": "bad_request", "message": "Invalid field(s)", "details": ["status must be a non-empty string"] }
/api/v1 machine codes: bad_request (400), insufficient_scope (403), forbidden (403), not_found (404), internal_error (500). On insufficient_scope, read requiredScopes / grantedScopes to self-correct.
Status codes
| Status | Meaning | What to do |
|---|---|---|
200 | Success | Read the response body. |
201 | Created | A POST created the resource; read it from the body. |
204 | No content | A DELETE succeeded; there is no body. |
400 | Validation error | Fix the request body or parameters; error/details say what is wrong. |
401 | Unauthorized | No valid API key was supplied. Check the Authorization header. |
403 | Forbidden / insufficient scope | The key’s owner lacks the required role, or the key is missing the required /api/v1 scope (insufficient_scope). |
404 | Not found | The resource does not exist — or, on /api/v1, exists but is not visible to the key (no existence leak). |
429 | Rate limited | Honor the Retry-After header and back off. |
500 | Server error | Transient — retry with backoff; if it persists, contact support. |
Common error messages
| Endpoint | Message | Cause |
|---|---|---|
| Create key | Name is required | Missing name in the body. |
| Create key | userId is required | Missing userId in the body. |
| Create key | expiresInDays must be between 1 and 365 | Out-of-range expiry. |
| Create key | Target user not found | userId does not match a user. |
| Revoke / usage | Key not found | The id does not match a key. |
| Any | Unauthorized | Missing or invalid key. |
| Any (admin) | Forbidden - Admin access required | Key owner is not an admin. |