Brainby arc-labs/docs
Recipe

Walk the entity graph

Encode a transcript, list the entities the pipeline extracted, and walk the relation graph with /v1/entities and /v1/graph.

Every encode runs the extraction pipeline (pattern → classifier → LLM). When it sees a name, place, or organization it creates or merges an entity, and it connects two entities with a typed relation. This structured knowledge is the typed graph, distinct from the whole-memory recall path.

Reading the typed graph is a wire-client / HTTP-edge capability — it is not on the strict HTTP-client verb subset. The examples below use the HTTP edge routes directly (Entities, Graph); the wire client (BrainClient) exposes the same surface programmatically via listEntities, traverseRelations, and graphFetch.

Encode a transcript

import { BrainHttpClient } from '@brain-db/sdk';

const brain = new BrainHttpClient({ apiKey: process.env.BRAIN_API_KEY! });

for (const turn of [
  'I met with Lina from Globex yesterday at their HQ in Hamburg.',
  'Productive meeting. She introduced me to Marco, their CTO.',
]) {
  await brain.encode({ text: turn });
}
from brain_db_sdk import BrainHttpClient

brain = BrainHttpClient(os.environ['BRAIN_API_KEY'])

for turn in [
    'I met with Lina from Globex yesterday at their HQ in Hamburg.',
    'Productive meeting. She introduced me to Marco, their CTO.',
]:
    brain.encode(turn)

Extraction runs asynchronously after the durable ack, so give the pipeline a moment before reading the graph. It produces entities for Lina, Globex, Hamburg, and Marco, plus relations such as Lina —brain:works_at→ Globex.

List entities

Filter by name prefix (see GET /v1/entities):

curl -s "$BRAIN_BASE_URL/v1/entities?prefix=Globex&limit=10" \
  -H "Authorization: Bearer $BRAIN_API_KEY"
{
  "entities": [
    {
      "entity_id": "0a1b2c3d-…",
      "entity_type_id": 2,
      "canonical_name": "Globex",
      "aliases": ["globex"],
      "mention_count": 2,
      "merged_into": null
    }
  ],
  "count": 1
}

Walk from an entity

Traverse relations outward from an anchor entity, two hops (POST /v1/entities/{id}/traverse):

curl -s -X POST "$BRAIN_BASE_URL/v1/entities/0a1b2c3d-…/traverse" \
  -H "Authorization: Bearer $BRAIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "direction": "both", "max_depth": 2 }'
{
  "paths": [
    { "steps": [{ "relation_id": "…", "from": "…lina", "to": "0a1b2c3d-…", "relation_type": "brain:works_at", "depth": 1 }] }
  ],
  "total_paths": 1,
  "truncated": false
}

Export the whole graph

To render the graph yourself, page the typed-graph export (GET /v1/graph) — a nodes-and-edges snapshot with keyset pagination:

curl -s "$BRAIN_BASE_URL/v1/graph?limit=200" \
  -H "Authorization: Bearer $BRAIN_API_KEY"
{
  "nodes": [
    { "id": "0a1b2c3d-…", "kind": "entity", "label": "Globex", "type_qname": "brain:Organization" }
  ],
  "edges": [
    { "from_id": "…lina", "to_id": "0a1b2c3d-…", "kind": "relation", "label": "brain:works_at" }
  ],
  "next_cursor": "9f8e7d6c"
}

The entity-graph retriever already walks this graph inside recall — you get graph-backed hits without touching these endpoints. Reach for the graph routes when you want to render the graph, not to retrieve.

Entities merge across encodes within a scope — "Globex" mentioned twice is one entity with mention_count: 2, not two. For isolated graphs per user, isolate by (namespace, agent) scope (see Identity from a JWT), not by trying to tag memories apart.

Was this page helpful?

On this page