> ## Documentation Index
> Fetch the complete documentation index at: https://cortex-e852fafe-t3code-rewrite-docs-declutter.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Recall

> How HydraDB retrieves the right context for each query - across Knowledge, Memories, and the context graph.

Recall turns stored context into the *right* context for a specific query. This page covers what recall is, the endpoints HydraDB exposes, the parameters that matter, and the patterns you'll reach for in production.

For request/response schemas, see the API reference: [Full Recall](/api-reference/endpoint/full-recall), [Memory Recall](/api-reference/endpoint/recall-preferences), [Boolean Recall](/api-reference/endpoint/boolean-recall).

***

## 1. What is Recall

Recall returns the chunks most likely to help your agent succeed on a query - not just the chunks most textually similar to it. Pure vector search gives you similarity; recall gives you usefulness.

HydraDB stores two kinds of context in separate vector stores:

| Store | Contains | `vectorstore_status` index | Recall endpoint |
| - | - | - | - |
| **Memories** | User preferences, conversation history, per-user inferred content | Index `0` (`[0]`) | `recall_preferences` |
| **Knowledge** | Ingested documents, files, and app sources | Index `1` (`[1]`) | `full_recall` |

A single recall call hits one store. To use both in one prompt, call the matching endpoint for each and merge the results.

When `graph_context` is enabled, recall also traverses the **context graph** - a graph of relationships between stored context that HydraDB derives automatically from your data - so related material that pure similarity would miss can come back with the result.

***

## 2. When to use Recall

Use recall when you need:

* Grounded answers from documents or app sources
* Personalized responses for a specific user
* Context-aware retrieval across multiple sources
* Deterministic metadata filtering combined with semantic search

Reach for something else when:

* You need the full document, not ranked chunks → use `/fetch/content`.

***

## 3. Types of Recall

HydraDB exposes three endpoints under `/recall/*`. Pick one based on what you need back.

| Endpoint | Searches | Returns | Use when |
| - | - | - | - |
| `POST /recall/full_recall` | Knowledge | `RetrievalResult` | You need facts from documents |
| `POST /recall/recall_preferences` | Memories | `RetrievalResult` | You need user-specific context |
| `POST /recall/boolean_recall` | Knowledge or Memories (`search_mode`) | `RetrievalResult` | You need exact term, AND, or phrase matching |

`full_recall` and `recall_preferences` share the same request and response shape (`RecallSearchRequest` → `RetrievalResult`). `boolean_recall` accepts a smaller set of parameters and runs deterministic lexical matching - no graph traversal, no metadata filters.

To deliver a personalized answer, the canonical pattern is two parallel calls - `full_recall` for shared Knowledge, `recall_preferences` for the user's Memories - merged into a single LLM prompt. See [Minimal Working Example](#6-minimal-working-example).

***

## 4. How Recall Works

The semantic recall endpoints (`full_recall`, `recall_preferences`) accept a `mode`:

| Mode | Pipeline | Latency |
| - | - | - |
| `fast` (default) | Single query | Lower |
| `thinking` | Multi-query expansion with reranking | Higher |

`thinking` produces higher-quality results by expanding the query into sub-queries and reranking candidates. It also surfaces forceful-relation extras (`extra_context_ids` and the `additional_context` map on the response) when matching sources have them. `fast` skips both steps.

`boolean_recall` has no `mode` parameter - it always runs deterministic term matching.

**Rule of thumb.** If a human will read the result, use `thinking`. If a machine will filter it further or low latency is the priority, use `fast`.

***

## 5. Key Parameters

These apply to `full_recall` and `recall_preferences` (`RecallSearchRequest`):

| Parameter | Type | Default | Purpose |
| - | - | - | - |
| `tenant_id` | string | - *(required)* | Tenant identifier - the top-level scoping identifier. |
| `sub_tenant_id` | string \| null | none | Scopes recall to a user, workspace, or partition. If omitted, HydraDB uses the tenant's default sub-tenant. |
| `query` | string | - *(required)* | Search terms. |
| `mode` | `"fast"` \| `"thinking"` | `"fast"` | Retrieval pipeline. |
| `max_results` | integer \| null | server default | Maximum chunks to return. Start with 10. |
| `alpha` | number \| `"auto"` | `0.8` | Hybrid ranking weight (`0.0` = keyword, `1.0` = semantic). |
| `recency_bias` | number | `0.0` | Boost for newer content (`0.0`–`1.0`). |
| `graph_context` | boolean | `false` | Set `true` to populate `graph_context` in the response. |
| `metadata_filters` | object \| null | `null` | Equality filters on declared, match-enabled metadata fields. Undeclared filters are ignored. |
| `additional_context` | string \| null | `null` | Extra hint to guide retrieval (e.g. `"User is on the billing page"`). |
| `search_forceful_relations` | boolean | `true` | Whether to fetch forceful-relation extras. Only takes effect in `"thinking"` mode. |

`boolean_recall` (`FullTextSearchRequest`) is intentionally narrower:

| Parameter | Type | Default | Purpose |
| - | - | - | - |
| `tenant_id`, `sub_tenant_id`, `query` | - | - | As above. `query` and `tenant_id` are required. |
| `operator` | `"or"` \| `"and"` \| `"phrase"` | `"or"` | How search terms combine. |
| `max_results` | integer | `10` | Result cap. |
| `search_mode` | `"sources"` \| `"memories"` | `"sources"` | Which store to search. |

It does **not** accept `mode`, `alpha`, `recency_bias`, `graph_context`, `metadata_filters`, or `additional_context`. If you need any of those, use a semantic endpoint.

<Warning>
  <strong>Two defaults that surprise developers</strong>

  <ul>
    <li><code>graph\_context</code> defaults to <code>false</code> - set it to <code>true</code> to receive graph data in the response.</li>
    <li><code>recency\_bias</code> defaults to <code>0</code> - no recency boost is applied unless you set it.</li>
  </ul>
</Warning>

<Warning>
  <strong><code>metadata\_filters</code> requires a pre-declared schema</strong>
  <p>Top-level filter keys should be defined in <code>tenant\_metadata\_schema</code> with matching enabled. Undeclared filters are ignored, so plan filterable keys before your first ingestion.</p>
  <p>See <a href="/api-reference/endpoint/create-tenant">Create Tenant</a>.</p>
</Warning>

### Tuning heuristics

* **`alpha`** - Start at `0.8`. Lower toward `0.3–0.5` when the query contains literal tokens (error codes, SKUs, product names). Raise toward `0.9` for conceptual questions. Use `"auto"` when the query shape varies.
* **`recency_bias`** - Leave at `0` for static reference material. Set `0.2–0.4` for mixed content, `0.6–0.8` for changelogs, news, or status updates.
* **`max_results`** - Start at `10`. Drop to `5` for tight context windows; raise to `20` if you rerank downstream.
* **`additional_context`** - Use it when the query alone is ambiguous. Keep it short and factual.

***

## 6. Minimal Working Example

The canonical personalized-answer flow: recall Knowledge, recall the user's Memories in parallel, merge into one LLM prompt.

### Setup

<CodeGroup>
  ```bash cURL theme={null}
  # Set your key as an environment variable - used in every request below
  export HYDRA_DB_API_KEY="your_api_key"
  # All requests: -H "Authorization: Bearer $HYDRA_DB_API_KEY"
  ```

  ```typescript TypeScript SDK theme={null}
  import { HydraDBClient } from "@hydradb/sdk";

  const client = new HydraDBClient({
    token: process.env.HYDRA_DB_API_KEY,
  });
  ```

  ```python Python SDK theme={null}
  import os
  from hydra_db import HydraDB

  client = HydraDB(token=os.environ["HYDRA_DB_API_KEY"])
  ```
</CodeGroup>

### Recall - Knowledge and Memories in parallel

<CodeGroup>
  ```bash cURL theme={null}
  # Run both in parallel from your shell or application layer

  curl -X POST 'https://api.hydradb.com/recall/full_recall' \
    -H "Authorization: Bearer $HYDRA_DB_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "tenant_id": "acme_corp",
      "query": "How do I reset my password?",
      "mode": "thinking",
      "max_results": 5,
      "graph_context": true
    }'

  curl -X POST 'https://api.hydradb.com/recall/recall_preferences' \
    -H "Authorization: Bearer $HYDRA_DB_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "tenant_id": "acme_corp",
      "sub_tenant_id": "user_john_123",
      "query": "answer style and tone preferences",
      "mode": "thinking",
      "max_results": 3
    }'
  ```

  ```typescript TypeScript SDK theme={null}
  async function gatherContext(
    tenantId: string,
    userId: string,
    query: string,
  ) {
    const [knowledge, memories] = await Promise.all([
      client.recall.fullRecall({
        tenant_id: tenantId,
        query,
        mode: "thinking",
        max_results: 5,
        graph_context: true,
      }),
      client.recall.recallPreferences({
        tenant_id: tenantId,
        sub_tenant_id: userId,
        query: "answer style and tone preferences",
        mode: "thinking",
        max_results: 3,
      }),
    ]);
    return { knowledge, memories };
  }
  ```

  ```python Python SDK theme={null}
  import asyncio
  from hydra_db import AsyncHydraDB

  async_client = AsyncHydraDB(token=os.environ["HYDRA_DB_API_KEY"])

  async def gather_context(tenant_id: str, user_id: str, query: str):
      knowledge, memories = await asyncio.gather(
          async_client.recall.full_recall(
              tenant_id=tenant_id,
              query=query,
              mode="thinking",
              max_results=5,
              graph_context=True,
          ),
          async_client.recall.recall_preferences(
              tenant_id=tenant_id,
              sub_tenant_id=user_id,
              query="answer style and tone preferences",
              mode="thinking",
              max_results=3,
          ),
      )
      return knowledge, memories
  ```
</CodeGroup>

### Merge into the LLM prompt

Both calls return the same shape: `chunks[]`, `sources[]`, and (when applicable) `graph_context` and `additional_context`. Format each into a context string - the helper in [How to Use API Results](/essentials/api-results) does this - and feed both into your prompt:

```typescript theme={null}
const knowledgeCtx = buildContextString(knowledge);
const memoryCtx = buildContextString(memories);

const completion = await openai.chat.completions.create({
  model: "gpt-4o",
  messages: [
    {
      role: "system",
      content: "Answer using only the provided context. Match the user's preferred style.",
    },
    {
      role: "user",
      content: `User preferences:\n${memoryCtx}\n\nRelevant docs:\n${knowledgeCtx}\n\nQuestion: How do I reset my password?`,
    },
  ],
});
```

### Production checklist

* **Parallelize** the two recall calls - they're independent.
* **Set per-call timeouts.** Generous for `thinking` (3–5s), tight for `fast` (≤500ms).
* **Degrade gracefully.** If memory recall fails or times out, continue with Knowledge only.
* **Pass `additional_context`** with known session state (page, feature, role). It can sharpen retrieval without requiring additional calls.

***

## 7. Common Mistakes

| Symptom | Cause | Fix |
| - | - | - |
| Empty `query_paths` / `chunk_relations` | `graph_context` not set, or no relations exist for the result set | Set `graph_context: true`; empty arrays are normal when there's nothing to return. |
| Recent uploads don't appear | Indexing not finished | Poll [`/ingestion/verify_processing`](/api-reference/endpoint/verify-processing) - chunks are invisible until processing completes. |
| `metadata_filters` does not narrow results | Filter key is undeclared or not match-enabled | Declare filterable keys in `tenant_metadata_schema` with `enable_match: true` before ingestion. |
| Memories missing from `full_recall` (or vice versa) | Knowledge and Memories are separate stores | Call both endpoints and merge. |
| Recency doesn't seem to matter | `recency_bias` defaults to `0` | Set it explicitly between `0.1` and `1.0`. |
| `400` / `422` on `boolean_recall` with `alpha`, `mode`, or `graph_context` | Boolean recall doesn't accept those parameters | Drop them, or switch to a semantic endpoint. |

***

## 8. Advanced Patterns

**Hybrid: `boolean_recall` + `full_recall`.** When a query mixes a literal token (error code, SKU, function name) with natural-language intent, run both, dedupe by `chunk_uuid`, and treat boolean hits as a "must include" floor.

**Recall-then-rerank.** Request more chunks than you need (`max_results: 20`), then apply your own reranker - recency windows, compliance filters, business rules - before picking the final top-k for the prompt.

***

## Related

* [Memories](/essentials/memories) - user-scoped dynamic context
* [Knowledge](/essentials/knowledge) - shared document context
* [Metadata](/essentials/metadata) - designing filterable fields
* [Context Graphs](/essentials/context-graphs) - how graph traversal enriches recall
* [How to Use API Results](/essentials/api-results) - turning `RetrievalResult` into an LLM prompt


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.