Skip to main content

The memory model

A memory is a text fact associated with an agent and a user. You write it by sending a content string along with agent_id and user_id identifiers. Everything else is optional.
{
  "content": "User is in the Europe/Berlin timezone.",
  "agent_id": "support-agent",
  "user_id": "user-42"
}
Write short, factual sentences. One clear idea per memory is significantly more effective for retrieval than long paragraphs.
✓  User prefers weekly email digests.
✓  User's primary language is German.
✗  User said they prefer emails and they live in Berlin and their name is Max and they use dark mode.

Scoping

Every memory belongs to three nested scopes. This hierarchy is enforced by the API and cannot be overridden by the caller.
ScopeSourceNotes
OrganizationFrom your API keyAutomatically applied — never sent in the request body
agent_idYour requestIdentifies which agent owns the memory. Max 256 chars, charset [A-Za-z0-9._:-]
user_idYour requestYour application’s user identifier. Same constraints as agent_id
A search for agent_id=support-agent and user_id=user-42 will only return memories written with that exact combination. Memories from other agents or users are never returned. An API key can never read another organization’s data. Isolation is enforced at the database level, not the application layer.

The write pipeline

When you call POST /v1/memories, the API responds with 202 Accepted immediately — the memory is persisted to a queue and the response includes the assigned UUID.
POST /v1/memories


   202 Accepted  ←─── You get this immediately
   {"id": "...", "status": "queued"}

         ▼ (background, ~1–5 seconds)

   ┌─────────────────────────────────────────┐
   │  Cognition Worker                        │
   │                                          │
   │  1. LLM fact extraction (if extract=true)│
   │     Transforms raw text into clean,      │
   │     discrete, retrievable facts.         │
   │                                          │
   │  2. Deduplication                        │
   │     Merges or supersedes memories that   │
   │     conflict with existing ones.         │
   │                                          │
   │  3. Importance scoring                   │
   │     Assigns a 0–1 score used in ranking. │
   │                                          │
   │  4. Compression (Level 1)                │
   │     Derives higher-level summaries from  │
   │     related raw memories when warranted. │
   │                                          │
   │  5. Store                                │
   │     Writes to vector DB + relational DB. │
   │     Warms the search cache.              │
   └─────────────────────────────────────────┘

The extract flag

The extract field (default true) controls whether the cognition worker runs LLM fact extraction before storing the content.
extractBehaviourBest for
true (default)LLM extracts discrete facts from the raw text before storageConversation turns, unstructured observations, anything written by users or models
falseContent is stored verbatim — no LLM call is madePre-formatted, clean facts you already control; lower latency, zero extraction cost

Memory levels

The cognition worker assigns a level to each memory based on its abstraction:
LevelNameDescription
0RawAn individual fact or observation as submitted (possibly after extraction)
1AbstractionA concise summary derived from the raw content, stored alongside the original
Level-1 memories are more compact and rank well for broad queries. Level 0 is the most granular and preserves the original phrasing. You can filter search results to a specific level using the level parameter.

Memory fields

Every memory record has the following fields:
FieldTypeDescription
idstring (UUID)Unique identifier assigned on creation
org_idstringYour organization identifier
agent_idstringThe agent that owns this memory
user_idstringThe user this memory belongs to
contentstringThe memory text (only in GET /v1/memories/{id} and search results)
levelinteger0 = raw, 1 = abstraction
statusstringactive (searchable) or deprecated (soft-deleted, excluded from search)
importancefloat (0–1)Importance score assigned by the cognition worker
confidencefloat (0–1)Confidence in the memory’s accuracy. Defaults to 1.0 if not provided
sourcestringWhere the memory came from (e.g. "agent")
created_atISO 8601 datetimeWhen the memory was created
updated_atISO 8601 datetimeWhen the memory was last updated
content is intentionally excluded from GET /v1/memories (list) responses to keep paginated payloads small. Use GET /v1/memories/{id} to retrieve the full record including content.

The search pipeline

POST /v1/memories/search is synchronous — it returns ranked results in a single request.
POST /v1/memories/search


   ┌─────────────────────────────────────────┐
   │  1. Hot cache check                     │
   │     Identical queries for the same      │
   │     org/agent/user return a cached      │
   │     result instantly (cache_hit: true). │
   │                                         │
   │  2. Embed the query                     │
   │     The query string is converted to a  │
   │     vector embedding.                   │
   │                                         │
   │  3. Vector search                       │
   │     Retrieves semantically similar      │
   │     memories for the org/agent/user.    │
   │                                         │
   │  4. Multi-signal fusion ranking         │
   │     Re-ranks candidates by combining:   │
   │      • Semantic similarity score        │
   │      • Memory importance (0–1)          │
   │      • Recency                          │
   │      • task_context match (if provided) │
   │                                         │
   │  5. Return top-k results                │
   └─────────────────────────────────────────┘


   200 OK {"results": [...], "latency_ms": 42, "cache_hit": false}
The score field in each result is the final fusion score, not raw cosine similarity. Use it to compare results within a single response.

Using task_context

task_context is an optional string that provides the ranker with a hint about what the agent is currently trying to do. It improves relevance when the user’s query alone does not convey enough intent.
results = client.search(
    query="what does the user prefer",
    agent_id="support-agent",
    user_id="user-42",
    task_context="composing a notification preferences summary email",
)

Deleting memories

Soft delete (default) marks a memory as deprecated. It is immediately excluded from all search results but remains in the database. This is the standard delete operation. Hard delete (?hard=true) permanently removes the memory from all stores — the relational database, the vector database, and the search cache. This is irreversible and intended for GDPR erasure requests. See DELETE /v1/memories/{id} for the full reference.