Errors & responses
The success and error response shapes, the error-code to HTTP-status map, and the invisibility rule.
Success
A successful request returns the endpoint's typed result directly, with a
2xx status. There is no wrapper envelope — the JSON body is exactly the data
the endpoint documents, so consult each endpoint's response schema in the
Reference for its shape.
Errors
An error carries a stable domain error code, and the HTTP status is that code's status. The JSON body is:
{
"code": "VALIDATION",
"message": "The input failed domain validation.",
"data": { "issues": [{ "path": "name", "message": "Required" }] }
}code— the stable, machine-readable error code (see the table).message— a human-readable summary (implementations may refine it per case).data— a typed payload specific to the code; absent for codes that carry none.
Branch on code (or the HTTP status), never on message.
Error codes
| Code | Status | Meaning | data |
|---|---|---|---|
UNAUTHORIZED | 401 | Authentication required, or the credential is invalid. | — |
PLAN_LIMIT | 402 | The action exceeds your plan's limits. | { limit, current, max, planId, suggestedPlanId } |
FORBIDDEN | 403 | Authenticated, but not allowed to perform this action. | — |
NOT_FOUND | 404 | The resource does not exist — or you cannot see it. | { resource } |
CONFLICT | 409 | The request conflicts with current state (e.g. a handle or version already taken). | { reason } |
VALIDATION | 422 | The input failed domain validation. | { issues: [{ path, message }] } |
SCAN_BLOCKED | 422 | Publish blocked by security-scan findings. | { report } |
WARNINGS_UNACKNOWLEDGED | 422 | Blocked by unacknowledged archive warnings; retry with allowWarnings. | { skills } |
RATE_LIMITED | 429 | Rate limit exceeded; retry later. | { retryAfterSeconds } |
Endpoints that are declared but not yet implemented (the external-source stubs)
return 501 with code NOT_IMPLEMENTED.
Not found, never forbidden
Reads never reveal the existence of something you are not allowed to see. A
request for a private resource you lack access to returns 404 NOT_FOUND,
not 403 — so a registry or skill you cannot reach is indistinguishable from
one that does not exist. 403 FORBIDDEN is reserved for writes you are
authenticated for but not permitted to perform.