Learn

Ingest

Stream conversations and documents into the brain with POST /v1/brain/ingest. Entity extraction and fact extraction run async; sourceRef keeps retries idempotent.

POST /v1/brain/ingest is the primary write. Send up to 100 items per call. Conversations run entity resolution and fact extraction asynchronously; documents land as extractable notes at a brain path. The response returns job ids — extraction is never synchronous.

Ingest a conversation

import { BrainClient } from "@unisonlabs/sdk";

const brain = new BrainClient({ token: process.env.UNISON_TOKEN });

await brain.ingest({
  items: [{
    type: "conversation",
    sourceRef: "session-42",          // your stable session/thread id
    turns: [
      { role: "user",      content: "switch the queue to pgmq" },
      { role: "assistant", content: "Done — migrated worker, dropped redis." },
    ],
    visibility: "private",            // default; use "workspace" to share immediately
  }],
});
curl -X POST https://brain.unisonlabs.ai/v1/brain/ingest \
  -H "Authorization: Bearer $UNISON_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [{
      "type": "conversation",
      "sourceRef": "session-42",
      "turns": [
        { "role": "user",      "content": "switch the queue to pgmq" },
        { "role": "assistant", "content": "Done — migrated worker, dropped redis." }
      ]
    }]
  }'

Ingest a document

await brain.ingest({
  items: [{
    type: "document",
    content: "# ADR-007\n\nWe moved the job queue from Redis to pgmq on 2026-05-10…",
    title: "ADR-007: pgmq migration",
    path: "/workspace/decisions/adr-007-pgmq.md",
    visibility: "workspace",
  }],
});

Item shapes

// Conversation
{
  type: "conversation",
  turns: [{ role: "user" | "assistant" | "system", content: string }],
  sourceRef: string,           // caller-side stable id — deduplication anchor
  visibility?: "private" | "workspace",
  idempotencyKey?: string      // explicit dedup key if sourceRef isn't enough
}

// Document
{
  type: "document",
  content: string,
  title?: string,
  path?: string,               // brain path; auto-routed to /private/ if omitted
  tags?: string[],
  visibility?: "private" | "workspace",
  sourceRef?: string
}

What gets extracted

Conversations are routed through the signal-extraction pipeline: entity resolution (people, systems, projects), fact extraction, and link detection. Documents get the same treatment plus they land at a stable brain path for direct reads. Neither is instant — check extraction state with GET /v1/brain/status (pendingJobs, lastIngestAt) or unison jobs ls.

sourceRef and idempotency

sourceRef is your stable caller-side id (a session id, thread id, webhook message id). Re-ingesting the same sourceRef is safe — the pipeline deduplicates. For pipelines that replay, pass an explicit idempotencyKey as a second anchor.

Visibility

ValueWho sees extracted knowledge
"private" (default)only the calling key (or actor)
"workspace"entire workspace on next recall

For direct document writes with explicit path control, use PUT /v1/brain/doc — see Documents.

See also: API reference

On this page