--- title: "Search" sidebarTitle: "Search API" description: "Semantic search across your memories and documents" icon: "/icons/hugeicons/search-01.svg" --- Search through your memories and documents with a single API call. Each search runs inside one `namespace` (what v3/v4 called a container tag). **`searchMode: "hybrid"`** is the default and gives the best results. It searches both memories and document chunks, returning the most relevant content. **TypeScript SDK:** one call, `supermemory.search(namespace, { query, searchMode })`. `searchMode` (`"memories"`, `"chunks"`, or `"hybrid"`) picks what comes back. There is no v5 Python SDK yet; the Python tab shows the legacy client. ## Quick start ```typescript import { Supermemory } from "supermemory"; const supermemory = new Supermemory({ apiKey: process.env.SUPERMEMORY_API_KEY }); const results = await supermemory.search("user_123", { query: "machine learning", searchMode: "hybrid", limit: 5, }); results.results.forEach(result => { console.log(result.memory || result.chunk, result.similarity); }); ``` ```python from supermemory import Supermemory client = Supermemory() results = client.search( "user_123", query="machine learning", search_mode="hybrid", limit=5, ) for result in results.results: print(result.memory or result.chunk, result.similarity) ``` ```bash curl -X POST "https://api.supermemory.ai/ns/user_123/search?searchMode=hybrid&limit=5" \ -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "query": "machine learning" }' ``` **Response:** ```json { "results": [ { "id": "mem_xyz", "memory": "User is interested in machine learning for product recommendations", "similarity": 0.91, "metadata": { "topic": "interests" }, "isLatest": true, "system": { "createdAt": "2024-01-15T10:30:00.000Z", "updatedAt": "2024-01-15T10:30:00.000Z" } }, { "id": "chunk_abc", "chunk": "Machine learning enables personalized experiences at scale...", "similarity": 0.87, "metadata": { "source": "onboarding_doc" }, "isLatest": true, "system": { "createdAt": "2024-01-14T09:15:00.000Z", "updatedAt": "2024-01-14T09:15:00.000Z" } } ], "searchTime": 92 } ``` In hybrid mode, results contain either a `memory` field (extracted facts) or a `chunk` field (document content), depending on the source. Branch on field presence. --- ## Parameters `namespace` is the URL path. Every other option goes in the JSON body (the second argument in the SDKs). | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `namespace` | string | required | Namespace to search (URL path) | | `query` | string | required | Search query | | `searchMode` | string | `"hybrid"` | `"hybrid"` (recommended), `"memories"`, or `"chunks"` | | `limit` | number | 10 | Max results (max 100) | | `threshold` | 0-1 | 0.3 | Similarity cutoff (higher = fewer, better results) | | `rerank` | string | `"none"` | `"none"`, `"order"` (re-score for relevance, +100ms), or `"aggregate"` | | `rewriteQuery` | boolean | false | Generate multiple rewrites, search all of them, and merge results. No extra cost, but adds latency | | `filter` | object | — | Metadata filter expression. See [Filtering](#filtering) | | `include` | object | — | `{ documents, related, forgotten }` — opt in to extra context per result | Defaults changed from v4: `searchMode` was `memories` and is now `hybrid`; `threshold` was `0.6` and is now `0.3`. Set both explicitly if you are comparing against v4 results. ### Search modes - **`hybrid`** (default, recommended) — Searches both memories and document chunks, and returns both in the response - **`memories`** — Only searches extracted memories - **`chunks`** — Only searches raw document/chunk content, skipping extracted memories ```typescript // Hybrid: memories + document chunks (default) await supermemory.search("user_123", { query: "quarterly goals", }); // Memories only: just extracted facts await supermemory.search("user_123", { query: "user preferences", searchMode: "memories", }); // Chunks only: RAG over documents await supermemory.search("user_123", { query: "refund policy", searchMode: "chunks", }); ``` --- ## Filtering The `namespace` scopes results to a user or project. Use `filter` for metadata-based filtering inside that namespace: ```typescript const results = await supermemory.search("user_123", { query: "meeting notes", filter: { operator: "and", operands: [ { field: "type", operator: "eq", value: "meeting" }, { field: "year", operator: "eq", value: 2024 }, ], }, }); ``` - **Equality:** `{ field: "status", operator: "eq", value: "active" }` (also `neq`; strings, numbers, booleans) - **String contains:** `{ field: "title", operator: "contains", value: "react" }` (also `notContains`; optional `caseSensitive`) - **Numeric:** `{ field: "priority", operator: "gte", value: 5 }` (`gt`, `gte`, `lt`, `lte`) - **Array contains:** `{ field: "tags", operator: "arrayContains", value: "important" }` (also `arrayNotContains`) - **Logic:** `{ operator: "and" | "or", operands: [...] }`, nested up to 5 levels Keys are literal: `customer.plan` is one field name, not a nested path. See [Organizing & Filtering](/concepts/filtering) for full syntax. --- ## Query optimization ### Reranking Re-scores results for better relevance. Adds ~100ms latency. ```typescript const results = await supermemory.search("user_123", { query: "complex technical question", rerank: "order", }); ``` ### Threshold Control result quality vs quantity: ```typescript // Broad search — more results await supermemory.search("user_123", { query: "...", threshold: 0.3 }); // Precise search — fewer, better results await supermemory.search("user_123", { query: "...", threshold: 0.8 }); ``` ### Attachments - `attach.documents` adds the most relevant source document to each result. - `attach.related` adds parent, child, and sibling memories (see [graph memory](/concepts/graph-memory)). - `attach.forgotten` allows forgotten memories in related context. By default, search excludes memories that have been forgotten or have passed their `forgetAfter` expiration. ```typescript await supermemory.search("user_123", { query: "old project notes", include: { related: true, forgotten: true }, searchMode: "memories", }); ``` Attached context arrives under `result.included` (`included.document`, `included.related.{parents,children,siblings}`). --- ## Chatbot example Optimal configuration for conversational AI: ```typescript async function getContext(userId: string, message: string) { const results = await supermemory.search(userId, { query: message, threshold: 0.6, searchMode: "hybrid", limit: 5, }); return results.results .map(r => r.memory || r.chunk) .join('\n\n'); } ``` ```typescript interface SearchResult { id: string; memory?: string; // Present for memory results chunk?: string; // Present for document chunk results similarity: number; // 0-1 metadata: object | null; isLatest: boolean; system: { createdAt: string; updatedAt: string }; included?: { // Only when you pass attach document?: object; related?: { parents: object[]; children: object[]; siblings: object[] }; }; } interface SearchResponse { results: SearchResult[]; searchTime: number; // ms } ``` --- ## Next steps - [Ingesting Content](/ingestion/add-memories) — Add content to search - [User Profiles](/recall/user-profiles) — Get user context - [Organizing & Filtering](/concepts/filtering) — Namespaces and metadata