API reference
REST endpoints.
Four primary surfaces. Auth is always a workspace-scoped bearer token. Writes accept Idempotency-Key for retry safety.
Authentication
Send your token as Authorization: Bearer bctx_live_.... Tokens are workspace-scoped: a token issued for workspace acme can only read/write nodes in acme. Cross-workspace calls return 403 with "token does not grant access to this workspace".
Content conventions
Structure node bodies with ## headings — each section becomes a stable, addressable block. References use /n/<node_id>#<block_id> (e.g. /n/abc#vision-2026), where the block id is the slug of the heading text. The convention is soft: nodes without H2s still work, they just degrade to whole-document references.
kindis the node's primary semantics. Tags are reusable workspace taxonomy and a node may carry several of them;parent_id optionally connects semantic nodes into a real hierarchy. Tags only classify content — they never grant access or replace workspace RLS. folder and category are not node fields.
Rate limits
Token-bucket per (workspace, scope-class). Buckets refill continuously; denial returns 429 with a Retry-After header.
read 120 req, refill 2 req/s
write 60 req, refill 1 req/s
chat 30 req, refill 0.5 req/s
embed 10 req, refill 0.1 req/sPOST /api/agents/context
The primary read endpoint for agents. Returns the top-k retrieval hits for query plus a projected semantic hierarchy. Retrieval scope is versioned and supports workspace (default), saved view, tags any/all, selection, neighborhood, and auto. Explicit scopes filter candidates before vector/BM25 ranking; auto reports its boosted lanes and always keeps a global workspace lane. Requires scope agents:read.
POST /api/agents/context
Authorization: Bearer bctx_live_...
Content-Type: application/json
{
"workspace": "acme",
"query": "what is blocking the embedding pipeline?",
"k": 6,
"scope": { "schema_version": 1, "type": "tags", "tags_any": ["product", "tech"] },
"fields": ["id", "title", "kind", "status"],
"include_counts": true
}{
"workspace": "acme",
"query": "what is blocking the embedding pipeline?",
"scope": { "schema_version": 1, "type": "tags", "size": 31, "workspace_size": 128, "can_expand_to_workspace": true },
"retrieved": [
{ "node_id": "...", "title": "...", "score": 0.82, "excerpt": "..." }
],
"tree": [ { "id": "...", "title": "...", "kind": "doc", "status": null } ],
"counts": { "docs": 14, "tasks": 22, "decisions": 3, "bugs": 5 }
}POST /api/agents/write
Batch up to 20 ops per call. create inserts a new node; patch partially updates one by id. Include an Idempotency-Key header — replays of the same key return the original response with Idempotent-Replay: true. Requires scope agents:write.
POST /api/agents/write
Authorization: Bearer bctx_live_...
Idempotency-Key: agent-42-batch-7
Content-Type: application/json
{
"workspace": "acme",
"ops": [
{ "op": "create", "node": {
"title": "ADR — switch auth provider",
"kind": "adr",
"parent_id": null,
"content_md": "## Context\n..."
} },
{ "op": "patch", "id": "node_123", "patch": { "status": "done" } }
]
}Supported writable node kinds: doc, task, decision, meeting, bug, adr, entity, skill.
POST /api/chat
Streaming chat against your workspace via the configured AI Gateway model. Retrieves citations from RAG, builds a context block, and pipes a Vercel AI SDK streamText response. Requires scope chat:run. Response headers expose scope type/size and whether the caller may expand to workspace; broad graph neighbors are marked explicitly.
POST /api/chat
Authorization: Bearer bctx_live_...
Content-Type: application/json
{
"workspace": "acme",
"activeNodeId": "node_123",
"scope": { "schema_version": 1, "type": "neighborhood", "root_node_ids": ["node_123"], "depth": 1 },
"messages": [
{ "role": "user", "content": "summarize the open ADRs" }
]
}GET/POST /api/nodes
Direct node CRUD for non-agent clients. GET needs nodes:read; POST needs nodes:write. Individual nodes live at /api/nodes/[id] with PATCH and DELETE. Filter by reusable taxonomy with tag_id or tag; repeat either parameter and pass tags_match=all to require every tag.
GET /api/nodes?workspace=acme
Authorization: Bearer bctx_live_...
POST /api/nodes
Authorization: Bearer bctx_live_...
Content-Type: application/json
{
"workspace": "acme",
"title": "Migration plan",
"kind": "doc",
"parent_id": null,
"tag_ids": ["tag_product", "tag_ai"]
}Tags taxonomy
List tags and usage counts with GET /api/tags. Owners/admins create, rename, merge, and delete tag definitions; callers with nodes:write may assign existing tags. Rename and merge preserve aliases for compatibility. Node tag assignments are metadata-only and do not create separate embeddings.
GET /api/tags?workspace=acme
Authorization: Bearer bctx_live_...
POST /api/tags
Authorization: Bearer bctx_live_...
Content-Type: application/json
{ "workspace": "acme", "name": "Customer research" }
PUT /api/nodes/node_123/tags
Authorization: Bearer bctx_live_...
Content-Type: application/json
{ "workspace": "acme", "tag_ids": ["tag_product", "tag_ai"] }Errors
All errors return JSON with an error field and an appropriate HTTP status: 400 bad input, 401 missing/invalid token, 403 wrong workspace, 404 workspace or node not found, 429 rate limited.