Apps for AI agents
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.
Base URL
https://ounie.com
Auth
Bearer ounie_live_…
Stable surface
/api/v1
Metered by
Your question quota
Authentication#
Send your API key as a Bearer token on every request. See the API overview for how to create one.
Request header
Authorization: Bearer ounie_live_…Versioned v1 paths
The/api/v1/brains routes below are the canonical, stable surface that the Zapier, Make, VS Code, and Obsidian integrations build on. The unversioned /api/brains paths remain supported. All v1 routes are available on every plan and metered by your question quota — no separate API tier.List your brains (v1)#
GET /api/v1/brains — returns your own brains, each with its id, name, slug, emoji, visibility, and source count. Handy as a dropdown for automation tools.
Request
curl -s https://ounie.com/api/v1/brains \
-H "Authorization: Bearer ounie_live_…"Response
{
"brains": [
{
"id": "…",
"name": "Research",
"slug": "research",
"emoji": "🧠",
"visibility": "private",
"sourceCount": 42
}
]
}Add a source (v1)#
POST /api/v1/brains/{brainId}/sources — add a link or a text passage. Any body may carry an externalId: a repeat returns the existing source with created: false (a 200), so retries and re-syncs are safe. A text source rides synthesis by default; set mode: "note" to store it verbatim.
Request body
// link
{ "kind": "link", "url": "https://example.com/article", "externalId": "art-42" }
// text (synthesized, default)
{ "title": "Standup notes", "content": "…", "sourceUrl": "https://…", "externalId": "standup-2026-06-07" }
// note (verbatim, skips synthesis)
{ "title": "Idea", "content": "…markdown…", "mode": "note", "externalId": "idea-7" }Response
{
"source": { "id": "…", "type": "text", "title": "Standup notes", "status": "pending", "externalId": "standup-2026-06-07" },
"created": true
}Ask a brain (v1)#
POST /api/v1/brains/{brainId}/ask — ask a grounded question. The answer's [[slug]] citations are rewritten to absolute markdown links, and citations carries those URLs. Asking is metered on your plan: an exhausted Free bank returns 402, an exceeded paid quota 429.
Request
curl -s -X POST https://ounie.com/api/v1/brains/{brainId}/ask \
-H "Authorization: Bearer ounie_live_…" \
-H "Content-Type: application/json" \
-d '{"question":"What did we decide about pricing?"}'Response
{
"id": "…",
"answer": "We set [Pricing](https://ounie.com/b/ada/ai/pricing) last week.",
"citations": [{ "slug": "pricing", "title": "Pricing", "url": "https://ounie.com/b/ada/ai/pricing" }],
"thin": false,
"quota": null,
"bank": 987
}List brainsv1 path above#
GET /api/brains — returns the brains you can access, each with its id, name, and source count.
Request
curl -s https://ounie.com/api/brains \
-H "Authorization: Bearer ounie_live_…"Response
{
"brains": [
{
"id": "…",
"name": "Research",
"slug": "research",
"visibility": "private",
"sourceCount": 42
}
]
}Ask a brainv1 path above#
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.
Request
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?"}'Response
{
"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).
Request
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?"}'Response
{
"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.
Request
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"}'Response
{
"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.
Request body
{ "type": "link", "url": "https://example.com/article" }Text#
Inline content that is synthesized and made citable. externalId makes repeats idempotent; sourceUrl attaches an origin.
Request body
{
"type": "text",
"title": "Standup notes",
"content": "…",
"sourceUrl": "https://…",
"externalId": "standup-2026-06-07"
}Note#
Stored verbatim, skipping synthesis.
Request body
{ "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:
Request
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.
Response
{ "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.