Brain
Errors and rate limits
The Unison error envelope, every error code with its HTTP status, optimistic-concurrency conflicts, and how to handle 429s.
Every error is the same envelope:
{ "error": { "code": "snake_case", "message": "…" } }Codes
| Code | HTTP | Meaning |
|---|---|---|
unauthenticated | 401 | missing/invalid usk_ token |
forbidden | 403 | token lacks the required scope, or write to a read-only path (/system/ or the ingest-only /private/sources/) |
not_found | 404 | e.g. GET /v1/brain/doc for a missing path |
invalid_path | 400 | malformed path or not ending in .md |
conflict | 409 | content-hash mismatch on write, or email_registered on provision |
rate_limited | 429 | per-token limit - retry with backoff |
| (generic) | 5xx | 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.