Skip to main content

cognee.update()

Description

Update existing data in Cognee. The document keeps its data_id across updates: the replacement is re-ingested pinned to the resolved id — the exact id, or the recorded pre-split legacy_id of a document forked by the dataset-scoping upgrade — so id mappings you hold externally never break. update() replaces exactly one document per call and never creates one: lists of more than one item are rejected, and a data_id that resolves to no document in the dataset raises UpdateTargetNotFoundError (HTTP 404). Use add() for new documents. Supported Input Types:
  • Text strings: Direct text content (str) - any string that is not a file://, s3://, http:// or https:// URL and does not point to an existing local file. An absolute-looking string that is not an existing file (for example "/remember to call the dentist") is ingested as text content on every platform, including Windows.
  • File paths: Local file paths as strings in these formats:
    • Absolute paths: “/path/to/document.pdf” (treated as a file reference only when the file exists)
    • File URLs: “file:///path/to/document.pdf” or “file://relative/path.txt”
    • S3 paths: “s3://bucket-name/path/to/file.pdf”
  • Binary file objects: File handles/streams (BinaryIO)
  • Lists: Accepted only with exactly one item — update() replaces one document per call, and a longer list is rejected
Supported File Formats:
  • Text files (.txt, .md, .csv)
  • PDFs (.pdf)
  • Images (.png, .jpg, .jpeg) - extracted via OCR/vision models
  • Audio files (.mp3, .wav) - transcribed to text
  • Code files (.py, .js, .ts, etc.) - parsed for structure and content
  • Office documents (.docx, .pptx) Workflow:
  1. Data Resolution: Resolves file paths and validates accessibility
  2. Content Extraction: Extracts text content from various file formats
  3. Dataset Storage: Stores processed content in the specified dataset
  4. Metadata Tracking: Records file metadata, timestamps, and user permissions
  5. Permission Assignment: Grants user read/write/delete/share permissions on dataset
Args: data_id: UUID of existing data to update data: The latest version of the data. Can be:
  • Single text string: “Your text content here”
  • Absolute file path: “/path/to/document.pdf” (must exist; otherwise the string is ingested as text)
  • File URL: “file:///absolute/path/to/document.pdf” or “file://relative/path.txt”
  • S3 path: “s3://my-bucket/documents/file.pdf”
  • Single-item list: [“Updated content”] (lists of more than one item are rejected)
  • Binary file object: open(“file.txt”, “rb”) dataset_name: Name of the dataset to store data in. Defaults to “main_dataset”. Create separate datasets to organize different knowledge domains. user: User object for authentication and permissions. Uses default user if None. Default user: “default_user@example.com” (created automatically on first use). Users can only access datasets they have permissions for. node_set: Optional list of node identifiers used to organize and filter data points in the knowledge graph. Not an access-control mechanism. vector_db_config: Optional configuration for vector database (for custom setups). graph_db_config: Optional configuration for graph database (for custom setups). dataset_id: Optional specific dataset UUID to use instead of dataset_name.
Returns: One dict on every path (schema: UpdateResult) — see Returns.

Parameters

UUID
required
UUID of the data item to update.
Union[BinaryIO, list[BinaryIO], str, list[str]]
required
New data to replace the existing data.
UUID
required
UUID of the dataset containing the data.
User
default:"None"
User performing the operation.
Optional[List[str]]
default:"None"
List of node set names to associate.
dict
default:"None"
Override vector database configuration.
dict
default:"None"
Override graph database configuration.
dict[str, dict[str, Any]]
default:"None"
Custom loader configuration.
bool
default:"True"
If true, skip unchanged data. The skip runs whenever this or data_cache is true, so a full re-cognify requires both to be False.
bool
default:"True"
Companion flag to incremental_loading — either one being true enables the already-processed skip for a data item.
bool
default:"True"
Diff the new content against the stored text and re-ingest only the chunks the edit touched, leaving unaffected chunks and their entities in place. Falls back to a full rebuild when its preconditions are not met — see How it works for the full set.
type[BaseModel]
default:"KnowledgeGraph"
Pydantic model the extraction step fills in. A non-default model disables the chunk-level path.
Optional[str]
default:"None"
Custom extraction prompt. Supplying one disables the chunk-level path.
type
default:"TextChunker"
Chunking strategy. Must match the one that built the document’s stored chunks; a mismatch falls back to the full flow rather than failing. Chunk-level path only.
ChunkPolicy
default:"DEFAULT_CHUNK_POLICY"
Decides which chunks exist after the edit and what happens to the old ones. Chunk-level path only, and not exposed on the HTTP route.

Returns

dict update() returns one dict on every path — chunk-level, unchanged, full rebuild, or failed rebuild — validated by the UpdateResult model (cognee.api.v1.update.result). The same body comes back from a local call, from PATCH /api/v1/update, and over a serve() connection. It is a superset of the chunk-level summary earlier releases returned, so result["status"] == "incremental" and result["kept_chunks"] keep working.
A failed rebuild is returned, not raised: the call hands back the data_id and the error so you can retry that one update. Over HTTP it keeps the 500 status but sends this same body. fallback.reason is one of nine values: fallback.detail is a sentence naming the specific cause, for example "chunk-level update does not reconcile node_set or document metadata".

How it works

With chunk_level_diff left at its default, update() diffs the new content against the stored text and touches only the chunks the edit changed. When that path’s preconditions are not met — a first ingestion, non-text content, a document whose stored chunks predate chunk-scoped ownership (anything ingested before v1.5.4), stored chunks that no longer tile the stored text, a graph or vector store without the narrow operations the path needs, a chunker that does not match the stored chunks, a node_set or changed DataItem metadata, a replacement that changes the content type (extension, MIME type, or loader), a non-default graph_model or custom_prompt, or a per-call vector_db_config/graph_db_config — it falls back to a full rebuild of the specified document, logging a warning and naming the cause in the result’s fallback:
  1. Drop memory — removes the document’s graph nodes, edges, and vector embeddings with forget(memory_only=True). The document’s row and its stored files stay. Entities that are also referenced by other documents in the same dataset are preserved (shared nodes are not deleted).
  2. Add — re-ingests the new version pinned to the resolved data_id, refreshing the existing row in place (content, name, metadata), so the document’s id, owner, and pre-split legacy_id are unchanged.
  3. Cognify — re-runs the knowledge graph construction pipeline on the dataset, extracting entities and relationships from the updated content. The rebuild keeps the chunk size the stored chunks were built with.
Because the row is never deleted, a rebuild that fails part-way leaves a document with its old content and no graph, which the next cognify() rebuilds — not a document that is gone. After update() completes, all graph nodes and relationships derived from the old content are removed and replaced with ones extracted from the new content. Relationships that no longer appear in the updated document are gone; new relationships found in the updated content are added. The document’s data_id is unchanged throughout — only the derived content moves.

Remote mode (serve())

While a serve() connection is active, update() is proxied to the remote instance over PATCH /api/v1/update. The routing happens before any local work, so the call operates on the remote document and writes nothing to the local store — updating a dataset that exists only on the remote instance succeeds instead of failing with a “Dataset not found” error from the local store. Only five parameters travel to the route: Every other parameter is dropped, and only some of them say so:
  • vector_db_config, graph_db_config, preferred_loaders, graph_model, custom_prompt, chunker, and policy have no slot on the route. Passing any of them logs a warning naming the dropped parameters, and the server applies its own configuration for those settings.
  • user, incremental_loading, and data_cache are dropped silently. user is redundant — the API key serve() connected with identifies the caller, and the server runs its own permission check — but incremental_loading=False and data_cache=False are no-ops over a connection, with nothing in the logs to say so.
The call still proceeds in both cases. Three other differences from local mode:
  • A file path string is uploaded as text, not as the file it points at. Locally, data="/path/to/document.pdf" (or an s3:// or file:// URL) resolves to that file and ingests its contents. Over serve() every string is sent as literal content, so the path itself becomes the document. To upload a file remotely, pass an open file object: data=open("document.pdf", "rb").
  • data must be text or a file object. Anything else raises a TypeError. As locally, a list is accepted only with exactly one item.
  • The return value has the same shape as locally. The client parses the server’s body — including the 500 body of a failed rebuild — through UpdateResult, so you get the same result dict key for key.
The document keeps its data_id across a remote update, exactly as it does locally.

Examples

Further details

incremental_loading=True (the default) tells the cognify step to skip data items that have already been processed successfully. Because a full rebuild clears the updated document’s processing record before re-adding it, that document is always re-cognified. Unchanged documents already in the dataset retain their completed status and are skipped, so only the updated document is re-processed.Set incremental_loading=False to force a full re-cognify of every document in the dataset — useful when you have changed your graph model or extraction prompt and want all content reprocessed.
This applies to local mode only. Over a serve() connection the parameter never reaches the server, so the call runs with the instance’s own settings and nothing is logged about it.
When a full rebuild drops the document’s memory, Cognee checks every node and edge it owned. Nodes that are also referenced by other documents in the same dataset are preserved — deleting one document does not break the rest of the graph. Only nodes and edges unique to the updated document are removed from both the graph database and the vector store.After cognify re-runs on the updated content, new entities and relationships are extracted. Any relationship that existed in the old version but is absent from the new version will not be re-created, so the graph always reflects the current state of your data.
Use graph visualization or a search query to inspect the knowledge graph before and after an update:
For a visual diff, launch the built-in graph explorer via cognee-cli -ui and compare the graph snapshots around the update.