Build on Cairni with the REST API
Reach your wikis from any language over plain HTTPS + JSON — the same capabilities as the MCP server (read, search, compile, ask). Issue a key in Settings → Developer, then send it as a Bearer header.
- Base URL
- https://api.cairni.com/v1
- Auth
- Authorization: Bearer cairni_live_…
- Format
- JSON
- Version
- v1
The version is part of the URL (/v1). We won't make breaking changes to v1 — anything that could break existing code (removing a field, changing a response shape) ships as a new /v2 instead, so your integration keeps working.
curl https://api.cairni.com/v1/me \
-H "Authorization: Bearer cairni_live_…"{
"user": { "id": "u_a1b2c3", "name": "Ada Lovelace", "email": "ada@example.com" },
"livemode": true,
"env": "live",
"scopes": ["*"],
"token_id": "tok_9d8e"
}Authentication
Create a key in Settings → Developer — choose Full access or specific scopes, with an optional expiry. The key is shown once, so store it securely. Every request needs the Bearer header; session cookies are not accepted.
- wiki:readRead wikis, pages, and search.
- wiki:askAsk grounded questions (uses credits).
- wiki:writeCreate wikis and edit pages.
Identity
Check connectivity and confirm which key is calling.
/pingHealth check
Unauthenticated reachability check — no key required.
okserviceversioncurl https://api.cairni.com/v1/ping{
"ok": true,
"service": "cairni-developer-api",
"version": "v1"
}/meWho am I
Returns the identity, environment, and scopes of the calling key — handy for SDK bootstrap and debugging.
userlivemodeenvscopestoken_idcurl https://api.cairni.com/v1/me \
-H "Authorization: Bearer cairni_live_…"{
"user": { "id": "u_a1b2c3", "name": "Ada Lovelace", "email": "ada@example.com" },
"livemode": true,
"env": "live",
"scopes": ["wiki:read", "wiki:ask"],
"token_id": "tok_9d8e"
}Wikis
List, inspect, and create wikis. You only ever see your own and shared wikis.
/wikisList wikis
Lists wikis you can access (your own plus shared), paginated with an opaque cursor.
cursorlimitobjectdatahas_morenext_cursorcurl https://api.cairni.com/v1/wikis \
-H "Authorization: Bearer cairni_live_…"{
"object": "list",
"data": [
{
"object": "wiki",
"slug": "product-handbook",
"name": "Product Handbook",
"visibility": "restricted",
"language": "en",
"role": "owner",
"workspace": { "name": "Ada's workspace", "kind": "personal" },
"page_count": 12
}
],
"has_more": false,
"next_cursor": null
}/wikis/{slug}Get a wiki
Returns a wiki's metadata. Wikis you can't access return 404 — their existence is hidden.
slugreqslugnamevisibilitylanguageroleworkspacepage_counthomecreated_atcurl https://api.cairni.com/v1/wikis/my-wiki \
-H "Authorization: Bearer cairni_live_…"{
"object": "wiki",
"slug": "product-handbook",
"name": "Product Handbook",
"visibility": "restricted",
"language": "en",
"role": "owner",
"workspace": { "name": "Ada's workspace", "kind": "personal" },
"page_count": 12,
"description": "Everything about how we build.",
"home": "overview",
"category": "engineering",
"created_at": "2026-06-01T09:30:00+00:00"
}/wikisCreate a wiki
Creates a new wiki in your personal space — you become its manager. Free. To fill it, compile sources (below).
namereqdescription…curl -X POST https://api.cairni.com/v1/wikis \
-H "Authorization: Bearer cairni_live_…" \
-H "Content-Type: application/json" \
-d '{"name":"Product Handbook","description":"Everything about how we build."}'{
"object": "wiki",
"slug": "product-handbook",
"name": "Product Handbook",
"visibility": "restricted",
"language": "en",
"role": "owner",
"workspace": { "name": "Ada's workspace", "kind": "personal" },
"page_count": 0,
"description": "Everything about how we build.",
"home": null,
"category": null,
"created_at": "2026-06-13T10:00:00+00:00"
}Pages
Read the compiled pages inside a wiki.
/wikis/{slug}/pagesList pages
Lists a wiki's pages in display order, cursor-paginated.
slugreqcursorlimitdatahas_morenext_cursorcurl https://api.cairni.com/v1/wikis/my-wiki/pages \
-H "Authorization: Bearer cairni_live_…"{
"object": "list",
"data": [
{
"object": "page",
"slug": "getting-started",
"title": "Getting started",
"type": "concept",
"summary": "A short overview of onboarding.",
"is_home": false,
"position": 0,
"updated_at": "2026-06-10T12:00:00+00:00"
}
],
"has_more": false,
"next_cursor": null
}/wikis/{slug}/pages/{page}Get a page
Returns a page's canonical Markdown body and metadata.
slugreqpagereqbodywikisourcesversionedit_origincurl https://api.cairni.com/v1/wikis/my-wiki/pages/getting-started \
-H "Authorization: Bearer cairni_live_…"{
"object": "page",
"slug": "getting-started",
"title": "Getting started",
"type": "concept",
"summary": "A short overview of onboarding.",
"is_home": false,
"position": 0,
"updated_at": "2026-06-10T12:00:00+00:00",
"wiki": "product-handbook",
"body": "# Getting started\n\nWelcome to the handbook…",
"sources": ["onboarding.pdf"],
"version": 3,
"edit_origin": "ai"
}Search
Find pages by keyword across your wikis.
/searchSearch pages
Matches page titles and summaries across accessible wikis, or a single wiki with ?wiki=slug.
qwikilimitdataqueryhas_morecurl https://api.cairni.com/v1/search \
-H "Authorization: Bearer cairni_live_…"{
"object": "list",
"data": [
{
"object": "search_result",
"wiki": "product-handbook",
"slug": "getting-started",
"title": "Getting started",
"summary": "A short overview of onboarding.",
"type": "concept"
}
],
"query": "onboarding",
"has_more": false
}Compile
Hand Cairni a source; it compiles it into pages in the background. There is no raw page-edit endpoint — sources in, structured pages out.
/wikis/{slug}/sourcesCompile a source
Hands a URL or text to Cairni, which compiles it into wiki pages in the background. Returns a job to poll. Requires editor access; uses workspace credits.
slugreqtyperequrltextnameinstructionsourcejob_idstatuscurl -X POST https://api.cairni.com/v1/wikis/my-wiki/sources \
-H "Authorization: Bearer cairni_live_…" \
-H "Content-Type: application/json" \
-d '{"type":"url","url":"https://example.com/post","name":"Launch post"}'{
"object": "ingest",
"wiki": "product-handbook",
"source": {
"name": "Launch post",
"kind": "url",
"status": "queued",
"duplicate": false
},
"job_id": "job_3f9c",
"status": "queued"
}/wikis/{slug}/sources/audioCompile an audio recording
Upload an audio file (multipart/form-data). Cairni transcribes and diarizes it, then compiles the transcript into pages — all in the background. Poll the returned job_id through transcribing → compiling → done.
slugreqfilereqnameparticipantsinstructionjob_idstatuscurl -X POST https://api.cairni.com/v1/wikis/my-wiki/sources/audio \
-H "Authorization: Bearer cairni_live_…" \
-F "file=@meeting.mp3" \
-F "name=Standup" \
-F "participants=Ada,Bob"{
"object": "ingest",
"wiki": "product-handbook",
"source": { "name": "Standup", "kind": "audio", "status": "transcribing", "duplicate": false },
"job_id": "src_9a8b",
"status": "transcribing"
}/wikis/{slug}/jobsList compile jobs
Lists this wiki's recent compile jobs, newest first.
slugreqlimitdatacurl https://api.cairni.com/v1/wikis/my-wiki/jobs \
-H "Authorization: Bearer cairni_live_…"{
"object": "list",
"data": [
{
"object": "job",
"id": "job_3f9c",
"status": "running",
"phase": "compile",
"progress": 60,
"total": 5,
"done": 3,
"compiled_pages": ["intro", "setup"],
"detail": "compiling 'setup'",
"source_id": "src_77ab"
}
]
}/wikis/{slug}/jobs/{job_id}Get a compile job
Returns a compile job's status, phase, progress, and the pages written so far. Poll until status is "done".
slugreqjob_idreqstatusphaseprogresscompiled_pagescurl https://api.cairni.com/v1/wikis/my-wiki/jobs/job_3f9c \
-H "Authorization: Bearer cairni_live_…"{
"object": "job",
"id": "job_3f9c",
"status": "done",
"phase": "done",
"progress": 100,
"total": 3,
"done": 3,
"compiled_pages": ["intro", "setup", "faq"],
"detail": "",
"source_id": "src_77ab"
}Ask
Ask a question and get an answer grounded in the wiki, with citations.
/wikis/{slug}/askAsk a question
Answers a question grounded in the wiki, citing the pages used. Refuses (refused=true) when the wiki has no grounding. Uses workspace credits.
slugreqquestionreqanswerrefusedreasoncited_pagescited_sourcescurl -X POST https://api.cairni.com/v1/wikis/my-wiki/ask \
-H "Authorization: Bearer cairni_live_…" \
-H "Content-Type: application/json" \
-d '{"question":"What changed in v2?"}'{
"object": "answer",
"wiki": "product-handbook",
"question": "What changed in v2?",
"answer": "v2 added cursor pagination and a structured error model.",
"refused": false,
"reason": "",
"cited_pages": ["changelog", "api-v2"],
"cited_sources": []
}Errors
Every non-2xx response returns the same JSON shape plus an X-Request-Id header. Branch on error.type (a stable contract), never on the message text or the HTTP status alone.
error.typeerror.messageerror.request_id{
"error": {
"type": "not_found",
"message": "Notebook not found",
"request_id": "req_8f3c1a"
}
}unauthorizedAuthentication failedThe Authorization header is missing or malformed, or the key is invalid, disabled, or expired. Send a valid `Authorization: Bearer cairni_live_…` key — session cookies are not accepted on the API. Rotate or re-issue the key in Settings → Developer if needed.
insufficient_creditsOut of creditsThe wiki's workspace has no credits left for a paid action (compiling a source, or ask). The error body includes `needed` and `available`. Top up credits or upgrade the plan — reads are always free, so this only affects POST …/sources and POST …/ask.
forbiddenScope or permission deniedThe key is valid but isn't allowed to do this. Either it lacks the required scope (e.g. a read-only key calling a write endpoint — check GET /me's scopes), or your role on the wiki is too low: compiling needs editor access or higher. Use a key with the right scope, or get edit access to the wiki.
not_foundNot found — or hiddenThe wiki, page, or job doesn't exist, or you can't access it. To avoid leaking which wikis exist, Cairni returns 404 (not 403) for wikis you can't access — so a 404 can mean "it exists, but it isn't yours". Double-check the slug and that the key's owner has access.
invalid_requestInvalid requestThe request body or query parameters didn't validate — a missing required field, an unknown `type`, a non-http(s) URL, empty text, or a `limit` out of range. The `message` names the offending field so you can fix it and retry.
rate_limitedToo many requestsYou're sending requests too fast, or too many compile jobs are already running for your account. Back off and retry after a short wait, and let in-flight jobs finish (poll GET …/jobs/{id}) before starting more.
Use your Cairni wikis in any AI client
Cairni exposes an MCP server, so clients like Claude, Cursor, and Codex can search, read, ask, and even compile into your wikis — your own and the ones shared with you. Connect once with OAuth, no copy-pasting tokens.
- Endpoint
- https://mcp.cairni.com/
- Transport
- Streamable HTTP
- Auth
- OAuth 2.1 · dynamic client registration · or PAT
Connect with OAuth (recommended)
The fastest way — your browser opens a consent screen and you click Allow.
Add the server
claude mcp add --transport http cairni https://mcp.cairni.com/Authorize in the browser
Done
Claude Desktop and claude.ai (Team / Enterprise): add Cairni under Settings → Connectors with the same URL — you'll get the same Allow screen.
Connect with a token
For scripts, CI, or clients without OAuth — use a personal access token (PAT).
Create a token
Add it as a header
claude mcp add --transport http cairni https://mcp.cairni.com/ \
--header "Authorization: Bearer cairni_live_…"{
"mcpServers": {
"cairni": {
"type": "http",
"url": "https://mcp.cairni.com/",
"headers": { "Authorization": "Bearer cairni_live_…" }
}
}
}Other clients
Cairni speaks the standard remote-MCP protocol, so any MCP-capable client connects to the same endpoint. Clients that only support local (stdio) servers can use the mcp-remote bridge, which runs the OAuth flow for you.
{
"mcpServers": {
"cairni": { "url": "https://mcp.cairni.com/" }
}
}Or open Settings → MCP → Add new server. Authorize with OAuth on first use.
codex mcp add cairni --url https://mcp.cairni.com/First-time rmcp setup: add experimental_use_rmcp_client = true under [features] in ~/.codex/config.toml, then run codex mcp login cairni.
npx -y mcp-remote https://mcp.cairni.com/For any client that only supports local (stdio) servers, register this as the command (command: npx, args: -y mcp-remote <url>). The bridge opens the OAuth consent in your browser, then relays the tools.
Tools
Every tool runs with your permissions — you only ever see your own and shared wikis.
| Tool | What it does | Scope | Cost |
|---|---|---|---|
| list_wikis | List wikis you can access | wiki:read | free |
| read_page | Read a page's Markdown | wiki:read | free |
| search | Search across your wikis | wiki:read | free |
| ask | Grounded Q&A with citations | wiki:ask | credits |
| put_page | Write a page directly (raw) | wiki:write | free |
| create_wiki | Create a new wiki | wiki:write | free |
| ingest | Hand sources to Cairni to compile | wiki:write | credits |
put_page writes Markdown your client composed — no Cairni AI runs, so it's free. ask and ingest use Cairni's LLM and draw from the wiki's workspace credits.
Scopes & security
- wiki:readRead wikis, pages, and search.
- wiki:askAsk grounded questions (uses credits).
- wiki:writeCreate wikis and edit pages.
Ready to connect?
Create a token or open Cairni to get started.