Overview
The Search API enables powerful semantic search across your memories using natural language. Queries are embedded and matched against your memory embeddings using semantic similarity, returning the most relevant results.
Pro tip: For best results, phrase your search queries as questions or statements that match how you stored the original memories.
Unified Search
GET /search — Search memories (and audio segments)
Cross-modal search across memories and audio segments. The query is embedded and fused using RRF.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
q | string | yes | Natural-language search query (1-1000 chars). |
include | string | no | Comma-separated content types to include: memories, audio. Default: both. |
space_id | string | no | Filter results to a single space UUID. |
tags | string | no | Comma-separated tags to filter by. |
limit | integer | no | Maximum results to return. Default: 20, Max: 100. |
offset | integer | no | Number of results to skip. Default: 0. |
threshold | number | no | Minimum similarity score (0-1). Default: 0. |
explain | boolean | no | Include a why_matched explanation per result. Default: false. |
include_superseded | boolean | no | Include superseded memories (with warnings). Default: true. |
pipeline | string | no | Named pipeline preset whose retrieval defaults seed limit and threshold. |
Response (200)
Returns results and facets. Each result carries a type field (memory or audio_segment).
{
"results": [
{
"type": "memory",
"id": "<uuid>",
"score": 0.94,
"content": "The user prefers dark mode and uses vim keybindings",
"content_type": "text",
"tags": ["preference"],
"metadata": { "type": "preference" }
},
{
"type": "audio_segment",
"id": "<uuid>",
"audio_file_id": "<uuid>",
"text": "I use vim keybindings everywhere",
"start_time": 12.4,
"end_time": 14.8,
"score": 0.81
}
],
"facets": { "memories": 4, "audio_segments": 1 }
}Global Search
GET /search/global — Global keyword search
Keyword search that can span memories, highlights, clusters and spaces. Useful for type-ahead and cross-resource lookup.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
q | string | yes | Search query (1-1000 chars). |
types | string | no | Comma-separated resource types to search: memory, highlight, cluster, space. |
limit | integer | no | Maximum results. Default: 20, Max: 100. |
Response (200)
Returns matches grouped by resource type.
Tag (Topic) Search
GET /search/topic — Find memories by tag
Returns memories that have the given tag. Matches the exact tag value rather than performing LLM topic extraction.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
topic | string | yes | Tag to match against the memory tags array (1-200 chars). |
limit | integer | no | Maximum results. Default: 20, Max: 100. |
Response (200)
Returns matching memories plus a total count.
{
"memories": [
{
"id": "<uuid>",
"content": "The user prefers dark mode and uses vim keybindings",
"content_type": "text",
"tags": ["preference", "dark-mode"],
"metadata": { "type": "preference" },
"priority": 3,
"created_at": "2026-04-10T10:30:00Z",
"topic_relevance": 1.0
}
],
"total": 1
}Note: For semantic/LLM-based topic retrieval, call GET /search with a natural-language query and optional tags filter instead.
Aggregate (Faceted) Search
GET /search/aggregate — Faceted search grouped by field
Semantic search with grouping by a chosen field (tags, clusters, content_type, priority or time bucket).
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
query | string | yes | Search query. |
group_by | string | yes | Field to group by (tags, clusters, content_type, priority, time_bucket, …). |
threshold | number | no | Minimum similarity (0-1). Default: 0.5. |
limit | integer | no | Max groups. Default: 10, Max: 100. |
space_id | string | no | Filter by space UUID. |
bucket_size | string | no | Required when group_by=time_bucket. One of day, week, month. |
Response (200)
Returns { query, group_by, total_count, groups }.
Batch Search
POST /search/batch — Run multiple searches in one request
Executes a batch of search queries in parallel and returns their results together.
Response (200)
Returns an array of per-query results.
Find Similar Memories
GET /search/similar/:memoryId — Similar memories to a given memory
Returns memories most similar (by embedding) to the given memory.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
memoryId | string | yes | Source memory UUID. |
Response (200)
Returns ranked similar memories.
Search Result Object
Each unified-search result has a type discriminator plus type-specific fields:
| Field | Type | Description |
|---|---|---|
type | string | memory or audio_segment. |
id | string | Result UUID (memory ID or audio segment ID). |
score | number | Fused relevance score (0-1). Higher is better. |
content | string | Memory content (when type = memory). |
content_type | string | Memory content type (text, audio, image, …). |
tags | string[] | Memory tags. |
metadata | object | Memory metadata. |
warnings | object[] | Optional warnings, e.g. when a superseded memory is included. |
audio_file_id | string | Parent audio file UUID (when type = audio_segment). |
text | string | Segment text (audio segments). |
highlight | string | Highlighted phrase (audio segments). |
start_time | number | Segment start in seconds. |
end_time | number | Segment end in seconds. |
clip_url | string | Signed clip URL (audio segments). |
Best Practices
Writing Effective Queries
- Use natural-language questions: "What does the user prefer for authentication?"
- Be specific when searching technical content: "React component state management patterns"
- Use
/search/aggregatewhen you want to browse results by tag or cluster. - Use
/search/topicwhen you want memories that carry a specific tag.
Optimizing Performance
- Filter by
space_idto reduce search scope. - Set a
thresholdto skip low-similarity matches. - Use
include=memoriesto skip audio scanning when you only want text. - Use a
pipelinepreset to apply tuned retrieval defaults.
Understanding Scores
- 0.9+ — Excellent match, highly relevant
- 0.8-0.9 — Good match, likely relevant
- 0.7-0.8 — Moderate match, possibly relevant
- <0.7 — Weak match, may not be useful