Concepts
Errors
The HTTP status always tells you the class of failure. Errors the gateway raises use one envelope with a stable code; errors a service raises arrive as that service sent them. Every response carries an x-request-id.
The gateway's envelope
{
"error": {
"type": "unauthorized",
"code": "CREDENTIAL_INVALID",
"message": "The credential is invalid, expired or revoked.",
"request_id": "f1552024-11e8-48b7-8ca4-497521d1971d",
"docs_url": "https://os.one.ml/api/v1/errors#CREDENTIAL_INVALID"
}
}| Field | Always | Meaning |
|---|---|---|
type | yes | The class, matching the status: unauthorized, forbidden, not_found, rate_limited… |
code | yes | Stable and machine-readable. Branch on this, never on message. |
message | yes | One sentence for people. It can change. |
request_id | yes | The same value as the x-request-id header. |
docs_url | yes | The code's entry in the catalog. |
required_scope | on SCOPE_MISSING | The scope the operation needs. |
The full catalog of 119 codes is at Error codes, and as JSON at https://os.one.ml/api/v1/errors.
Service errors
When the gateway admits a request and the service refuses it, the service's own status and body come back unchanged. Service bodies vary; for example:
{ "error": { "type": "not_found", "status": 404, "message": "project not found: prj_missing", "request_id": "…" } }{ "error": "Project not found" }Rely on the HTTP status, then on the body's fields where the service documents them. Each operation's Responses in the API reference lists the statuses it returns.
By status
| Status | What happened | What to do |
|---|---|---|
400 | The path, query, header or body failed validation. | Fix the request; retrying the same request fails the same way. |
401 | No credential, or one that is invalid, expired or revoked. | Send one Authorization: Bearer header with a live credential. |
403 | The credential is valid but may not do this, often SCOPE_MISSING. | Use a credential with required_scope, or a signed-in session. |
404 | No such route, or no such resource in your organization. | Check the path and id. |
409 | The resource changed or already exists. | Read the current state, then decide. |
422 | The body is well-formed but not acceptable. | Fix the field the message names. |
429 | Too many requests for this principal. | Wait Retry-After seconds. See Rate limits. |
502 504 | The service answered badly or too slowly. | Retry reads with backoff; for writes, see Idempotency. |
503 | The service is unavailable or not enabled here. | Check Status; honour Retry-After when present. |
In the SDK, CLI and MCP
import { GenesisError, errorCatalog } from '@lifesi/genesis'
try {
await genesis.call('hives_delete_project', { project_id })
} catch (e) {
if (!(e instanceof GenesisError)) throw e
// Always: e.status, e.type, e.message, e.requestId.
// Gateway errors also carry e.code; errorCatalog(e) adds required_scope and docs_url.
console.error(e.status, e.code ?? e.type, e.requestId, errorCatalog(e).required_scope)
}genesis --json hives projects delete prj_doesnotexist
# {"error":{"type":"not_found","status":404,"message":"project not found: prj_doesnotexist","request_id":"…"}}{
"isError": true,
"content": [{ "type": "text", "text": "{ \"error\": { \"type\": \"not_found\", \"status\": 404, \"message\": \"project not found: prj_doesnotexist\", \"request_id\": \"…\" } }" }]
}When you contact support, include the request_id.
One Superintelligence, Inc. · Built from Genesis 0.1.12 and the live gateway on 2026-10-20. Support