Memories API
Authentication
All endpoints require Authorization: Bearer <token> header. See Authentication.
Search Memories
Performs semantic search across all memories using hybrid BM25 + vector similarity in PostgreSQL search index.
POST /api/memories/searchRequest Body
{
"query": "coffee meeting with John",
"filters": {
"connectorType": "gmail",
"sourceType": "email",
"contactId": "contact-uuid",
"factualityLabel": "FACT"
},
"limit": 10
}| Field | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Natural language search query |
filters | object | No | Optional filters |
filters.connectorType | string | No | Filter by connector type |
filters.sourceType | string | No | Filter by source type |
filters.contactId | string | No | Filter to memories involving this contact |
filters.factualityLabel | string | No | Filter by factuality label |
diversityFactor | number | No | Connector diversity threshold (0-1, default: 0.15). Higher values sacrifice more score for diversity across connector types. 0 disables diversity ordering. |
limit | number | No | Max results (default: 20) |
Response
[
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"text": "Hi team, let's meet for coffee tomorrow at 10am...",
"sourceType": "email",
"connectorType": "gmail",
"eventTime": "2026-01-15T10:30:00Z",
"accountIdentifier": "[email protected]",
"score": 0.87,
"weights": {
"semantic": 0.92,
"recency": 0.78,
"importance": 0.7,
"trust": 0.95,
"final": 0.87
},
"factuality": "{\"label\":\"FACT\",\"confidence\":0.9,\"rationale\":\"Direct email from known sender\"}",
"entities": "[{\"type\":\"person\",\"value\":\"John\",\"confidence\":0.95}]",
"metadata": "{\"from\":\"[email protected]\",\"subject\":\"Coffee meeting\"}"
}
]Results are sorted by the final score (descending). The scoring formula is:
final = 0.70 * semantic + 0.15 * recency + 0.10 * importance + 0.05 * trustContent cleaning: Stored text is cleaned before indexing -- HTML tags, email signatures, reply chains, and messaging formatting are stripped. Search queries match against cleaned text.
Factuality corroboration: Memories with supports links from different connector types are automatically promoted from UNVERIFIED to FACT. See Memory Model: Factuality Corroboration.
Diversity diversity ordering: When diversityFactor > 0, results are diversified to prevent a single connector type from dominating. The algorithm picks from underrepresented connectors when their score is within diversityFactor of the best available.
List Memories
List memories with pagination and optional filters, ordered by event time (newest first).
GET /api/memoriesQuery Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | number | 50 | Page size |
offset | number | 0 | Pagination offset |
connectorType | string | - | Filter by connector type |
sourceType | string | - | Filter by source type |
Response
{
"items": [
{
"id": "memory-uuid",
"accountId": "account-uuid",
"connectorType": "gmail",
"sourceType": "email",
"sourceId": "msg-12345",
"text": "Email content...",
"eventTime": "2026-01-15T10:30:00Z",
"ingestTime": "2026-01-16T02:00:00Z",
"factuality": "{...}",
"weights": "{...}",
"entities": "[...]",
"metadata": "{...}",
"embeddingStatus": "done",
"createdAt": "2026-01-16T02:00:00Z",
"accountIdentifier": "[email protected]"
}
],
"total": 15420
}Get Memory Stats
Returns aggregate statistics about the memory store.
GET /api/memories/statsResponse
{
"total": 15420,
"bySource": {
"email": 8200,
"message": 5100,
"photo": 1800,
"location": 320
},
"byConnector": {
"gmail": 8500,
"slack": 3200,
"whatsapp": 1900,
"photos": 1800
},
"byFactuality": {
"FACT": 4200,
"UNVERIFIED": 10800,
"FICTION": 420
}
}Get Memory Graph
Returns the relationship graph for visualization. Includes up to 500 recent memories with their links and associated contacts.
GET /api/memories/graphResponse
{
"nodes": [
{
"id": "memory-uuid",
"label": "Email about Q3 budget...",
"type": "email",
"connectorType": "gmail",
"factuality": "FACT",
"importance": 0.8,
"cluster": 0,
"nodeType": "memory",
"entities": ["John", "Q3 budget"]
},
{
"id": "contact-contact-uuid",
"label": "John Smith",
"type": "contact",
"connectorType": "gmail",
"factuality": "FACT",
"importance": 0.8,
"cluster": 0,
"nodeType": "contact",
"connectors": ["gmail", "slack"]
}
],
"edges": [
{
"source": "memory-uuid-1",
"target": "memory-uuid-2",
"type": "related",
"strength": 0.85
},
{
"source": "contact-contact-uuid",
"target": "memory-uuid-1",
"type": "involves",
"strength": 0.7
}
]
}Get Memory by ID
GET /api/memories/:idResponse
Returns the full memory object, or null if not found.
Create Memory
Create a manual memory. The memory will be automatically embedded and enqueued for enrichment.
POST /api/memoriesRequest Body
{
"text": "The project deadline was moved to March 15th.",
"sourceType": "manual",
"connectorType": "manual"
}| Field | Type | Required | Default | Description |
|---|---|---|---|---|
text | string | Yes | - | Memory text content |
sourceType | string | No | manual | Source type label |
connectorType | string | No | manual | Connector type label |
Response
{
"id": "new-uuid",
"text": "The project deadline was moved to March 15th.",
"sourceType": "manual",
"connectorType": "manual",
"eventTime": "2026-02-20T10:00:00Z",
"createdAt": "2026-02-20T10:00:00Z"
}Delete Memory
Removes a memory from both PostgreSQL and PostgreSQL search index.
DELETE /api/memories/:idResponse
{
"ok": true
}Retry Failed Embeddings
Re-enqueues all memories with embeddingStatus of failed or stuck pending.
POST /api/memories/retry-failedResponse
{
"enqueued": 15,
"total": 15
}Backfill Contacts
Enqueues contact resolution for memories that do not yet have contact links.
POST /api/memories/backfill-contactsResponse
{
"enqueued": 200,
"total": 200
}