> ## Documentation Index
> Fetch the complete documentation index at: https://docs.60db.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Search Memories

> Hybrid semantic + keyword search with cross-encoder reranking

Search memories in a collection using hybrid retrieval. Combines vector similarity (semantic) with BM25 keyword scoring, with optional cross-encoder reranking for higher precision. Optionally returns graph relationships.

## Request

### Headers

<ParamField header="Authorization" type="string" required>
  Bearer token with your API key
</ParamField>

<ParamField header="Content-Type" type="string" required>
  application/json
</ParamField>

### Body

<ParamField body="query" type="string" required>
  Search query text. Max 2,000 characters.
</ParamField>

<ParamField body="collection" type="string">
  Collection to search. Defaults to the caller's personal collection.
</ParamField>

<ParamField body="mode" type="string" default="fast">
  Search mode:

  * `fast` — single-query dense retrieval (\~100-200ms). Best for simple lookups.
  * `thinking` — fetches a wider candidate pool and applies cross-encoder reranking for higher precision (\~200-400ms). Best for complex or multi-faceted questions.
</ParamField>

<ParamField body="max_results" type="integer" default="10">
  Maximum number of results. Capped at 50.
</ParamField>

<ParamField body="alpha" type="number" default="0.8">
  Weight of semantic search (0-1). `0` = keyword only, `1` = semantic only.
</ParamField>

<ParamField body="recency_bias" type="number" default="0.0">
  Weight given to newer memories (0-1).
</ParamField>

<ParamField body="graph_context" type="boolean" default="false">
  Include knowledge-graph relationships in the response.
</ParamField>

### Advanced reranker knobs

These parameters override server-side defaults for the cross-encoder reranker. Omit to use the deployment default.

<ParamField body="rerank_top_k" type="integer">
  Max candidates the cross-encoder reranks (1-500). Default: server setting (30).
</ParamField>

<ParamField body="rerank_timeout_ms" type="integer">
  Hard timeout for the rerank call in milliseconds (50-5000). Default: server setting (500).
</ParamField>

<ParamField body="min_rerank_score" type="number">
  Drop results with rerank score below this threshold (0-1). Default: server setting (0.25).
</ParamField>

<ParamField body="fetch_multiplier" type="integer">
  In `thinking` mode, fetch N x `max_results` candidates before reranking (1-10). Default: server setting (3).
</ParamField>

## Response

<ResponseField name="data.chunks" type="array">
  Raw chunk-level search results with scores. Each chunk includes:

  * `score` — dense vector similarity score (0-1)
  * `rerank_score` — cross-encoder rerank score (0-1, present when reranker is active, null otherwise)
</ResponseField>

<ResponseField name="data.sources" type="array">
  Deduplicated source memories (one per unique memory\_id)
</ResponseField>

<ResponseField name="data.graph_context" type="object">
  Graph nodes, edges, and triplets (only if `graph_context: true`)
</ResponseField>

<ResponseField name="data.total_chunks" type="integer">
  Total number of chunks returned
</ResponseField>

<ResponseField name="data.latency_ms" type="number">
  Search latency in milliseconds
</ResponseField>

<ResponseField name="data.trace" type="object">
  Per-query diagnostic trace including stage timings, reranker meta, and active flag snapshot. Useful for debugging search quality.
</ResponseField>

## Example

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.60db.ai/memory/search \
    -H "Authorization: Bearer your-api-key" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "What are my dietary preferences?",
      "mode": "thinking",
      "max_results": 5,
      "alpha": 0.8,
      "recency_bias": 0.1
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.60db.ai/memory/search', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer your-api-key',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      query: "What are my dietary preferences?",
      mode: "thinking",
      max_results: 5,
      alpha: 0.8,
      recency_bias: 0.1,
    }),
  });
  const data = await response.json();
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.60db.ai/memory/search",
      headers={
          "Authorization": "Bearer your-api-key",
          "Content-Type": "application/json",
      },
      json={
          "query": "What are my dietary preferences?",
          "mode": "thinking",
          "max_results": 5,
          "alpha": 0.8,
          "recency_bias": 0.1,
      },
  )
  data = response.json()
  ```
</RequestExample>

<ResponseExample>
  ```json Response theme={null}
  {
    "success": true,
    "data": {
      "query": "What are my dietary preferences?",
      "chunks": [
        {
          "chunk_id": "c_01HV...",
          "source_id": "mem_01HV8K...",
          "text": "User prefers vegetarian food, lactose intolerant",
          "score": 0.912,
          "rerank_score": 0.9485,
          "metadata": { "title": "Dietary preferences" }
        }
      ],
      "sources": [
        {
          "source_id": "mem_01HV8K...",
          "title": "Dietary preferences",
          "text": "User prefers vegetarian food, lactose intolerant",
          "score": 0.912,
          "rerank_score": 0.9485
        }
      ],
      "total_chunks": 1,
      "total_sources": 1,
      "latency_ms": 287.4,
      "mode": "thinking",
      "alpha": 0.8,
      "trace": {
        "timings_ms": { "embed_ms": 112, "vector_search_ms": 52, "total_ms": 287 },
        "rerank": { "mode": "on", "ok": true, "latency_ms": 103, "top_score": 0.9485 }
      }
    }
  }
  ```
</ResponseExample>

## Billing

Flat \*\*$0.0003 per query**, regardless of `max_results` or `mode`. A workload of 10,000 searches per month costs $3.

Every successful request returns:

| Header             | Meaning                          |
| ------------------ | -------------------------------- |
| `x-credit-balance` | Wallet balance after this charge |
| `x-credit-charged` | `0.000300`                       |
| `x-billing-tx`     | Audit row UUID                   |

On `402 INSUFFICIENT_CREDITS`, the response includes `details.shortfall` so you can prompt the user to top up. See [Pricing & Billing](/api-reference/memory/pricing).

## Tuning

**Query types and recommended settings**:

| Query type                     | Recommended settings            |
| ------------------------------ | ------------------------------- |
| Exact phrase match             | `alpha: 0.2, mode: fast`        |
| Conceptual question            | `alpha: 0.9, mode: fast`        |
| Complex multi-faceted question | `alpha: 0.7, mode: thinking`    |
| Latest-events focus            | `alpha: 0.6, recency_bias: 0.3` |
