Documentation
Memory
Long-term memory your agent keeps between sessions — preferences, identity, decisions, evolving facts about a user or a body of documents. Three providers behind one wallet, every operation 1¢: Mem0 (the default per-user store), Zep (temporal knowledge graph), and Letta (a stateful agent that manages its own memory).
When to use which
| Need | Calls | Pick when |
|---|---|---|
| Remember what a user likes / said | mem0/add · mem0/search | The default. Quickest, lowest overhead; simple add/search scoped by user_id. |
| “What’s true now” as facts change | zep/user-add → thread-create → add → get-context | Temporal knowledge graph; hands back a ready-to-inject context block. |
| An agent that manages its own memory | letta/agent-create · letta/message | You drive it with messages, not raw add/search — it self-edits what it keeps. |
Default to Mem0 unless the task clearly calls for temporal reasoning (Zep) or an autonomous, self-managing agent (Letta). Memory is for *remembering between calls* — it’s distinct from compute (running code) and web search (reading the live web).
mem0/add
- Price
- 1¢
- Latency
- fast — extraction is queued server-side
Stores conversation turns as long-term memory. Mem0 auto-extracts the durable facts (preferences, identity, decisions) from the messages you send. messages and user_id are required; metadata (object) and infer (bool, default true — set false to store verbatim) are optional.
curl -X POST https://vaaya.ai/api/run/mem0/add \
-H "Authorization: Bearer $VAAYA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"messages": [{ "role": "user", "content": "I prefer TypeScript over Python" }],
"user_id": "alice"
}'Gotchas
addreturns a queued event, not the extracted memory — there’s a brief delay before asearchwill surface it.- Always scope by the same
user_idyou’ll search with, or memories leak across users.
mem0/search
- Price
- 1¢
- Latency
- fast
Semantic search over one user’s stored memories — call it *before* answering, then prepend the hits to your prompt. query and user_id are required; top_k (int) is optional. Returns ranked memories with scores.
curl -X POST https://vaaya.ai/api/run/mem0/search \
-H "Authorization: Bearer $VAAYA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "programming preferences", "user_id": "alice", "top_k": 5}'Zep — temporal knowledge-graph memory
- Price
- 1¢ per operation
- Setup
- user → thread → messages, in that order
Use Zep when *what’s true changes over time* and you need “what’s true now” — statuses, evolving preferences. Heavier than Mem0 but stronger at temporal reasoning. Order matters: create a user, then a thread, then add messages — there is no implicit creation. Facts from any thread join the user-level graph.
# 1) create the user (once per end-user; pass a stable user_id)
curl -X POST https://vaaya.ai/api/run/zep/user-add \
-H "Authorization: Bearer $VAAYA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"user_id": "alice", "first_name": "Alice"}'
# 2) open a thread (one per conversation)
curl -X POST https://vaaya.ai/api/run/zep/thread-create \
-H "Authorization: Bearer $VAAYA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"thread_id": "conv-123", "user_id": "alice"}'
# 3) add messages — Zep extracts facts into the graph in the background
curl -X POST https://vaaya.ai/api/run/zep/add \
-H "Authorization: Bearer $VAAYA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"thread_id": "conv-123",
"messages": [{ "role": "user", "content": "I moved to Berlin", "name": "Alice" }],
"return_context": true
}'
# later: fetch the context block to inject into your prompt
curl -X POST https://vaaya.ai/api/run/zep/get-context \
-H "Authorization: Bearer $VAAYA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"thread_id": "conv-123"}'return_context: trueonzep/addreturns the context block inline — saves the follow-upget-contextcall.zep/get-contextreturns{ "context": "..." }— a summarized block of facts, entities, and messages, ready to prepend to a prompt.zep/search({ "query": "...", "user_id": "..." }) retrieves one *specific* fact from the user graph — use it when you don’t want the whole context block.
Letta — a stateful, self-managing agent
- Price
- 1¢ per call
- Latency
- fast (
agent-create) · medium (messageruns an LLM step)
Letta is for long-running relationships where the *agent itself* decides what to remember and rewrites its own tiered memory — not a passive key-value store. Create an agent once, then drive it with messages.
# 1) create the agent — all params optional; capture the returned id
curl -X POST https://vaaya.ai/api/run/letta/agent-create \
-H "Authorization: Bearer $VAAYA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "support-agent",
"model": "openai/gpt-4o-mini",
"memory_blocks": [{ "label": "human", "value": "Name: Alice" }]
}'
# 2) converse — the agent persists and rewrites its own memory
curl -X POST https://vaaya.ai/api/run/letta/message \
-H "Authorization: Bearer $VAAYA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agent_id": "agent-abc", "input": "What did I say I preferred last week?"}'Gotchas
- Capture the
idreturned byagent-create— everyletta/messagecall needs it. - One agent per persona/user — don’t recreate an agent per turn.
- The reply is the message with
message_type: "assistant_message"in the response.