Reading Data from the Graph

Zep provides APIs to read Edges, Nodes, and Episodes from the graph. These elements can be retrieved individually using their UUID, or as lists associated with a specific user_id or graph_id. The latter method returns all objects in that user’s or graph’s data.

Examples of each retrieval method are provided below.

Reading Edges

1from zep_cloud.client import Zep
2
3client = Zep(
4 api_key=API_KEY,
5)
6
7edge = client.graph.edge.get(edgeUuid)

Reading Nodes

1from zep_cloud.client import Zep
2
3client = Zep(
4 api_key=API_KEY,
5)
6
7node = client.graph.node.get_by_user(userUuid)

Reading Episodes

1from zep_cloud.client import Zep
2
3client = Zep(
4 api_key=API_KEY,
5)
6
7episode = client.graph.episode.get_by_graph_id(graph_uuid)

Listing artifacts in bulk

The methods above return a single artifact by its UUID. To enumerate artifacts of a given type in bulk, use the list methods. Where searching the graph ranks results by relevance to a query, the list methods return everything of a given type in a user or graph, with filtering, sorting, and pagination applied server-side.

Reach for these methods when you are not answering a question but enumerating data: rendering an entity browser or a facts table in a UI, exporting a graph, or auditing what a graph contains. Sorting and cursor pagination let you walk large graphs in stable, predictable pages instead of pulling everything into memory at once.

The same parameters — filters, order_by, direction, limit, and cursor — are shared across four artifact types:

Each type exposes two list methods: get_by_user_id for a user’s graph and get_by_graph_id for a named graph. Both return a flat array of typed objects.

Shared parameters

All four artifact types accept the same parameters on both get_by_user_id and get_by_graph_id.

ParameterTypeDescriptionDefault
filtersSearchFiltersRestrict which artifacts are returned. Same type as graph.search, supporting date filters (created_at, valid_at, expired_at, invalid_at as 2D OR/AND arrays), edge_types/exclude_edge_types, node_labels/exclude_node_labels, and property filters.
order_bystringField to sort by: "created_at" or "uuid"."uuid"
directionstringSort direction: "asc" or "desc"."desc"
limitintegerMaximum number of items returned per call.
cursorstringOpaque forward cursor for the next page. Read it from the Zep-Next-Cursor response header (see Pagination).
uuid_cursorstringDeprecated legacy cursor. Pass the UUID of the last item from the previous page. Prefer cursor.

The filters object is the same SearchFilters type documented under Search Filters, so date, type, and property filters behave identically here. Refer to that section for the full filter reference.

Listing nodes

List the entities in a user’s graph, most recently created first.

1from zep_cloud.client import Zep
2
3client = Zep(api_key=API_KEY)
4
5# The 20 most recently created entities in a user's graph.
6nodes = client.graph.node.get_by_user_id(
7 user_id="emily-painter",
8 order_by="created_at",
9 direction="desc",
10 limit=20,
11)
12
13for node in nodes:
14 print(node.name, node.created_at)

To list entities in a named (non-user) graph, use get_by_graph_id with a graph_id. See Entities for per-type detail.

Listing edges with filters

Pass a SearchFilters object to narrow the results. The example below lists facts on a named graph that were created in July 2025 and use specific edge types.

1from zep_cloud.client import Zep
2from zep_cloud.types import SearchFilters, DateFilter
3
4client = Zep(api_key=API_KEY)
5
6edges = client.graph.edge.get_by_graph_id(
7 graph_id="my-graph",
8 filters=SearchFilters(
9 edge_types=["WORKS_WITH", "COLLABORATES_ON"],
10 created_at=[
11 [
12 DateFilter(comparison_operator=">=", date="2025-07-01T00:00:00Z"),
13 DateFilter(comparison_operator="<", date="2025-08-01T00:00:00Z"),
14 ],
15 ],
16 ),
17 order_by="created_at",
18 direction="desc",
19 limit=50,
20)
21
22for edge in edges:
23 print(edge.fact, edge.created_at)

The date filter uses the same 2D OR/AND array structure as graph.search: the outer array is OR, the inner array is AND. See Datetime Filtering for the full semantics.

Pagination

The list methods return a flat array, not a paginated envelope. The forward cursor for the next page comes back in the Zep-Next-Cursor response header. To read it, use the SDK’s raw response accessor — with_raw_response in Python, withRawResponse in TypeScript, and WithRawResponse in Go — which returns both the parsed data and the raw HTTP response.

Pass the cursor from one page as the cursor argument of the next call. When the header is empty, there are no more pages.

1from zep_cloud.client import Zep
2
3client = Zep(api_key=API_KEY)
4
5all_nodes = []
6cursor = None
7
8while True:
9 resp = client.graph.node.with_raw_response.get_by_user_id(
10 user_id="emily-painter",
11 order_by="created_at",
12 direction="desc",
13 limit=100,
14 cursor=cursor,
15 )
16 all_nodes.extend(resp.data)
17
18 cursor = resp.headers.get("Zep-Next-Cursor")
19 if not cursor:
20 break

uuid_cursor is the deprecated legacy pagination path: pass the UUID of the last item from the previous page to fetch the next one. Prefer the opaque cursor from the Zep-Next-Cursor header, which encodes the sort field, direction, and continuation position.

Listing observations and thread summaries

Observations and thread summaries use the same shared parameters. The examples below list each for a user, newest first.

1# Observations for a user, newest first.
2observations = client.graph.observation.get_by_user_id(
3 user_id="emily-painter",
4 order_by="created_at",
5 direction="desc",
6 limit=20,
7)
8
9# Thread summaries across a user's threads.
10summaries = client.graph.thread_summary.get_by_user_id(
11 user_id="emily-painter",
12 limit=20,
13)

See Observations and Thread summaries for per-type detail. Use get_by_graph_id for a named graph.

Episodes are different

Episodes do not use the shared list parameters. graph.episode.get_by_user_id and graph.episode.get_by_graph_id accept only lastn — the most-recent-N episodes. They do not support cursor, filters, order_by, direction, or limit.

1# Episodes accept only lastn — the most recent N episodes.
2response = client.graph.episode.get_by_user_id(
3 user_id="emily-painter",
4 lastn=10,
5)
6episodes = response.episodes