Reference
Relationships API
Navigate the directed relationship graph that connects your workspace memories. Relationships are typed, directed edges discovered post-hoc by multiple heuristics: file overlap, concept overlap, embedding similarity, and session context. Use these endpoints to explore clusters of related knowledge, visualise how concepts connect, and find the shortest path between two memories.
See Relationships Concepts for a full explanation of relationship types and discovery methods.
Base URL and Authentication
https://api.neuroloom.devAll requests require an API key:
Authorization: Token $MEMORIES_API_TOKENRelationship Types
| Value | Direction | Meaning |
|---|---|---|
references | A → B | A explicitly references or depends on B (file/symbol overlap) |
related_to | A → B | General semantic relatedness; default for heuristic discovery |
caused_by | A → B | A is the consequence of B (LLM only; directed) |
contradicts | A ↔ B | A and B conflict on the same topic (LLM only; symmetric) |
supersedes | A → B | A replaces B; B is the older knowledge (LLM only; directed) |
similar_to | A ↔ B | Discovered by embedding cosine similarity (symmetric) |
depends_on | A → B | A requires B to hold; never heuristic-assigned (LLM/manual only) |
Get Raw Graph Data
GET /api/v1/memories/graphReturn all nodes and edges in the workspace's memory graph. Use this for full-graph visualisation or to build a local relationship index. For large workspaces, prefer the explore endpoint to fetch a bounded subgraph.
Response — 200 OK
{
"nodes": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"title": "Prefer async SQLAlchemy for all DB calls",
"memory_type": "pattern",
"importance_score": 0.9,
"pagerank_score": 0.51,
"community_label": "database-patterns"
}
],
"edges": [
{
"source_memory_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"target_memory_id": "b9987766-5544-aabb-ccdd-eeff00112233",
"relationship_type": "similar_to",
"discovery_method": "embedding_similarity",
"confidence": 0.87,
"is_bidirectional": false,
"created_at": "2026-03-20T09:00:00Z"
}
]
}curl "https://api.neuroloom.dev/api/v1/memories/graph" \
-H "Authorization: Token $MEMORIES_API_TOKEN"pagerank_score and community_label are computed by the background graph analysis job. They are null for memories whose embeddings have not yet been processed.
Explore a Topic Subgraph
POST /api/v1/memories/exploreSeed a graph traversal with a query, then expand outward through relationship edges to return a bounded subgraph. Useful for understanding how a topic connects through your workspace knowledge, and for building contextual memory injections without retrieving the entire graph.
memory_explore(
query="async database patterns and performance",
max_nodes=30,
relationship_types=["similar_to", "references", "related_to"],
min_edge_confidence=0.7,
seed_limit=5
)The MCP memory_explore tool exposes all the same parameters as the REST endpoint.
import httpx, os
response = httpx.post(
"https://api.neuroloom.dev/api/v1/memories/explore",
headers={"Authorization": f"Token {os.environ['MEMORIES_API_TOKEN']}"},
json={
"query": "async database patterns and performance",
"max_nodes": 30,
"relationship_types": ["similar_to", "references", "related_to"],
"min_edge_confidence": 0.7,
"seed_limit": 5,
},
)
subgraph = response.json()
print(f"Nodes: {len(subgraph['nodes'])}, Edges: {len(subgraph['edges'])}")curl -X POST "https://api.neuroloom.dev/api/v1/memories/explore" \
-H "Authorization: Token $MEMORIES_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "async database patterns and performance",
"max_nodes": 30,
"relationship_types": ["similar_to", "references", "related_to"],
"min_edge_confidence": 0.7,
"seed_limit": 5
}'Request body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
query | string | Yes | — | Natural language topic or question used to find seed memories via semantic search. |
max_nodes | integer | No | 50 | Maximum nodes to include in the returned subgraph. Maximum value: 200. |
relationship_types | array of strings | No | all types | Restrict traversal to these edge types. Omit to traverse all relationship types. |
min_edge_confidence | float | No | 0.0 | Minimum edge confidence for an edge to be traversed. Set 0.7 or higher to filter noise. |
seed_limit | integer | No | 5 | Number of seed memories to start the traversal from. Seeds are chosen by semantic similarity to query. |
Response — 200 OK
{
"nodes": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"title": "Prefer async SQLAlchemy for all DB calls",
"memory_type": "pattern",
"importance_score": 0.9,
"pagerank_score": 0.51,
"community_label": "database-patterns"
},
{
"id": "c3344556-6677-ccdd-eeff-001122334455",
"title": "Configure connection pool for production load",
"memory_type": "decision",
"importance_score": 0.82,
"pagerank_score": 0.38,
"community_label": "database-patterns"
}
],
"edges": [
{
"source_memory_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"target_memory_id": "c3344556-6677-ccdd-eeff-001122334455",
"relationship_type": "references",
"confidence": 0.81
}
],
"seed_memories": ["a1b2c3d4-e5f6-7890-abcd-ef1234567890"]
}seed_memories lists the memory IDs used as traversal starting points. All remaining nodes were reached via graph traversal from those seeds.
Find Shortest Path
POST /api/v1/memories/pathFind the shortest relationship path between two memories using BFS traversal. Returns the sequence of memory IDs and the edges connecting them. Useful for understanding how two apparently unrelated concepts connect through the workspace's relationship graph.
Request body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
source_memory_id | string (UUID) | Yes | — | Starting memory UUID. |
target_memory_id | string (UUID) | Yes | — | Destination memory UUID. |
max_depth | integer | No | 5 | Maximum BFS depth. Higher values find longer paths but take more time. |
relationship_types | array of strings | No | all types | Restrict path search to these edge types. |
Response — 200 OK
{
"path": [
"a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"c3344556-6677-ccdd-eeff-001122334455",
"b9987766-5544-aabb-ccdd-eeff00112233"
],
"edges": [
{
"source_memory_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"target_memory_id": "c3344556-6677-ccdd-eeff-001122334455",
"relationship_type": "references",
"confidence": 0.81
},
{
"source_memory_id": "c3344556-6677-ccdd-eeff-001122334455",
"target_memory_id": "b9987766-5544-aabb-ccdd-eeff00112233",
"relationship_type": "references",
"confidence": 0.91
}
],
"depth": 2
}If no path exists within max_depth, returns:
{ "path": [], "edges": [], "depth": 0 }curl -X POST "https://api.neuroloom.dev/api/v1/memories/path" \
-H "Authorization: Token $MEMORIES_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"source_memory_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"target_memory_id": "b9987766-5544-aabb-ccdd-eeff00112233",
"max_depth": 5,
"relationship_types": ["references", "related_to", "similar_to"]
}'How Relationships Are Discovered
Relationships are created automatically by background jobs that run after each memory is stored or updated. The four discovery heuristics are:
| Method | How It Works |
|---|---|
embedding_similarity | pgvector cosine similarity between memory embeddings. Creates similar_to edges above a confidence threshold. |
file_overlap | Memories sharing one or more source_files entries. Creates references or related_to edges. |
concept_overlap | Memories sharing concepts labels. Creates related_to edges weighted by overlap count. |
session_context | Memories created in the same session or temporally proximate sessions. Creates related_to edges. |
Declare a Relationship Manually
The four heuristics above discover edges automatically. When you already hold ground-truth a heuristic can't reliably infer — this decision replaces that one, this task depends on that one — declare the edge yourself instead of waiting for discovery to find it. This is the same "declare what you know, the engine discovers what you don't" split that runs through the rest of Neuroloom: you assert the connections you're certain of, and the discovery pipeline keeps filling in the ones you didn't think to name.
POST /api/v1/relationships
DELETE /api/v1/relationshipsRequest body (POST)
| Field | Type | Required | Description |
|---|---|---|---|
source_id | string (UUID) | Yes | Source memory id. |
target_id | string (UUID) | Yes | Target memory id. Must differ from source_id. |
relationship_type | string | Yes — no default | One of supersedes, related_to, depends_on. Every other type is discovery-only and rejected with a 422. |
context | string | No | Optional human-readable explanation of why the relationship exists. |
There is no workspace_id field — the workspace is resolved from your authenticated API key. The created edge is stamped discovery_method: "manual" and confidence: 1.0, both server-fixed and not caller-settable, and is immune to the nightly reclassifier that would otherwise silently retype a discovered edge.
curl -X POST "https://api.neuroloom.dev/api/v1/relationships" \
-H "Authorization: Token $MEMORIES_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"source_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"target_id": "b9987766-5544-aabb-ccdd-eeff00112233",
"relationship_type": "supersedes",
"context": "Replaces the Redis-based caching approach."
}'Response — 201 Created
{
"relationships": [
{
"id": "c3344556-6677-ccdd-eeff-001122334455",
"source_memory_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"target_memory_id": "b9987766-5544-aabb-ccdd-eeff00112233",
"relationship_type": "supersedes",
"discovery_method": "manual",
"confidence": 1.0,
"is_bidirectional": false,
"context": "Replaces the Redis-based caching approach.",
"created_at": "2026-07-15T10:30:00Z"
}
]
}relationships is always a list — one row for a directed type (supersedes/depends_on), two mirrored rows for the symmetric related_to type.
DELETE /relationships retracts a manual edge, by relationship_id or by the natural key (source_id + target_id + relationship_type) — not both, not neither. Deleting a discovered (non-manual) edge returns 409.
Only supersedes, related_to, and depends_on are writable. contradicts is excluded because a false edge does asymmetric damage to the epistemic-confidence score it feeds; caused_by is excluded because it asserts a causal claim with its own liability if wrong. See Relationships Concepts for the full allowlist rationale, and the Decision Tracking cookbook for a worked example.
Error Responses
| Status | When |
|---|---|
401 Unauthorized | Missing or invalid Authorization header. |
404 Not Found | A memory UUID supplied in the path request does not exist. |
422 Unprocessable Entity | Invalid parameter value (e.g. max_nodes > 200, unknown relationship_types value). |
422 Unprocessable Entity (self_edge_not_allowed) | POST /relationships — source_id and target_id refer to the same memory. A memory cannot hold a relationship with itself. |
422 Unprocessable Entity (excluded_relationship_type) | POST /relationships — relationship_type is not one of the three caller-writable types (supersedes, related_to, depends_on). contradicts, caused_by, references, and similar_to are discovery-only. |
409 Conflict (duplicate_manual_relationship) | POST /relationships — a manual edge already exists between these two memories in this direction. Includes the cross-direction case: a manual related_to(A,B) edge mirrors to (B,A,manual), which blocks a later manual supersedes(B,A). Delete the existing edge and recreate it with the desired type instead. |
409 Conflict (relationship_not_manual) | DELETE /relationships — the targeted edge exists but was created by automatic discovery, not declared by a caller. Only manual edges can be deleted through this endpoint. |
429 Too Many Requests | POST/DELETE /relationships — the workspace has exceeded its relationship-write rate. Response includes a Retry-After header (uncoded — no code field). |
429 Too Many Requests | POST /relationships — the workspace has reached its manual-relationship edge-count cap, proportional to its memory count (uncoded — no code field). Delete unused manual edges, or ask us to raise the ceiling. |
Related
- Relationships and Graph — relationship types, discovery heuristics, and community detection
- Graph Exploration — topic subgraphs, shortest paths, and cluster discovery