Skip to main content

cognee.recall()

Description

recall() is the main retrieval entry point in Cognee v1.0.
  • It auto-routes queries by default when you do not specify query_type. Routing is rule-based (no LLM call) and falls back to GRAPH_COMPLETION when no cue matches — see Auto-routing behavior for the full cue-to-search-type mapping and when to override.
  • It can search the permanent graph, session memory, or both.
  • It returns RecallResponse items sourced from graph retrieval, session retrieval, or both depending on the request.
For the full behavior walkthrough, see Recall and Search Basics.

Prerequisites

recall() only reads from memory that already exists — it does not initialize anything on its own. Populate memory first with remember() (or the legacy add() + cognify() sequence). The first ingestion run creates the relational, vector, and graph databases and the default user.
Calling recall() before any data has been ingested raises RecallPreconditionError (a CogneeValidationError, HTTP 422) with the message “Recall prerequisites not met: no database/default user found.” It is triggered by the underlying DatabaseNotCreatedError (“The database has not been created yet. Please call await setup() first.”) or UserNotFoundError. The fix is to run remember() (or add() + cognify()) first.

Parameters

str
required
Natural-language query to run against memory.
SearchType | None
default:"None"
Forces a specific retrieval strategy instead of using auto-routing.
list[str] | None
default:"None"
Restricts graph retrieval to the named datasets. Dataset names are resolved only against datasets owned by the current user. When both datasets and dataset_ids are omitted, retrieval spans every dataset the current user has read access to — not just a single default dataset. Pass this to narrow the search to specific datasets.
list[UUID] | None
default:"None"
Restricts graph retrieval by dataset UUIDs instead of names. Use this for shared datasets that the current user can access but did not create. When provided, this takes precedence over datasets and the name-to-UUID lookup is skipped. Leaving both datasets and dataset_ids unset searches all of the user’s readable datasets.
int
default:"15"
Maximum number of results to return.
bool
default:"True"
When True, Cognee chooses a retrieval strategy automatically if query_type is not set, using the rule-based query router. Set it to False to always use GRAPH_COMPLETION. An explicit query_type always takes precedence over routing.
str | list[str] | None
default:"None"
Controls whether retrieval uses session, graph, or the default automatic combination logic.

Additional keyword options

recall() accepts only the parameters documented above — it has no catch-all **kwargs. Passing an unsupported keyword such as node_type raises TypeError: recall() got an unexpected keyword argument 'node_type'. To restrict retrieval to specific nodes or node sets, use node_name (a list[str]). node_type is a legacy search() parameter and is not exposed on recall().

Structured output with response_model

Pass a Pydantic model class to get a validated, parsed answer instead of free text — each result carries the validated payload as a dict in its structured field. All completion-style search types support it (GRAPH_COMPLETION and its variants except GRAPH_SUMMARY_COMPLETION, RAG_COMPLETION, TRIPLET_COMPLETION, HYBRID_COMPLETION, TEMPORAL, AGENTIC_COMPLETION):
response_model is shorthand for retriever_specific_config={"response_model": ...} — Cognee folds the parameter into the config before dispatching, so the dict form still works. Pass it in one place: supplying the same model class through both is allowed, but different classes raise CogneeValidationError (HTTP 422).
Remote mode. A Python class cannot cross the HTTP boundary, so against a remote server (see serve()) the SDK forwards response_model.model_json_schema() as the response_schema field of POST /api/v1/recall, and the server rebuilds a validation model from it. Only the schema’s structure travels — custom validators and value constraints are not enforced server-side; rehydrate on the client (NLPFacts.model_validate(results[0].structured)) when you need them. See Search & Recall — response_schema for the supported schema subset and rejection rules.

Return value

recall() returns a list of RecallResponse items. Depending on the request, results may come from session memory, permanent graph retrieval, or both. These items are Pydantic objects, not plain dictionaries — read fields with attribute access (result.text), not result.get("text") or result["text"]. Calling .get() on a result raises AttributeError: 'ResponseGraphEntry' object has no attribute 'get'. The concrete type of each item is set by its source field (import from cognee.modules.recall.types.RecallResponse):

Warming-up marker

Before running graph retrieval, recall() checks whether the target datasets have ever been through a Cognee pipeline. This check is a single indexed relational query — it never spins up a graph or vector engine. When no pipeline has ever run for those datasets, the graph lane returns immediately instead of running graph search plus an LLM call that could only come back empty:
If you branch on source, add a "system" case — code that previously saw an empty list for a cold dataset now sees a one-item list carrying this marker. text is populated so consumers that just render text still display something sensible. Details and exceptions:
  • The marker only appears when graph is the sole source. In a multi-source recall (for example a session-scoped call that reads both session memory and the graph), a cold graph contributes [] instead, so the other sources — and the tools on_empty fallback — behave exactly as if graph retrieval had returned nothing.
  • only_context=True bypasses the check and always runs normal retrieval, since those callers expect context rather than a marker.
  • Populated datasets are unaffected. Any dataset that has been through a pipeline reads as warm, including one that has only been add()-ed but not yet cognified.
  • The check fails open. A probe or configuration error falls through to a normal search, so it can never block a real answer.
  • It can be turned off with RECALL_WARMUP_SHORTCIRCUIT=false (or cognee.config.set("recall_warmup_shortcircuit", False)), which restores the previous behavior exactly. See Recall warm-up for that variable and its two companions.

Source provenance in metadata

For chunk and summary results (CHUNKS, CHUNKS_LEXICAL, SUMMARIES), the metadata dict carries stable source identifiers so you can map a result back to the data you ingested and inspect the exact cited chunk. Only the keys present in the underlying payload are included: Completion-style results (e.g. GRAPH_COMPLETION) carry an empty metadata dict; for those, the same ids are surfaced inline in the Evidence: block instead (see include_references). When include_references=True, each evidence bullet is rendered as - chunk N of document NAME (data_id: …, chunk_id: …): "snippet". This is an additive response-schema change — no DB migration is required, since document_id is already stored on chunks.
The text_result, context_result, and objects_result keys come from the legacy search(verbose=True) API, which returns plain dicts. recall() does not produce those keys. For a graph-backed recall item, result.text is the display-ready value. result.raw preserves the normalized payload for that item; for completion-style searches, it is not the same thing as objects_result.
For the full breakdown of session-hit shapes, graph-backed wrappers, and per-search-type payloads, see Recall — What recall returns.

Examples

With backend access control enabled, datasets=["name"] only resolves dataset names owned by the current user. If a dataset was created by Alice and shared with Bob, Bob should query it with dataset_ids=[shared_id], not datasets=["name"].
See also SearchType and search() when you need lower-level retrieval control.