Brain

Errors and rate limits

The Unison error envelope, every error code with its HTTP status, optimistic-concurrency conflicts, and how to handle 429s.

unison-brain

Every error is the same envelope:

{ "error": { "code": "snake_case", "message": "…" } }

Codes

CodeHTTPMeaning
invalid_path400malformed path or not ending in .md
invalid_json400request body is not valid JSON
invalid_request400auth endpoints - missing or invalid fields
bad_request400other validation failures
unauthenticated401missing/invalid usk_ token
unauthorized401internal auth mapping only - rare
forbidden403token lacks the required scope, or write to a read-only path (/system/ or the ingest-only /private/sources/)
not_found404e.g. GET /v1/brain/doc for a missing path
conflict409content-hash mismatch on write, or email_registered on provision
precondition_failed412a precondition on the request was not met
payload_too_large413request body exceeds the size limit
unprocessable_content422request is well-formed but semantically invalid
rate_limited / too_many_requests429per-token limit - retry with backoff
rest_error500generic internal server error

Optimistic concurrency

PUT /v1/brain/doc accepts expectedContentHash (hex16). If the document changed since you read it, the write returns 409 conflict instead of clobbering - re-read, re-apply, retry. CLI: unison write --if-match <hash>.

Rate limiting

Limits are per token. On 429 rate_limited, back off and retry; for high-volume ingest prefer batching (up to 100 items per POST /v1/brain/ingest) over per-item calls.

Client behavior

Clients (SDK/CLI/MCP) never pre-check scopes or validate paths - they send the call and surface the server's verdict. Treat every 4xx as authoritative.

On this page