Skip to main content
Every error from /api/* is JSON with Content-Type: application/json:
The HTTP status stays meaningful on its own. New fields may be added, so ignore ones you do not recognize.

Codes from the status

Most errors carry a code derived from their status: An unknown path under /api returns 404 with {"message": "Not found", "code": "NOT_FOUND"}. Unexpected server failures return 500 with {"message": "Internal Server Error", "code": "INTERNAL_SERVER_ERROR"} and never include internal details.

Specific codes

missingPermissions only names permissions for the route you called in the workspace it targets. A 401 with UNAUTHORIZED means Kaneo did not accept your session or API key. Sign in again or replace the key only for that code, not for every 401. Sign-in, sign-up, and workspace membership endpoints under /api/auth/* return the same message and code fields. Their codes describe the specific failure, for example INVALID_EMAIL_OR_PASSWORD, PASSWORD_REGISTRATION_DISABLED, or CAPTCHA_FAILED.

Validation issues

message repeats the first issue. issues lists all of them, so a form can mark every invalid field at once:
Each path starts with the part of the request that failed: body, query, params, or header, followed by the field, for example query.limit or body.customFields.0.value.

Retrying

A 429 may include a Retry-After header with the number of seconds to wait. Do not retry 4xx errors other than 408 and 429 without changing the request.

Exceptions

These endpoints follow external standards and keep their own error bodies:
  • Device authorization. /api/auth/device/code and /api/auth/device/token return RFC 8628 errors such as {"error": "authorization_pending"} and {"error": "slow_down"}. See Authentication.
  • MCP OAuth. /api/mcp/register, /api/mcp/authorize, /api/mcp/authorize/request/{requestId}, and /api/mcp/token return RFC 6749 and RFC 7591 errors shaped as {"error": "invalid_request", "error_description": "..."}. The /api/mcp endpoint itself answers with {"error": ...} bodies, such as invalid_token, and MCP protocol messages.
  • Inbound webhooks. The GitHub, Gitea, and GitLab webhook receivers are called by those services, not by API clients, and keep their existing responses.

Older instances

Kaneo versions before this format returned many errors as plain text. If your client talks to instances you do not control, read the body as text and parse it as JSON only when it is valid, falling back to the text as the message.