Manually Updating the Graph
Overview
Zep provides several ways to manually change a graph:
- Use
graph.add_nodesto add one or more nodes without creating relationships. - Use
graph.add_fact_tripleto add a relationship and its source and target nodes together. - Use
graph.node.updateto update an existing node by UUID. - Use
graph.edge.updateto update an existing edge by UUID.
Adding Nodes
Use add_nodes when you already have structured entity data and do not need Zep to extract nodes from an episode or create relationships between them. Zep stores the node contents you provide and derives the search representation from each node’s name.
The same method handles both single-node and batch creation. Each request must contain between 1 and 100 nodes and target one user_id or graph_id.
Adding a Single Node
Pass one item in the nodes list to add a single node:
Adding Nodes in a Batch
Include multiple items in the same nodes list to create up to 100 nodes in one request. The nodes may use different entity types, but they must all belong to the same user or graph.
Node Creation Behavior
add_nodes returns a task_id and the accepted nodes immediately. Each returned node includes its server-assigned or caller-supplied UUID, but the node is not available to read or search until the asynchronous task succeeds. See Check Data Ingestion Status for how to poll the task.
Supplying a UUID makes node creation retry-safe and enables upserts:
- If the UUID does not exist, Zep creates the node with that UUID.
- If the UUID already exists in the graph, Zep updates that node. A non-empty summary or label replaces the existing value, attributes are merged, and the existing name is preserved.
- If you omit the UUID, Zep creates a new node with a server-assigned UUID. Nodes are not deduplicated by name or content.
When add_nodes upserts an existing node, an attribute set to null is stored as null; it is not deleted. Use graph.node.update to rename a node, delete an attribute, or clear its entity type.
Each node supports the following fields:
Updating a Node
Use graph.node.update to update an existing node by UUID. Only the fields you provide are changed, and the updated node is returned synchronously.
Node attributes are merged with the existing attributes. Set an attribute to null to delete it. If you provide labels, the list replaces the existing labels. Python and TypeScript callers can use an empty list to clear the node’s entity type.
The current Go SDK omits an empty Labels slice from the request. To clear a node’s entity type from Go, send {"labels": []} directly to PATCH /graph/node/{uuid}.
Updating an Edge
Use graph.edge.update to update an existing entity edge by UUID. You can change its relationship name, fact, temporal fields, and attributes. The source and target node UUIDs cannot be changed.
Edge attributes are merged with the existing attributes. Set an attribute to null to delete it. Temporal fields use RFC 3339 / ISO 8601 timestamps.
Adding a Fact Triplet
You can add manually specified fact/node triplets to the graph. Provide the fact, a relationship name, and the source and target node names or UUIDs. Zep will then create a new corresponding edge and nodes, or use existing nodes and an edge if they represent the same entities and relationship. If the new fact invalidates an existing fact, Zep marks the existing fact as invalid and adds the new fact triplet.
The add_fact_triple method returns a task_id that can be used to track the processing status of the operation. See the Check Data Ingestion Status recipe for how to poll task status.
Retrieving Created UUIDs
Because fact triple creation is asynchronous, the UUIDs for the edge and nodes are not returned immediately. After the task completes, you can retrieve them by calling client.task.get() with the task_id returned from add_fact_triple. The task’s params field will contain edge_uuid, source_node_uuid, and target_node_uuid.
Custom types and attributes
You can attach custom scalar attributes to nodes and edges, and optionally reference custom entity and edge types from your ontology to enforce a schema.
source_node_labels/target_node_labels— specify a single entity type name. When it matches an ontology type with properties, the node attributes are validated against it.fact_name— serves as both the relationship display name and the edge type name looked up in your ontology.source_node_attributes/target_node_attributes/edge_attributes— custom scalar properties on those nodes and edges, usable for filtering in graph searches.
Attribute validation — specifying types is optional. If a label or fact_name is not found in your ontology, attributes pass through without validation:
When validation activates, every attribute key and value type must match the schema — otherwise the call returns HTTP 400.
Attribute values must be scalar types: string, number, boolean, or null. Nested objects and arrays are not supported.
Fact triplet metadata
You can attach metadata to a fact triple, which makes the resulting edge and nodes filterable via episode metadata filters in graph search. See Episode metadata for full details on metadata constraints and update semantics.
Metadata values must be scalars (string, number, boolean, or null) or non-empty arrays of scalars. A maximum of 10 keys are allowed.
Specifying Node UUIDs
You can optionally specify source_node_uuid and/or target_node_uuid to control which nodes are used. The behavior depends on whether you provide a UUID:
See the associated SDK reference for complete details on all available parameters.