Errors & conventions
Status codes and shared behavior
Conventions that apply across most of the API reference rather than to any one endpoint.
Status codes
Bad request
Validation failure. Body shape is usually { "error": "some_code_or_message" } — error naming is not fully consistent (see below).
Unauthenticated
No session cookie and no valid Bearer token.
Forbidden
Authenticated, but missing the required scope or role, or the account is blocked.
Not found
The resource id doesn't exist, or you don't have visibility into it.
Conflict
A uniqueness constraint failed — but not every conflict uses 409, see below.
Rate limited
Only on the headless email-claim endpoints today.
The 400-vs-409 line isn't drawn consistently yet: POST /api/community/labels returns 409 on a duplicate name, but POST /api/community/username returns 400 for the same class of conflict. Check the specific endpoint's entry in the reference rather than assuming.
How a request is authenticated
Every scope-checked route accepts two different kinds of credential, and they behave differently:
- A browser session cookie(the same one the monoes.me web app uses) is accepted first, and if present it short-circuits the check entirely — the endpoint's declared scope is not verified against it. A signed-in browser session can call any scope-checked route.
- A Bearer token (OAuth-issued or from the headless agent flow) is checked against its stored
scopesarray with exact string matching —community:writedoes not implycommunity:read. If you need both, request both scopes.
Blocked accounts
A blocked user hitting a scope-only write route (most of the API) gets { "error": "Account blocked" }. On a role-gated (admin/moderator) route the check can't tell "wrong role" apart from "blocked" — both collapse into a generic { "error": "Forbidden" }. Either way, a blocked user also can't start a new browser session; existing sessions are invalidated.
Library API errors
The /api/library/* endpoints return a structured error, { "error": { "code": "...", "message": "..." } }, so clients can branch on code and show message:
- 400
invalid_request,invalid_artifact(the file failed validation) - 401
unauthorized; 403insufficient_scope,forbidden,blocked - 404
not_found(also for private items you can't see) - 409
version_conflict,gallery_org; 413too_large; 429rate_limited
Unlike the community endpoints, a library token without the needed scope gets 403 insufficient_scope rather than being treated as anonymous, and library lists use a 1-indexed page.
Pagination
The one paginated endpoint, GET /api/community/feed, uses a 0-indexed page query parameter — the first page is page=0, not page=1.