Skip to content

Graph

GET /api/v1/graph/seed

Returns a BFS neighborhood of a seed node up to the requested depth. Used by the dashboard graph view for the initial paint.

If no seed is supplied the tenant's hub node (highest connection_count, excluding archived nodes) is used automatically.

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | seed | string | — | ID of the seed node. Omit to use the hub node. | | depth | 1 | 2 | 3 | 1 | BFS depth. Higher values return larger neighborhoods. |

{
"seed_id": "abc123",
"nodes": [
{
"id": "abc123",
"title": "Node title",
"para_category": "projects",
"para_item_id": "para-456",
"connection_count": 5,
"depth": 0
}
],
"edges": [
{
"source": "abc123",
"target": "def456",
"link_type": "related",
"weight": 0.9
}
],
"frontier_ids": ["def456"],
"meta": {
"node_count": 12,
"edge_count": 15,
"depth": 1
}
}

seed_id is null and all arrays are empty when the tenant has no nodes.

frontier_ids lists nodes at the deepest BFS hop that have additional unloaded neighbours. The dashboard uses these IDs to display the expansion affordance.

depth in each node is 0 for the seed itself and 1–3 for BFS hops.

| Status | Condition | |--------|-----------| | 400 | depth is not 1, 2, or 3 | | 401 | Missing or invalid authentication | | 404 | Seed node not found, belongs to another tenant, or is archived | | 429 | Rate limit exceeded |


GET /api/v1/graph/neighbors/:id

Returns the one-hop neighbours of a single node. Intended for on-demand expansion when the user clicks a frontier node in the graph view.

All returned nodes carry newly_added: true so the client can apply a fade-in animation.

When there are more neighbours than limit the response includes a next_cursor value for retrieving the next page.

| Parameter | Description | |-----------|-------------| | id | ID of the node whose neighbours to return. |

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | direction | out | in | both | both | Which link direction to follow. | | limit | 1–200 | 50 | Maximum number of neighbour nodes to return. | | cursor | string | — | Pagination cursor from a previous response. |

Cursors are opaque to clients. Do not parse or construct them. Internally they are base64url-encoded JSON:

  • direction=out or direction=in: encodes { dir, weight, source_id, target_id }. Results are ordered by weight DESC, source_id ASC, target_id ASC.
  • direction=both: encodes { out?: string, in?: string } — a composite of independent per-direction cursors. Each side pages independently; a side is absent once it is exhausted.

An invalid or expired cursor returns 400. Clients must not carry a cursor across seed changes.

{
"node_id": "abc123",
"nodes": [
{
"id": "def456",
"title": "Neighbor node",
"para_category": null,
"para_item_id": null,
"connection_count": 3,
"newly_added": true
}
],
"edges": [
{
"source": "abc123",
"target": "def456",
"link_type": "related",
"weight": 0.9
}
],
"next_cursor": null
}

next_cursor is null when there are no further pages.

| Status | Condition | |--------|-----------| | 400 | Invalid direction, limit out of range, or invalid cursor | | 401 | Missing or invalid authentication | | 404 | Node not found, belongs to another tenant, or is archived | | 429 | Rate limit exceeded |