Developers
The public API lets your own scripts and tools take knowledge out of Breno and put it back in, with the same access rules as the app.
Get a token
- In Breno, open Settings, then Connect AI.
- Create a token, give it a name and choose its scopes and expiry.
- Copy it. It starts with
sirmx_mcp_and is shown only once.
The same token works on the MCP endpoint and on the REST API. Send it as:
Authorization: Bearer sirmx_mcp_…A token belongs to you in one workspace. It sees exactly what you can see: spaces you belong to, sensitivity labels you are cleared for, and your own private items. It stops working at once when you revoke it, it expires, you leave the workspace, your account is erased, or the workspace is deleted.
Tokens issued to an OAuth connector (Claude.ai, ChatGPT) work only on the MCP endpoint; the REST API answers 401 TOKEN_AUDIENCE_MISMATCH.
Scopes and operations
| Scope | Operation | Route |
|---|---|---|
read | List documents (filters, paging) | GET /api/v1/documents |
read | List documents as cards, with summaries | GET /api/v1/documents/cards |
read | Get a document | GET /api/v1/documents/{id} |
read | Full extracted text | GET /api/v1/documents/{id}/text |
read | Note content | GET /api/v1/documents/{id}/content |
read | Search passages (no generation) | POST /api/v1/search/query |
read | List native connectors | GET /api/v1/connectors |
read | List connected sources with sync status | GET /api/v1/integrations/connections |
ask | Grounded answer with citations | POST /api/v1/search/ask |
ask | Streamed answer (server-sent events) | GET /api/v1/search/ask/stream |
export | JSON bundle | POST /api/v1/knowledge/export |
export | ZIP of Markdown files | POST /api/v1/knowledge/export/zip |
export | Start an asynchronous export | POST /api/v1/knowledge/exports |
export | Download a finished export archive | GET /api/v1/knowledge/exports/{id}/download |
write | Upload a file | POST /api/v1/documents/upload |
write | Capture a link | POST /api/v1/documents/capture |
write | Edit one of your own notes | PATCH /api/v1/documents/{id}/content |
Every other endpoint (deleting, sharing, members, settings, token management, connecting sources, and so on) refuses tokens with 403 SESSION_REQUIRED, so a leaked token can never administer your workspace. Viewers cannot write with a token either.
GET /documents filters: source_type, status, space_id, tag, owner (a user id or me), q (title contains), updated_since (RFC 3339), plus limit (max 200) and offset.
Examples
export BRENO=https://<your-breno-host>/api/v1
export TOKEN=sirmx_mcp_…
# List your notes changed this week
curl -s -H "Authorization: Bearer $TOKEN" \
"$BRENO/documents?source_type=note&updated_since=2026-10-01T00:00:00Z&limit=50"
# Search without generating an answer
curl -s -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"query":"data retention policy"}' "$BRENO/search/query"
# Ask (scope ask)
curl -s -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"question":"What did we decide about the Q3 launch?"}' "$BRENO/search/ask"
# Export everything you can read as Markdown (scope export)
curl -s -X POST -H "Authorization: Bearer $TOKEN" -o breno-export.zip "$BRENO/knowledge/export/zip"
# Add knowledge (scope write)
curl -s -H "Authorization: Bearer $TOKEN" -F file=@report.pdf "$BRENO/documents/upload"
curl -s -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"url":"https://example.com/article"}' "$BRENO/documents/capture"SDKs
Both SDKs are in the repository, cover the public API, and are tested against the spec’s schemas: packages/sdk-ts and packages/sdk-go. The CLI (apps/cli) can bridge the MCP endpoint over stdio with a scoped token.
import { BrenoClient, RateLimitError } from '@brainers/sdk-ts';
const breno = new BrenoClient({ baseUrl: 'https://<your-breno-host>', token: process.env.BRENO_TOKEN! });
for await (const doc of breno.iterateDocuments({ owner: 'me' })) console.log(doc.title);
const answer = await breno.ask('What is our refund policy?');
answer.evidence.forEach((c) => console.log(c.source?.url ?? c.document_id));
await breno.captureNote('Standup 8 Oct', '- shipped the REST API');c := client.NewClient(client.Config{BaseURL: "https://<your-breno-host>", Token: os.Getenv("BRENO_TOKEN")})
it := c.Documents(client.ListOptions{SourceType: "note"})
for it.Next(ctx) {
fmt.Println(it.Document().Title)
}
bundle, err := c.Export(ctx)Rate limits
- 120 requests per minute per token, and 300 per minute per IP address for token traffic.
- The workspace’s normal per-user limits also apply.
- Over the limit you get
429 RATE_LIMIT_EXCEEDEDwith aRetry-Afterheader, in seconds.
Errors
Every error uses one envelope:
{ "success": false, "error": { "code": "INSUFFICIENT_SCOPE", "message": "This token lacks the 'export' scope", "details": { "required_scope": "export" } } }| Status | Code | Meaning |
|---|---|---|
| 400 | INVALID_FILTER, INVALID_BODY, … | Bad request |
| 401 | INVALID_TOKEN | Unknown, expired or revoked token, or you lost access to the workspace |
| 401 | TOKEN_AUDIENCE_MISMATCH | An OAuth connector token used on the REST API |
| 403 | INSUFFICIENT_SCOPE | The token lacks the scope (details.required_scope) |
| 403 | SESSION_REQUIRED | The endpoint is not part of the public API |
| 403 | TOKEN_OWN_NOTES_ONLY | A token can edit only notes its owner created |
| 403 | READ_ONLY_ROLE | Viewers cannot make changes |
| 404 | NOT_FOUND | No such item, or one you cannot read |
| 422 | SOURCE_UNSUPPORTED | A link Breno cannot read; nothing was saved |
| 429 | RATE_LIMIT_EXCEEDED | Slow down; retry after the Retry-After header |
Keeping the contract honest
- A test fails if the token allowlist, the router and the spec’s public operations disagree, in either direction and including scopes, or if a public schema’s fields differ from what the server writes.
- Both SDKs test their models against the spec’s schemas.