Developers
REST API
Everything you can do in the app, you can do over HTTP. All paths are relative to https://ounie.com and authenticate with a Bearer API key.
Authentication#
Send your API key as a Bearer token on every request. See the API overview for how to create one.
Authorization: Bearer ounie_live_…List brains#
GET /api/brains — returns the brains you can access, each with its id, name, and source count.
curl -s https://ounie.com/api/brains \
-H "Authorization: Bearer ounie_live_…"{
"brains": [
{
"id": "…",
"name": "Research",
"slug": "research",
"visibility": "private",
"sourceCount": 42
}
]
}Ask a brain#
POST /api/brains/{brainId}/ask — ask a grounded question and get an answer with citations. If the brain cannot answer, thin is true. Asking counts against your daily quota; an exceeded quota returns 429 with a quota object.
curl -s -X POST https://ounie.com/api/brains/{brainId}/ask \
-H "Authorization: Bearer ounie_live_…" \
-H "Content-Type: application/json" \
-d '{"question":"What did we decide about pricing?"}'{
"answerMd": "…answer with [[slug]] citations…",
"answerHtml": "<p>…</p>",
"citations": [{ "slug": "pricing", "title": "Pricing", "documentId": "…" }],
"retrievedSlugs": ["pricing", "…"],
"thin": false
}Ask a brain set (blended)#
POST /api/v1/brain-sets/{setId}/ask — ask a brain set (a primary brain blended with advisor brains) and get one answer that tags each citation by its source brain. Create a set in Brain Lab to get a set_… id. This endpoint requires API access (Pro and Team).
curl -s -X POST https://ounie.com/api/v1/brain-sets/{setId}/ask \
-H "Authorization: Bearer ounie_live_…" \
-H "Content-Type: application/json" \
-d '{"question":"How should I word this?"}'{
"answer": "…answer with [[slug]] citations…",
"citations": [
{ "brain": { "id": "…", "name": "Company", "kind": "primary" },
"slug": "pricing", "title": "Pricing", "url": "https://ounie.com/b/…" }
],
"thin": false,
"advisorContributed": true
}Retrieve context#
POST /api/brains/{brainId}/context — return the matching wiki pages without generating an answer, so your own model can reason over them. This does not count against your ask quota.
curl -s -X POST https://ounie.com/api/brains/{brainId}/context \
-H "Authorization: Bearer ounie_live_…" \
-H "Content-Type: application/json" \
-d '{"query":"pricing decision"}'{
"contextText": "…full markdown of the retrieved pages…",
"pages": [{ "slug": "pricing", "title": "Pricing" }],
"thin": false
}Add a source#
POST /api/brains/{brainId}/sources — add a link, a synthesized text passage, or a verbatim note. The body shape depends on type.
Link#
Ounie fetches the URL and synthesizes it into the wiki.
{ "type": "link", "url": "https://example.com/article" }Text#
Inline content that is synthesized and made citable. externalId makes repeats idempotent; sourceUrl attaches an origin.
{
"type": "text",
"title": "Standup notes",
"content": "…",
"sourceUrl": "https://…",
"externalId": "standup-2026-06-07"
}Note#
Stored verbatim, skipping synthesis.
{ "type": "note", "title": "Idea", "body": "…markdown…" }Each call returns the created source with a status that moves from pending to ready as it is processed in the background.
List sources#
GET /api/brains/{brainId}/sources — list every source in a brain with its type, title, and status.
Upload a file#
Files upload directly to storage in two steps. First request a presigned URL:
curl -s -X POST https://ounie.com/api/brains/{brainId}/sources/upload-url \
-H "Authorization: Bearer ounie_live_…" \
-H "Content-Type: application/json" \
-d '{"filename":"report.pdf","contentType":"application/pdf","size":248000}'Then PUT the file bytes to the returned uploadUrl (with a matching Content-Type). Ounie processes it into the wiki once the upload lands.
{ "sourceId": "…", "uploadUrl": "https://…", "key": "…" }Quota and errors
Asking is metered by your plan; over-quota requests return429. A bad or revoked key returns 401. A brain you cannot access returns 404.