Skip to main content

Visualization payloads

visualize_graph() renders a self-contained HTML page. The functions on this page return the same data as plain dictionaries instead, so an external UI or dashboard can render it itself. Both paths run through the same authorized, bounded graph read and the same preprocess() step, so they cannot drift on the data — only on how each packages it.
These builders are not re-exported on the top-level cognee module. Import them from cognee.api.v1.visualize.

visualize_graph_json()

The graph as a JSON-safe dict, without the semantic layout. Authorization, dataset resolution and the bounded fetch are shared with visualize_graph(), so the same arguments give you exactly the subgraph the HTML page would have shown — including the bounded-subgraph defaults.

Parameters

bool
default:"True"
Embed the caller’s search and improve events in the payload as search_events.
list
default:"None"
Restrict embedded session events to these sessions.
Optional[User]
default:"None"
User context for dataset access. Falls back to the default user.
Optional[Union[str, UUID]]
default:"'main_dataset'"
Dataset name or id to read.
bool
default:"False"
Return the entire graph instead of a bounded subgraph.
Optional[str]
default:"None"
Query string whose nearest vector hits seed the subgraph.
Optional[List[str]]
default:"None"
Explicit seed node ids for neighborhood expansion.
Optional[Any]
default:"None"
A recall() or search result whose graph provenance seeds the subgraph. Python-only — there is no HTTP equivalent.
int
default:"2"
k-hop expansion depth around the seeds.
int
default:"10"
Maximum number of seed nodes.
int
default:"500"
Hard cap on nodes after expansion.

Returns

dict — every field of the renderer’s PreprocessedGraph snapshot, plus search_events: Semantic positions are deliberately absent — see below.

visualize_semantic_json()

Semantic positions and clusters for the same subgraph, computed on demand. Pass the same dataset/seed/depth/cap arguments you passed to visualize_graph_json() to lay out the same subgraph. This is the one call that fetches embeddings and runs the PCA (or UMAP) projection over them, bounded to SEMANTIC_NODE_CAP = 2000 nodes. The HTML render computes the layout on every render; splitting it out here means a client that never opens a semantic view never pays for it.

Returns

dict with semantic_positions and semantic_clusters. Both are null together — the layout is best-effort, so no embeddings resolving or the projection failing yields {"semantic_positions": null, "semantic_clusters": null} rather than an error.

build_brains_payload()

A small graph preview for every dataset the caller may read — their own, their tenant’s, and anything granted to a role they belong to. There is no dataset argument: this is the overview across brains, not one brain.

Returns

dict keyed by dataset id, each value {"name", "nodes", "links", "node_set_colors"} — not the full visualize_graph_json() shape, since an overview does not need one dataset’s worth of schema/memory/pipeline detail multiplied by every dataset. max_nodes is applied independently per dataset; there is no larger combined cap.

get_live_events()

The delta of search and improve events since a cursor, for refreshing a timeline without rebuilding the whole graph payload. dataset_id gates who may call this — the same read-permission check every other visualization entry point runs — not which events come back. Session events are collected per user, matching the search_events already embedded in visualize_graph_json(). Raises PermissionDeniedError when the dataset does not exist or the caller cannot read it.

Returns

{"events": [...], "cursor": <ISO datetime string or None>}. Omit since on the first call to get everything available, then pass the previous response’s cursor straight back as the next since — the filter is strict (>, not >=), so no event is delivered twice. When nothing new has happened the response echoes back the since you sent, or null if you sent none.

get_memory_provenance_payload()

The memory-provenance graph — the ownership and data-flow story read purely from the relational database — packaged as a dict. Same scoping rules as get_memory_provenance_graph(): in multi-tenant deployments you must pass a scope, or the read spans every tenant.

Returns

dict in the same shape visualize_graph_json() returns (nodes, links, color_maps, schema_graph, memory_map, and the rest) — not the raw (nodes, edges) tuple get_memory_provenance_graph() returns.

Over HTTP

Each builder above has an HTTP endpoint in front of it. GET /api/v1/visualize/json, GET /api/v1/visualize/semantic and GET /api/v1/schema/provenance/json are JSON siblings of existing HTML endpoints; /brains and /live-events have no HTML equivalent. POST /api/v1/visualize/multi remains HTML-only. All of them require authentication. The three that take a dataset_id enforce the same read permission as GET /api/v1/visualize; /brains takes none and simply returns the datasets the caller can read. /json and /semantic accept the same query params as GET /api/v1/visualizedataset_id (required), full, query, seed_node_ids, neighborhood_depth, neighborhood_seed_top_k and max_nodes — with the defaults listed above. Pass identical arguments to both to get a graph and its semantic layout for the same subgraph.

Errors

JSON error bodies carry a fixed message and never the exception text — full detail is server-logged instead.
  • 403/live-events only, when the caller lacks read permission on the dataset (or it does not exist).
  • 409 — the payload could not be built. Note that a semantic layout that cannot be computed is not an error: /semantic answers 200 with both fields null, and only returns 409 if the underlying graph fetch itself fails.

See also