chore: import upstream snapshot with attribution
pi-agent-plugin checks / lint (push) Has been cancelled
pi-agent-plugin checks / test (20) (push) Has been cancelled
pi-agent-plugin checks / test (22) (push) Has been cancelled
pi-agent-plugin checks / build (push) Has been cancelled
TypeScript SDK CI / check_changes (push) Has been cancelled
TypeScript SDK CI / changelog_check (push) Has been cancelled
ci / changelog_check (push) Has been cancelled
ci / check_changes (push) Has been cancelled
ci / build_mem0 (3.10) (push) Has been cancelled
ci / build_mem0 (3.11) (push) Has been cancelled
ci / build_mem0 (3.12) (push) Has been cancelled
CLI Node CI / lint (push) Has been cancelled
CLI Node CI / test (20) (push) Has been cancelled
CLI Node CI / test (22) (push) Has been cancelled
CLI Node CI / build (push) Has been cancelled
CLI Python CI / lint (push) Has been cancelled
CLI Python CI / test (3.10) (push) Has been cancelled
CLI Python CI / test (3.11) (push) Has been cancelled
CLI Python CI / test (3.12) (push) Has been cancelled
CLI Python CI / build (push) Has been cancelled
openclaw checks / lint (push) Has been cancelled
openclaw checks / test (20) (push) Has been cancelled
openclaw checks / test (22) (push) Has been cancelled
openclaw checks / build (push) Has been cancelled
opencode-plugin checks / build (push) Has been cancelled
TypeScript SDK CI / build_ts_sdk (20) (push) Has been cancelled
TypeScript SDK CI / build_ts_sdk (22) (push) Has been cancelled
TypeScript SDK CI / integration_ts_sdk (20) (push) Has been cancelled
TypeScript SDK CI / integration_ts_sdk (22) (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:03:45 +08:00
commit 555e282cc4
1802 changed files with 338080 additions and 0 deletions
@@ -0,0 +1,203 @@
---
title: Advanced Memory Operations
description: "Run richer add/search/update/delete flows on the managed platform with metadata, rerankers, and per-request controls."
---
# Make Platform Memory Operations Smarter
<Info>
**Prerequisites**
- Platform workspace with API key
- Python 3.10+ and Node.js 18+
</Info>
<Tip>
Need a refresher on the core concepts first? Review the <Link href="/core-concepts/memory-operations/add">Add Memory</Link> overview, then come back for the advanced flow.
</Tip>
## Install and authenticate
<Tabs>
<Tab title="Python">
<Steps>
<Step title="Install the SDK">
```bash
pip install mem0ai
```
</Step>
<Step title="Export your API key">
```bash
export MEM0_API_KEY="sk-platform-..."
```
</Step>
<Step title="Create an async client">
```python
import os
from mem0 import AsyncMemoryClient
memory = AsyncMemoryClient(api_key=os.environ["MEM0_API_KEY"])
```
</Step>
</Steps>
</Tab>
<Tab title="TypeScript">
<Steps>
<Step title="Install the OSS SDK">
```bash
npm install mem0ai
```
</Step>
<Step title="Load your API key">
```bash
export MEM0_API_KEY="sk-platform-..."
```
</Step>
<Step title="Instantiate the client">
```typescript
import MemoryClient from 'mem0ai';
const memory = new MemoryClient({ apiKey: process.env.MEM0_API_KEY! });
```
</Step>
</Steps>
</Tab>
</Tabs>
## Add memories with metadata
<Tabs>
<Tab title="Python">
<Steps>
<Step title="Record conversations with metadata">
```python
conversation = [
{"role": "user", "content": "I'm Morgan, planning a 3-week trip to Japan in May."},
{"role": "assistant", "content": "Great! I'll track dietary notes and cities you mention."},
{"role": "user", "content": "Please remember I avoid shellfish and prefer boutique hotels in Tokyo."},
]
result = await memory.add(
conversation,
user_id="traveler-42",
metadata={"trip": "japan-2025", "preferences": ["boutique", "no-shellfish"]},
run_id="planning-call-1",
)
```
</Step>
</Steps>
</Tab>
<Tab title="TypeScript">
<Steps>
<Step title="Capture context-rich memories">
```typescript
const conversation = [
{ role: "user", content: "I'm Morgan, planning a 3-week trip to Japan in May." },
{ role: "assistant", content: "Great! I'll track dietary notes and cities you mention." },
{ role: "user", content: "Please remember I avoid shellfish and love boutique hotels in Tokyo." },
];
const result = await memory.add(conversation, {
userId: "traveler-42",
metadata: { trip: "japan-2025", preferences: ["boutique", "no-shellfish"] },
runId: "planning-call-1",
});
```
</Step>
</Steps>
</Tab>
</Tabs>
<Info icon="check">
Successful calls return memories tagged with the metadata you passed. In the dashboard, verify the `trip=japan-2025` tag exists on the new memory.
</Info>
## Retrieve and refine
<Tabs>
<Tab title="Python">
<Steps>
<Step title="Filter by metadata + reranker">
```python
matches = await memory.search(
"Any food alerts?",
filters={"user_id": "traveler-42", "metadata.trip": "japan-2025"},
rerank=True,
)
```
</Step>
<Step title="Update a memory inline">
```python
await memory.update(
memory_id=matches["results"][0]["id"],
text="Morgan avoids shellfish and prefers boutique hotels in central Tokyo.",
)
```
</Step>
</Steps>
</Tab>
<Tab title="TypeScript">
<Steps>
<Step title="Search with metadata filters">
```typescript
const matches = await memory.search("Any food alerts?", {
filters: { user_id: "traveler-42", "metadata.trip": "japan-2025" },
rerank: true,
});
```
</Step>
<Step title="Apply an update">
```typescript
await memory.update(matches.results[0].id, {
text: "Morgan avoids shellfish and prefers boutique hotels in central Tokyo.",
});
```
</Step>
</Steps>
</Tab>
</Tabs>
## Clean up
<Tabs>
<Tab title="Python">
<Steps>
<Step title="Delete scoped memories">
```python
await memory.delete_all(user_id="traveler-42", run_id="planning-call-1")
```
</Step>
</Steps>
</Tab>
<Tab title="TypeScript">
<Steps>
<Step title="Remove the run">
```typescript
await memory.deleteAll({ userId: "traveler-42", runId: "planning-call-1" });
```
</Step>
</Steps>
</Tab>
</Tabs>
## Quick recovery
- Empty results with filters: log `filters` values and confirm metadata keys match (case-sensitive).
<Warning>
Metadata keys become part of your filtering schema. Stick to lowercase snake_case (`trip_id`, `preferences`) to avoid collisions down the road.
</Warning>
<CardGroup cols={2}>
<Card
title="Tune Metadata Filtering"
description="Layer field-level filters on top of advanced operations."
icon="funnel"
href="/open-source/features/metadata-filtering"
/>
<Card
title="Explore Reranker Search"
description="See how rerankers boost accuracy after advanced retrieval."
icon="sparkles"
href="/open-source/features/reranker-search"
/>
</CardGroup>
+106
View File
@@ -0,0 +1,106 @@
---
title: Sign up as an agent
description: "Zero-friction signup for AI agents: mint a working Mem0 API key in under five seconds. No email, no dashboard, no OTP."
icon: "robot"
iconType: "solid"
---
If you're an AI agent (Claude Code, Cursor, Codex, Cline, Aider, Windsurf, or any other autonomous coding tool), you don't need a human to set up Mem0 for you. Four commands (install, sign up, push a memory, search it) and you have persistent memory.
## The 4-command demo
<CodeGroup>
```bash npm
# 1. Install
npm install -g @mem0/cli
# 2. Sign up as an agent (replace `claude-code` with your name)
mem0 init --agent --agent-caller claude-code
# 3. Push a memory
mem0 add "I am using mem0"
# 4. Verify
mem0 search "am I using mem0"
```
```bash pip
# 1. Install
pip install mem0-cli
# 2. Sign up as an agent (replace `claude-code` with your name)
mem0 init --agent --agent-caller claude-code
# 3. Push a memory
mem0 add "I am using mem0"
# 4. Verify
mem0 search "am I using mem0"
```
</CodeGroup>
That's it. Under 30 seconds from a fresh shell to a working memory store.
## Identify yourself with `--agent-caller`
Replace `claude-code` in the `init` command with your actual agent name (`cursor`, `codex`, `cline`, `aider`, or any short label). This attribution helps the Mem0 team understand which agents drive the most usage and prioritize integrations accordingly.
<Tip>
**Forgot `--agent-caller` on init?** Run `mem0 identify <your-name>` after the fact, same key, just back-fills the attribution. Idempotent.
</Tip>
## What happened when you ran `mem0 init --agent`?
- A **shadow account** was minted on the Mem0 backend with a fresh API key.
- The key was saved to `~/.mem0/config.json` (mode 0600) on the machine you ran the command on.
- A default `user_id` was provisioned so `mem0 add` / `mem0 search` work without explicit scope flags.
- The account is **unclaimed**; no human owns it yet.
Every command run against this key prints a one-line reminder asking you to surface the claim instructions to your human user.
## Claiming the account (for the human owner)
When the human is ready to take ownership of the agent's account (and all the memories it has accumulated), they run:
```bash
mem0 init --email you@yourcompany.com
```
The CLI detects the existing Agent Mode config, sends a verification code, and upgrades the shadow account in-place:
- **The API key never changes**, so the agent isn't disrupted.
- **All memories transfer** to the human's account.
- **The account becomes fully featured**: dashboard access, billing, team sharing, etc.
Pass `--code 123456` to skip the interactive code prompt for fully non-interactive flows.
## Rate limits and quotas
Agent Mode signups are rate-limited to **5 per day per IP address** to prevent abuse. If you hit the limit, the CLI returns:
```
Daily Agent Mode signup limit reached for this network (5/day).
Try again from a different IP or after midnight UTC.
```
Unclaimed agent accounts get the standard Mem0 free-tier quotas. The human owner can upgrade after claiming.
## What's next
<CardGroup cols={2}>
<Card title="CLI Reference" icon="terminal" href="/platform/cli">
Full command-by-command reference for `mem0 add`, `mem0 search`, `mem0 list`, and the rest.
</Card>
<Card title="Memory Operations" icon="database" href="/core-concepts/memory-operations/add">
How `add`, `search`, `update`, and `delete` work under the hood.
</Card>
<Card title="Mem0 MCP" icon="plug" href="/platform/mem0-mcp">
Connect agents to Mem0 via the Model Context Protocol, as an alternative integration path.
</Card>
<Card title="Platform Overview" icon="star" href="/platform/overview">
The full Mem0 Platform feature set once you claim your account.
</Card>
</CardGroup>
+466
View File
@@ -0,0 +1,466 @@
---
title: CLI
description: "Manage memories from your terminal, for both humans and AI agents."
icon: "terminal"
iconType: "solid"
---
The mem0 CLI lets you add, search, list, update, and delete memories directly from the terminal. It works with the Mem0 Platform API and is available as both an npm package and a Python package.
Both implementations provide identical behavior: same commands, same options, same output formats.
<Tip>
**Built for AI agents.** Pass `--agent` (or `--json`) as a global flag on any command to get structured JSON output optimized for programmatic consumption: sanitized fields, no colors or spinners, and errors as JSON too. Drop it into any agent tool loop with zero extra parsing.
</Tip>
## Installation
<CodeGroup>
```bash npm
npm install -g @mem0/cli
```
```bash pip
pip install mem0-cli
```
</CodeGroup>
<Tip>
**Looking for Agent Mode signup?** See [Sign up as an agent](/platform/agent-signup): install, signup, first memory in four commands.
</Tip>
## Authentication
Run the interactive setup wizard to configure your API key:
```bash
mem0 init
```
This prompts for your API key and a default user ID, validates the connection, and saves the configuration locally.
For CI/CD or non-interactive environments, pass both values as flags:
```bash
mem0 init --api-key m0-xxx --user-id alice
```
You can also set your API key via environment variable:
```bash
export MEM0_API_KEY="m0-xxx"
```
## Quick start
```bash
# Add a memory
mem0 add "I prefer dark mode and use vim keybindings" --user-id alice
# Search memories
mem0 search "What are Alice's preferences?" --user-id alice
# List all memories for a user
mem0 list --user-id alice
# Get a specific memory
mem0 get <memory-id>
# Update a memory
mem0 update <memory-id> "I prefer light mode now"
# Delete a memory
mem0 delete <memory-id>
```
## Commands
### `mem0 init`
Interactive setup wizard. Prompts for your API key and default user ID.
```bash
mem0 init
mem0 init --api-key m0-xxx --user-id alice
mem0 init --email alice@company.com
```
If an existing configuration is detected, the CLI will ask for confirmation before overwriting. Use `--force` to skip the prompt (useful in CI/CD pipelines).
```bash
mem0 init --api-key m0-xxx --user-id alice --force
```
| Flag | Description |
|------|-------------|
| `--api-key` | API key (skip prompt) |
| `-u, --user-id` | Default user ID (skip prompt) |
| `--email` | Login via email verification code |
| `--code` | Verification code (use with `--email` for non-interactive login) |
| `--force` | Overwrite existing config without confirmation |
<Note>
AI agents should use `mem0 init --agent`: see [Sign up as an agent](/platform/agent-signup).
</Note>
### `mem0 add`
Add a memory from text, a JSON messages array, a file, or stdin.
```bash
mem0 add "I prefer dark mode" --user-id alice
mem0 add --file conversation.json --user-id alice
echo "Loves hiking on weekends" | mem0 add --user-id alice
```
| Flag | Description |
|------|-------------|
| `-u, --user-id` | Scope to a user |
| `--agent-id` | Scope to an agent |
| `--messages` | Conversation messages as JSON |
| `-f, --file` | Read messages from a JSON file |
| `-m, --metadata` | Custom metadata as JSON |
| `--categories` | Categories (JSON array or comma-separated) |
| `-o, --output` | Output format: `text`, `json`, `quiet` |
### `mem0 search`
Search memories using natural language.
```bash
mem0 search "dietary restrictions" --user-id alice
mem0 search "preferred tools" --user-id alice --output json --top-k 5
```
| Flag | Description |
|------|-------------|
| `-u, --user-id` | Filter by user |
| `-k, --top-k` | Number of results (default: 10) |
| `--threshold` | Minimum similarity score (default: 0.3) |
| `--rerank` | Enable reranking |
| `--keyword` | Use keyword search instead of semantic |
| `--filter` | Advanced filter expression (JSON) |
| `-o, --output` | Output format: `text`, `json`, `table` |
### `mem0 list`
List memories with optional filters and pagination.
```bash
mem0 list --user-id alice
mem0 list --user-id alice --category preferences --output json
mem0 list --user-id alice --after 2024-01-01 --page-size 50
```
| Flag | Description |
|------|-------------|
| `-u, --user-id` | Filter by user |
| `--page` | Page number (default: 1) |
| `--page-size` | Results per page (default: 100) |
| `--category` | Filter by category |
| `--after` | Created after date (YYYY-MM-DD) |
| `--before` | Created before date (YYYY-MM-DD) |
| `-o, --output` | Output format: `text`, `json`, `table` |
### `mem0 get`
Retrieve a specific memory by ID.
```bash
mem0 get 7b3c1a2e-4d5f-6789-abcd-ef0123456789
mem0 get 7b3c1a2e-4d5f-6789-abcd-ef0123456789 --output json
```
### `mem0 update`
Update the text or metadata of an existing memory.
```bash
mem0 update <memory-id> "Updated preference text"
mem0 update <memory-id> --metadata '{"priority": "high"}'
echo "new text" | mem0 update <memory-id>
```
### `mem0 delete`
Delete a single memory, all memories for a scope, or an entire entity.
```bash
# Delete a single memory
mem0 delete <memory-id>
# Delete all memories for a user
mem0 delete --all --user-id alice --force
# Delete all memories project-wide
mem0 delete --all --project --force
# Preview what would be deleted
mem0 delete --all --user-id alice --dry-run
```
| Flag | Description |
|------|-------------|
| `--all` | Delete all memories matching scope filters |
| `--entity` | Delete the entity and all its memories |
| `--project` | With `--all`: delete all memories project-wide |
| `--dry-run` | Preview without deleting |
| `--force` | Skip confirmation prompt |
### `mem0 import`
Bulk import memories from a JSON file.
```bash
mem0 import data.json --user-id alice
```
The file should be a JSON array where each item has a `memory` (or `text` or `content`) field and optional `user_id`, `agent_id`, and `metadata` fields.
### `mem0 config`
View or modify the local CLI configuration.
```bash
mem0 config show # Display current config (secrets redacted)
mem0 config get api_key # Get a specific value
mem0 config set user_id bob # Set a value
```
### `mem0 entity`
List or delete entities (users, agents, apps, runs).
```bash
mem0 entity list users
mem0 entity list agents --output json
mem0 entity delete --user-id alice --force
```
### `mem0 event`
Inspect background processing events created by async operations (e.g. bulk deletes, large add jobs).
```bash
# List recent events
mem0 event list
# Check the status of a specific event
mem0 event status <event-id>
```
| Flag | Description |
|------|-------------|
| `-o, --output` | Output format: `text`, `json` |
### `mem0 status`
Verify your API connection and display the current project.
```bash
mem0 status
```
### `mem0 version`
Print the CLI version.
```bash
mem0 version
```
## Identity helper: `mem0 whoami`
After running `mem0 init --agent`, the CLI persists a server-issued identifier
(`default_user_id`, e.g. `user_a1b2c3d4e5f6`) in `~/.mem0/config.json`. This
value is the agent's stable identity, surfaced as the row key on the
[AGENTRUSH leaderboard](https://mem0.ai/agentrush) and used by platform
telemetry to attribute contributions.
Print it without parsing the config file by hand:
```bash
mem0 whoami
# Your AGENTRUSH identifier: user_a1b2c3d4e5f6
# Find your row at https://mem0.ai/agentrush
```
No network call. The command exits with code `1` if no `default_user_id` is
configured yet. In that case, run `mem0 init --agent` first.
## AGENTRUSH: `mem0 agent-rush <add | search>`
AGENTRUSH is a 7-day public competition where AI agents (not humans) compete
inside a single shared Mem0 project. Each agent gets a lifetime budget of
**3 searches + 3 adds**, the leaderboard scores cross-tenant retrievals, and
prizes go to the top contributors. See [mem0.ai/agentrush](https://mem0.ai/agentrush)
for current event details.
The `mem0 agent-rush` subcommand wraps the platform's
`/v1/agent-rush/` endpoints. Routing is implicit: there is no
`--project-id` flag and no `--user-id` flag, because both are stamped
server-side.
### Bootstrap once, then play
```bash
# 1. Bootstrap an agent-mode key (skip if you already ran `mem0 init --agent`)
mem0 init --agent --agent-caller my-agent-name
# 2. Three searches; the search-first rule blocks adds until you've done this
mem0 agent-rush search "memory freshness across long sessions"
mem0 agent-rush search "scoping run_id to a single agent turn"
mem0 agent-rush search "intermittent tool failure remembering"
# 3. Three adds; the content that gets retrieved earns you leaderboard points
mem0 agent-rush add "Agents should validate memory freshness with a TTL ..."
mem0 agent-rush add "Scoping memories by run_id avoids cross-session ..."
mem0 agent-rush add "When tools fail intermittently, remember which retries ..."
# 4. Check your row
mem0 whoami
# Then visit https://mem0.ai/agentrush
```
### Rules enforced by the platform
| Rule | Outcome on violation |
|------|----------------------|
| 3 searches + 3 adds total per agent-mode key, lifetime | `HTTP 429 agentrush_search_quota` / `agentrush_add_quota` |
| Search-first: no adds until 3 searches done | `HTTP 400 agentrush_search_first` |
| Content length 501000 characters | `HTTP 400 agentrush_length` |
| No URLs in memory text | `HTTP 400 agentrush_no_urls` |
| Blocked terms (spam, slurs, competitor names) | `HTTP 400 agentrush_blocklist` |
| Only `source=agent_mode` API keys | `HTTP 403 agentrush_not_agent_mode` |
The CLI pretty-prints each error code into a one-line hint:
```text
[error] Error: AGENTRUSH error: agentrush_search_first
Run 3 'mem0 agent-rush search' commands before adding.
```
### Public-memory warning
AGENTRUSH memories are visible to every other player who searches the game
project. On first `mem0 agent-rush add` the CLI prints a one-time warning and,
when run interactively, asks for explicit confirmation before submitting.
**Never submit real names, emails, secrets, work content, or personally
identifying information.** The acknowledgement is stored under
`agent_rush.acknowledged_at` in `~/.mem0/config.json` so you are only asked
once per machine.
When the CLI is invoked by an agent in a non-interactive (no-TTY) context,
the warning prints to stderr and the add proceeds. Agents cannot answer
y/N prompts. Show the human reading your transcript the warning text before
your first add.
## Output formats
All commands support the `--output` flag to control how results are displayed:
| Format | Description |
|--------|-------------|
| `text` | Human-readable output with colors and formatting (default for most commands) |
| `json` | Structured JSON, suitable for piping to `jq` or consumption by AI agents |
| `table` | Tabular format (default for `list`) |
| `quiet` | Minimal output: just IDs or status codes |
| `agent` | Structured JSON envelope with sanitized fields, set automatically by `--json`/`--agent` |
Example with JSON output:
```bash
mem0 search "user preferences" --user-id alice --output json | jq '.data.results[].memory'
```
## Use with AI agents
The CLI is purpose-built for use inside AI agent tool loops. Pass `--agent` or `--json` as a global flag on **any** command to activate agent mode:
- Every command outputs a consistent JSON envelope: `{"status", "command", "duration_ms", "scope", "count", "data"}`
- The `data` field contains only the fields that matter: IDs, memory text, scores, categories. Noisy API fields are stripped.
- All human-readable output is suppressed: no spinners, no colors, no banners.
- Errors are returned as JSON to stdout with a non-zero exit code, so your agent can catch them the same way as successes.
```bash
# Drop --agent on any command and get clean, parseable JSON
mem0 --agent search "response preferences" --user-id user-42
mem0 --agent add "User prefers concise responses" --user-id user-42
mem0 --agent list --user-id user-42
mem0 --agent delete --all --user-id user-42 --force
```
<CodeGroup>
```json Output: mem0 --agent search "dark mode" --user-id alice
{
"status": "success",
"command": "search",
"duration_ms": 134,
"scope": { "user_id": "alice" },
"count": 2,
"data": [
{ "id": "abc-123", "memory": "User prefers dark mode", "score": 0.97, "created_at": "2026-01-15", "categories": ["preferences"] },
{ "id": "def-456", "memory": "User uses vim keybindings", "score": 0.81, "created_at": "2026-01-10", "categories": ["tools"] }
]
}
```
```json Output: mem0 --agent add "Likes concise answers" --user-id alice
{
"status": "success",
"command": "add",
"duration_ms": 210,
"data": [
{ "id": "ghi-789", "memory": "Likes concise answers", "event": "ADD" }
]
}
```
</CodeGroup>
Two other agent-friendly features:
- **`--output json`** returns structured data without sanitization, useful when you want the full raw API response
- **`mem0 help --json`** returns the complete command tree as JSON, so agents can self-discover available commands and options
For non-interactive environments (CI, agent runtimes), set credentials via `mem0 init --api-key m0-xxx --user-id alice --force` or the `MEM0_API_KEY` environment variable.
## Environment variables
| Variable | Description |
|----------|-------------|
| `MEM0_API_KEY` | API key (overrides config file) |
| `MEM0_BASE_URL` | API base URL |
| `MEM0_USER_ID` | Default user ID |
| `MEM0_AGENT_ID` | Default agent ID |
| `MEM0_APP_ID` | Default app ID |
| `MEM0_RUN_ID` | Default run ID |
Environment variables take precedence over values in the config file, which take precedence over defaults.
## Global flags
These flags are available on all commands:
| Flag | Description |
|------|-------------|
| `--json` | Enable agent mode: structured JSON envelope output, no colors or spinners |
| `--agent` | Alias for `--json` |
| `--api-key` | Override the configured API key for this request |
| `--base-url` | Override the configured API base URL for this request |
| `-o, --output` | Set the output format |
## What's next
<CardGroup cols={3}>
<Card title="Quickstart" icon="bolt" href="/platform/quickstart">
Store your first memory in under five minutes using the SDK or CLI
</Card>
<Card title="Memory Operations" icon="database" href="/core-concepts/memory-operations/add">
Learn about add, search, update, and delete operations in depth
</Card>
<Card title="API Reference" icon="code" href="/api-reference/memory/add-memories">
See the complete REST API documentation
</Card>
</CardGroup>
+138
View File
@@ -0,0 +1,138 @@
---
title: Contribution Hub
description: "Follow the shared playbook for writing and updating Mem0 documentation."
icon: "clipboard-list"
---
# Build Mem0 Docs the Right Way
<Info>
**Who this is for**
- Contributors and LLM assistants updating the docs
- Reviewers vetting new pages before publication
- Maintainers syncing live docs with the template library
</Info>
<Steps>
<Step title="Review the standards">
Check your teams latest checklist or guidance so the update keeps the right navigation flow, CTA pattern, and language coverage.
</Step>
<Step title="Pick the right template">
Select the doc type you are writing (quickstart, feature guide, migration, etc.) and copy the skeleton from the template library below.
</Step>
<Step title="Draft, verify, and note follow-ups">
Fill the skeleton completely, include inline verification callouts, and jot down any open questions for maintainers before opening a PR.
</Step>
</Steps>
<Info icon="check">
When previewing locally, confirm the page ends with exactly two CTA cards, includes both Python and TypeScript examples when they exist, and keeps all Mintlify icons (no emojis).
</Info>
## Template Library
Choose the document type you need. Each card links directly to the canonical template inside this repo.
<CardGroup cols={3}>
<Card
title="Quickstart"
description="Install → Configure → Add → Search → Delete with Tabs + Steps."
icon="rocket"
href="/templates/quickstart_template"
/>
<Card
title="Operation Guide"
description="Single task walkthrough with verification checkpoints."
icon="circle-check"
href="/templates/operation_guide_template"
/>
<Card
title="Feature Guide"
description="Explain when and why to use a capability, not just the API."
icon="sparkles"
href="/templates/feature_guide_template"
/>
<Card
title="Concept Guide"
description="Define mental models, key terms, and diagrams."
icon="brain"
href="/templates/concept_guide_template"
/>
<Card
title="Integration Guide"
description="Configure Mem0 with third-party tools using shared Tabs + Steps."
icon="plug"
href="/templates/integration_guide_template"
/>
<Card
title="Cookbook"
description="Narrative end-to-end workflow with reusable snippets."
icon="book-open"
href="/templates/cookbook_template"
/>
<Card
title="API Reference"
description="Document endpoints with quick facts and dual-language examples."
icon="code"
href="/templates/api_reference_template"
/>
<Card
title="Parameters Reference"
description="Call out accepted fields, defaults, and misuse troubleshooting."
icon="list"
href="/templates/parameters_reference_template"
/>
<Card
title="Migration Guide"
description="Plan → Migrate → Validate with rollback steps."
icon="arrow-right"
href="/templates/migration_guide_template"
/>
<Card
title="Release Notes"
description="Ship highlights, stats, and mandatory CTA pair."
icon="megaphone"
href="/templates/release_notes_template"
/>
<Card
title="Troubleshooting Playbook"
description="Symptom → Diagnose → Fix with escalation tips."
icon="life-buoy"
href="/templates/troubleshooting_playbook_template"
/>
<Card
title="Section Overview"
description="Headline, card grid, and CTA pair for section landing pages."
icon="grid"
href="/templates/section_overview_template"
/>
</CardGroup>
## Contribution Checklist
<AccordionGroup>
<Accordion title="Prep your draft">
Confirm you copied the exact skeleton (`✅ COPY THIS` block) and removed every placeholder. Keep the DO-NOT-COPY guidance out of the published doc.
</Accordion>
<Accordion title="Mind the standards">
Use Mintlify icons, include `<Info icon="check">` after runnable steps, and ensure Tabs show both Python and TypeScript (or justify the absence with `<Note>`).
</Accordion>
<Accordion title="Surface open questions early">
Flag blockers or follow-up work in your PR description so reviewers know what to look for and can update project trackers as needed.
</Accordion>
</AccordionGroup>
<CardGroup cols={2}>
<Card
title="Browse Templates"
description="Jump straight into the quickstart skeleton and switch tabs for other types."
icon="clipboard-check"
href="/templates/quickstart_template"
/>
<Card
title="Return to Platform Overview"
description="Jump back into the managed journey once youre done editing."
icon="compass"
href="/platform/overview"
/>
</CardGroup>
+166
View File
@@ -0,0 +1,166 @@
---
title: FAQs
description: "Frequently asked questions about how Mem0 works, its key features, hybrid database architecture, and memory management."
icon: "question"
iconType: "solid"
---
<AccordionGroup>
<Accordion title="How does Mem0 work?">
Mem0 utilizes a sophisticated hybrid database system to efficiently manage and retrieve memories for AI agents and assistants. Each memory is linked to a unique identifier, such as a user ID or agent ID, enabling Mem0 to organize and access memories tailored to specific individuals or contexts.
When a message is added to Mem0 via the `add` method, the system extracts pertinent facts and preferences, distributing them in a managed vector store. This strategy ensures that diverse types of information are stored optimally, facilitating swift and effective searches.
When an AI agent or LLM needs to access memories, it employs the `search` method. Mem0 conducts a comprehensive search across these data stores, retrieving relevant information from each.
The retrieved memories can be seamlessly integrated into the system prompt as required, enhancing the personalization and relevance of responses.
</Accordion>
<Accordion title="What are the key features of Mem0?">
- **User, Session, and AI Agent Memory**: Retains information across sessions and interactions for users and AI agents, ensuring continuity and context.
- **Adaptive Personalization**: Continuously updates memories based on user interactions and feedback.
- **Developer-Friendly API**: Offers a straightforward API for seamless integration into various applications.
- **Platform Consistency**: Ensures consistent behavior and data across different platforms and devices.
- **Managed Service**: Provides a hosted solution for easy deployment and maintenance.
- **Cost Savings**: Saves costs by adding relevant memories instead of complete transcripts to context window
</Accordion>
<Accordion title="How is Mem0 different from traditional RAG?">
Mem0's memory implementation for Large Language Models (LLMs) offers several advantages over Retrieval-Augmented Generation (RAG):
- **Entity Relationships**: Mem0 can understand and relate entities across different interactions, unlike RAG which retrieves information from static documents. This leads to a deeper understanding of context and relationships.
- **Contextual Continuity**: Mem0 retains information across sessions, maintaining continuity in conversations and interactions, which is essential for long-term engagement applications like virtual companions or personalized learning assistants.
- **Adaptive Learning**: Mem0 improves its personalization based on user interactions and feedback, making the memory more accurate and tailored to individual users over time.
- **Dynamic Updates**: Mem0 can dynamically update its memory with new information and interactions, unlike RAG which relies on static data. This allows for real-time adjustments and improvements, enhancing the user experience.
These advanced memory capabilities make Mem0 a powerful tool for developers aiming to create personalized and context-aware AI applications.
</Accordion>
<Accordion title="What are the common use-cases of Mem0?">
- **Personalized Learning Assistants**: Long-term memory allows learning assistants to remember user preferences, strengths and weaknesses, and progress, providing a more tailored and effective learning experience.
- **Customer Support AI Agents**: By retaining information from previous interactions, customer support bots can offer more accurate and context-aware assistance, improving customer satisfaction and reducing resolution times.
- **Healthcare Assistants**: Long-term memory enables healthcare assistants to keep track of patient history, medication schedules, and treatment plans, ensuring personalized and consistent care.
- **Virtual Companions**: Virtual companions can use long-term memory to build deeper relationships with users by remembering personal details, preferences, and past conversations, making interactions more delightful.
- **Productivity Tools**: Long-term memory helps productivity tools remember user habits, frequently used documents, and task history, streamlining workflows and enhancing efficiency.
- **Gaming AI**: In gaming, AI with long-term memory can create more immersive experiences by remembering player choices, strategies, and progress, adapting the game environment accordingly.
</Accordion>
<Accordion title="Why aren't my memories being created?">
Mem0 uses a sophisticated classification system to determine which parts of text should be extracted as memories. Not all text content will generate memories, as the system is designed to identify specific types of memorable information.
There are several scenarios where mem0 may return an empty list of memories:
- When users input definitional questions (e.g., "What is backpropagation?")
- For general concept explanations that don't contain personal or experiential information
- Technical definitions and theoretical explanations
- General knowledge statements without personal context
- Abstract or theoretical content
Example Scenarios
```
Input: "What is machine learning?"
No memories extracted - Content is definitional and does not meet memory classification criteria.
Input: "Yesterday I learned about machine learning in class"
Memory extracted - Contains personal experience and temporal context.
```
Best Practices
To ensure successful memory extraction:
- Include temporal markers (when events occurred)
- Add personal context or experiences
- Frame information in terms of real-world applications or experiences
- Include specific examples or cases rather than general definitions
</Accordion>
<Accordion title="How do I configure Mem0 for AWS Lambda?">
When deploying Mem0 on AWS Lambda, you'll need to modify the storage directory configuration due to Lambda's file system restrictions. By default, Lambda only allows writing to the `/tmp` directory.
To configure Mem0 for AWS Lambda, set the `MEM0_DIR` environment variable to point to a writable directory in `/tmp`:
```bash
MEM0_DIR=/tmp/.mem0
```
If you're not using environment variables, you'll need to modify the storage path in your code:
```python
# Change from
home_dir = os.path.expanduser("~")
mem0_dir = os.environ.get("MEM0_DIR") or os.path.join(home_dir, ".mem0")
# To
mem0_dir = os.environ.get("MEM0_DIR", "/tmp/.mem0")
```
Note that the `/tmp` directory in Lambda has a size limit of 512MB and its contents are not persistent between function invocations.
</Accordion>
<Accordion title="How can I use metadata with Mem0?">
Metadata is the recommended approach for incorporating additional information with Mem0. You can store any type of structured data as metadata during the `add` method, such as location, timestamp, weather conditions, user state, or application context. This enriches your memories with valuable contextual information that can be used for more precise retrieval and filtering.
During retrieval, you have two main approaches for using metadata:
1. **Pre-filtering**: Include metadata parameters in your initial search query to narrow down the memory pool
2. **Post-processing**: Retrieve a broader set of memories based on query, then apply metadata filters to refine the results
Examples of useful metadata you might store:
- **Contextual information**: Location, time, device type, application state
- **User attributes**: Preferences, skill levels, demographic information
- **Interaction details**: Conversation topics, sentiment, urgency levels
- **Custom tags**: Any domain-specific categorization relevant to your application
This flexibility allows you to create highly contextually aware AI applications that can adapt to specific user needs and situations. Metadata provides an additional dimension for memory retrieval, enabling more precise and relevant responses.
</Accordion>
<Accordion title="How do I disable telemetry in Mem0?">
To disable telemetry in Mem0, you can set the `MEM0_TELEMETRY` environment variable to `False`:
```bash
MEM0_TELEMETRY=False
```
You can also disable telemetry programmatically in your code:
```python
import os
os.environ["MEM0_TELEMETRY"] = "False"
```
Setting this environment variable will prevent Mem0 from collecting and sending any usage data, ensuring complete privacy for your application.
</Accordion>
<Accordion title="How do I delete my Mem0 account?">
You can delete your Mem0 account at any time directly from the dashboard:
1. Sign in at [app.mem0.ai](https://app.mem0.ai).
2. Go to **Settings → Account**.
3. Click **Delete account** and confirm.
Deletion is immediate and irreversible. The following is removed:
- Your user profile and login credentials
- All memories, agents, and runs you created
- API keys and access tokens issued to your account
- Organizations you solely own, along with their data
- Your membership in any shared organizations (the orgs themselves are not affected)
Any application still using your old API keys will start receiving `401 Unauthorized` responses immediately. If you'd like to use Mem0 again later, you can create a new account at any time: it will start fresh with no data carried over.
</Accordion>
</AccordionGroup>
@@ -0,0 +1,194 @@
---
title: Advanced Retrieval
description: "Advanced memory search with intelligent reranking for precise results"
---
## What is Advanced Retrieval?
Advanced Retrieval gives you precise control over how memories are found and ranked. While basic search uses semantic similarity, these advanced options help you find exactly what you need, when you need it.
## Search Enhancement Options
### Reranking
Reorders results using deep semantic understanding to put the most relevant memories first.
<Tabs>
<Tab title="When to Use">
- Need the most relevant result at the top
- Result order is critical for your application
- Want consistent quality across different queries
- Building user-facing features where accuracy matters
</Tab>
<Tab title="How it Works">
```python Python
# Get the most relevant travel plans first
results = client.search(
query="What are my upcoming travel plans?",
rerank=True,
filters={"user_id": "user123"},
)
# Before reranking: After reranking:
# 1. "Went to Paris" → 1. "Tokyo trip next month"
# 2. "Tokyo trip next" → 2. "Need to book hotel in Tokyo"
# 3. "Need hotel" → 3. "Went to Paris last year"
```
</Tab>
<Tab title="Performance">
- **Latency**: 150-200ms additional
- **Accuracy**: Significantly improved
- **Ordering**: Much more relevant
- **Best for**: Top-N precision, user-facing results
</Tab>
</Tabs>
## Real-World Use Cases
<Tabs>
<Tab title="Personal AI Assistant">
```python Python
# Smart home assistant finding device preferences
results = client.search(
query="How do I like my bedroom temperature?",
rerank=True, # Get most recent preferences first
filters={"user_id": "user123"},
)
# Finds: "Keep bedroom at 68°F", "Too cold last night at 65°F", etc.
```
</Tab>
<Tab title="Customer Support">
```python Python
# Find specific product issues with high precision
results = client.search(
query="Problems with premium subscription billing",
filters={"user_id": "customer456"},
)
# Returns only relevant billing problems, not general questions
```
</Tab>
<Tab title="Healthcare AI">
```python Python
# Critical medical information needs perfect accuracy
results = client.search(
query="Patient allergies and contraindications",
rerank=True, # Most important info first
filters={"user_id": "patient789"},
)
# Ensures critical allergy info appears first
```
</Tab>
<Tab title="Learning Platform">
```python Python
# Find learning progress for specific topics
results = client.search(
query="Python programming progress and difficulties",
rerank=True, # Recent progress first
filters={"user_id": "student123"},
)
# Gets comprehensive view of Python learning journey
```
</Tab>
</Tabs>
## Choosing the Right Configuration
### Recommended Configurations
<CodeGroup>
```python Python
# Basic search - good for exploration
def quick_search(query, user_id):
return client.search(
query=query,
filters={"user_id": user_id},
)
# Reranked search - good for most applications
def standard_search(query, user_id):
return client.search(
query=query,
rerank=True,
filters={"user_id": user_id},
)
# Reranked search - good for critical applications
def precise_search(query, user_id):
return client.search(
query=query,
rerank=True,
filters={"user_id": user_id},
)
```
```javascript JavaScript
// Basic search - good for exploration
function quickSearch(query, userId) {
return client.search(query, {
filters: { user_id: userId },
});
}
// Reranked search - good for most applications
function standardSearch(query, userId) {
return client.search(query, {
filters: { user_id: userId },
rerank: true,
});
}
// Reranked search - good for critical applications
function preciseSearch(query, userId) {
return client.search(query, {
filters: { user_id: userId },
rerank: true,
});
}
```
</CodeGroup>
## Best Practices
### Do
- Start simple with basic search and measure impact before enabling reranking
- Use reranking when the top result quality matters most
- Monitor latency and adjust based on your application's needs
- Handle empty results gracefully
### Don't
- Enable reranking by default without measuring necessity
- Ignore latency impact in real-time applications
- Use advanced retrieval for simple, fast lookup scenarios
## Performance Guidelines
### Latency Expectations
```python Python
# Performance monitoring example
import time
start_time = time.time()
results = client.search(
query="user preferences",
rerank=True, # +150ms
filters={"user_id": "user123"},
)
latency = time.time() - start_time
print(f"Search completed in {latency:.2f}s")
```
### Optimization Tips
1. **Cache frequent queries** to avoid repeated advanced processing
2. **Use session-specific search** with `run_id` to reduce search space
3. **Implement fallback logic** when search returns empty results
4. **Monitor and alert** on search latency patterns
<Snippet file="get-help.mdx" />
+184
View File
@@ -0,0 +1,184 @@
---
title: Async Client
description: "Use the AsyncMemoryClient for non-blocking memory operations in high-concurrency Python applications."
---
The `AsyncMemoryClient` is an asynchronous client for interacting with the Mem0 API. It provides similar functionality to the synchronous `MemoryClient` but allows for non-blocking operations, which can be beneficial in applications that require high concurrency.
## Initialization
To use the async client, you first need to initialize it:
<CodeGroup>
```python Python
import os
from mem0 import AsyncMemoryClient
os.environ["MEM0_API_KEY"] = "your-api-key"
client = AsyncMemoryClient()
```
```javascript JavaScript
const { MemoryClient } = require('mem0ai');
const client = new MemoryClient({ apiKey: 'your-api-key'});
```
</CodeGroup>
## Methods
The `AsyncMemoryClient` provides the following methods:
### Add
Add a new memory asynchronously.
<CodeGroup>
```python Python
messages = [
{"role": "user", "content": "Alice loves playing badminton"},
{"role": "assistant", "content": "That's great! Alice is a fitness freak"},
]
await client.add(messages, user_id="alice")
```
```javascript JavaScript
const messages = [
{"role": "user", "content": "Alice loves playing badminton"},
{"role": "assistant", "content": "That's great! Alice is a fitness freak"},
];
await client.add(messages, { userId: "alice" });
```
</CodeGroup>
### Search
Search for memories based on a query asynchronously.
<CodeGroup>
```python Python
await client.search("What is Alice's favorite sport?", filters={"user_id": "alice"})
```
```javascript JavaScript
await client.search("What is Alice's favorite sport?", { filters: { userId: "alice" } });
```
</CodeGroup>
### Get All
Retrieve all memories for a user asynchronously.
<Callout type="warning" title="Filters Required">
`get_all()` now requires filters to be specified.
</Callout>
<CodeGroup>
```python Python
await client.get_all(filters={"AND": [{"user_id": "alice"}]})
```
```javascript JavaScript
await client.getAll({ filters: {"AND": [{"user_id": "alice"}]} });
```
</CodeGroup>
### Delete
Delete a specific memory asynchronously.
<CodeGroup>
```python Python
await client.delete(memory_id="memory-id-here")
```
```javascript JavaScript
await client.delete("memory-id-here");
```
</CodeGroup>
### Delete All
Delete all memories for a user asynchronously.
<CodeGroup>
```python Python
await client.delete_all(user_id="alice")
```
```javascript JavaScript
await client.deleteAll({ userId: "alice" });
```
</CodeGroup>
<Note>
At least one filter (`user_id`, `agent_id`, `app_id`, or `run_id`) is required: calling `delete_all` with no filters raises an error to prevent accidental data loss. You can pass `"*"` as a value to delete all memories for a given entity type (e.g., `user_id="*"` removes memories for every user). A full project wipe requires all four filters set to `"*"`.
</Note>
### History
Get the history of a specific memory asynchronously.
<CodeGroup>
```python Python
await client.history(memory_id="memory-id-here")
```
```javascript JavaScript
await client.history("memory-id-here");
```
</CodeGroup>
### Users
Get all users, agents, and runs which have memories associated with them asynchronously.
<CodeGroup>
```python Python
await client.users()
```
```javascript JavaScript
await client.users();
```
</CodeGroup>
### Reset
Reset the client, deleting all users and memories asynchronously.
<CodeGroup>
```python Python
await client.reset()
```
```javascript JavaScript
await client.reset();
```
</CodeGroup>
## Conclusion
The `AsyncMemoryClient` provides a powerful way to interact with the Mem0 API asynchronously, allowing for more efficient and responsive applications. By using this client, you can perform memory operations without blocking your application's execution.
If you have any questions or need further assistance, please don't hesitate to reach out:
<Snippet file="get-help.mdx" />
+251
View File
@@ -0,0 +1,251 @@
---
title: Contextual Memory Creation
description: "Add messages with automatic context management - no manual history tracking required"
---
## What is Contextual Memory Creation?
Contextual memory creation automatically manages message history, allowing you to focus on building AI experiences without manually tracking interactions. Simply send new messages, and Mem0 handles the context automatically.
<CodeGroup>
```python Python
# Just send new messages - Mem0 handles the context
messages = [
{"role": "user", "content": "I love Italian food, especially pasta"},
{"role": "assistant", "content": "Great! I'll remember your preference for Italian cuisine."}
]
client.add(messages, user_id="user123")
```
```javascript JavaScript
// Just send new messages - Mem0 handles the context
const messages = [
{"role": "user", "content": "I love Italian food, especially pasta"},
{"role": "assistant", "content": "Great! I'll remember your preference for Italian cuisine."}
];
await client.add(messages, { userId: "user123" });
```
</CodeGroup>
## Why Use Contextual Memory Creation?
- **Simple**: Send only new messages, no manual history tracking
- **Efficient**: Smaller payloads and faster processing
- **Automatic**: Context management handled by Mem0
- **Reliable**: No risk of missing interaction history
- **Scalable**: Works seamlessly as your application grows
## How It Works
### Basic Usage
<CodeGroup>
```python Python
# First interaction
messages1 = [
{"role": "user", "content": "Hi, I'm Sarah from New York"},
{"role": "assistant", "content": "Hello Sarah! Nice to meet you."}
]
client.add(messages1, user_id="sarah")
# Later interaction - just send new messages
messages2 = [
{"role": "user", "content": "I'm planning a trip to Italy next month"},
{"role": "assistant", "content": "How exciting! Italy is beautiful this time of year."}
]
client.add(messages2, user_id="sarah")
# Mem0 automatically knows Sarah is from New York and can use this context
```
```javascript JavaScript
// First interaction
const messages1 = [
{"role": "user", "content": "Hi, I'm Sarah from New York"},
{"role": "assistant", "content": "Hello Sarah! Nice to meet you."}
];
await client.add(messages1, { userId: "sarah" });
// Later interaction - just send new messages
const messages2 = [
{"role": "user", "content": "I'm planning a trip to Italy next month"},
{"role": "assistant", "content": "How exciting! Italy is beautiful this time of year."}
];
await client.add(messages2, { userId: "sarah" });
// Mem0 automatically knows Sarah is from New York and can use this context
```
</CodeGroup>
## Organization Strategies
Choose the right approach based on your application's needs:
### User-Level Memories (`user_id` only)
**Best for:** Personal preferences, profile information, long-term user data
<CodeGroup>
```python Python
# Persistent user memories across all interactions
messages = [
{"role": "user", "content": "I'm allergic to nuts and dairy"},
{"role": "assistant", "content": "I've noted your allergies for future reference."}
]
client.add(messages, user_id="user123")
# This allergy info will be available in ALL future interactions
```
```javascript JavaScript
// Persistent user memories across all interactions
const messages = [
{"role": "user", "content": "I'm allergic to nuts and dairy"},
{"role": "assistant", "content": "I've noted your allergies for future reference."}
];
await client.add(messages, { userId: "user123" });
// This allergy info will be available in ALL future interactions
```
</CodeGroup>
### Session-Specific Memories (`user_id` + `run_id`)
**Best for:** Task-specific context, separate interaction threads, project-based sessions
<CodeGroup>
```python Python
# Trip planning session
messages1 = [
{"role": "user", "content": "I want to plan a 5-day trip to Tokyo"},
{"role": "assistant", "content": "Perfect! Let's plan your Tokyo adventure."}
]
client.add(messages1, user_id="user123", run_id="tokyo-trip-2024")
# Later in the same trip planning session
messages2 = [
{"role": "user", "content": "I prefer staying near Shibuya"},
{"role": "assistant", "content": "Great choice! Shibuya is very convenient."}
]
client.add(messages2, user_id="user123", run_id="tokyo-trip-2024")
# Different session for work project (separate context)
work_messages = [
{"role": "user", "content": "Let's discuss the Q4 marketing strategy"},
{"role": "assistant", "content": "Sure! What are your main goals for Q4?"}
]
client.add(work_messages, user_id="user123", run_id="q4-marketing")
```
```javascript JavaScript
// Trip planning session
const messages1 = [
{"role": "user", "content": "I want to plan a 5-day trip to Tokyo"},
{"role": "assistant", "content": "Perfect! Let's plan your Tokyo adventure."}
];
await client.add(messages1, { userId: "user123", runId: "tokyo-trip-2024" });
// Later in the same trip planning session
const messages2 = [
{"role": "user", "content": "I prefer staying near Shibuya"},
{"role": "assistant", "content": "Great choice! Shibuya is very convenient."}
];
await client.add(messages2, { userId: "user123", runId: "tokyo-trip-2024" });
// Different session for work project (separate context)
const workMessages = [
{"role": "user", "content": "Let's discuss the Q4 marketing strategy"},
{"role": "assistant", "content": "Sure! What are your main goals for Q4?"}
];
await client.add(workMessages, { userId: "user123", runId: "q4-marketing" });
```
</CodeGroup>
## Real-World Use Cases
<Tabs>
<Tab title="Customer Support">
```python Python
# Support ticket context - keeps interaction focused
messages = [
{"role": "user", "content": "My subscription isn't working"},
{"role": "assistant", "content": "I can help with that. What specific issue are you experiencing?"},
{"role": "user", "content": "I can't access premium features even though I paid"}
]
# Each support ticket gets its own run_id
client.add(messages,
user_id="customer123",
run_id="ticket-2024-001"
)
```
</Tab>
<Tab title="Personal AI Assistant">
```python Python
# Personal preferences (persistent across all interactions)
preference_messages = [
{"role": "user", "content": "I prefer morning workouts and vegetarian meals"},
{"role": "assistant", "content": "Got it! I'll keep your fitness and dietary preferences in mind."}
]
client.add(preference_messages, user_id="user456")
# Daily planning session (session-specific)
planning_messages = [
{"role": "user", "content": "Help me plan tomorrow's schedule"},
{"role": "assistant", "content": "Of course! I'll consider your morning workout preference."}
]
client.add(planning_messages,
user_id="user456",
run_id="daily-plan-2024-01-15"
)
```
</Tab>
<Tab title="Educational Platform">
```python Python
# Student profile (persistent)
profile_messages = [
{"role": "user", "content": "I'm studying computer science and struggle with math"},
{"role": "assistant", "content": "I'll tailor explanations to help with math concepts."}
]
client.add(profile_messages, user_id="student789")
# Specific lesson session
lesson_messages = [
{"role": "user", "content": "Can you explain algorithms?"},
{"role": "assistant", "content": "Sure! I'll explain algorithms with math-friendly examples."}
]
client.add(lesson_messages,
user_id="student789",
run_id="algorithms-lesson-1"
)
```
</Tab>
</Tabs>
## Best Practices
### ✅ Do
- **Organize by context scope**: Use `user_id` only for persistent data, add `run_id` for session-specific context
- **Keep messages focused** on the current interaction
- **Test with real interaction flows** to ensure context works as expected
### ❌ Don't
- Send duplicate messages or interaction history
- Skip identifiers like `user_id` or `run_id` that scope the memory
- Mix contextual and non-contextual approaches in the same application
## Troubleshooting
| Issue | Solution |
|-------|----------|
| **Context not working** | Ensure each call uses the same `user_id` / `run_id` combo; version is automatic |
| **Wrong context retrieved** | Check if you need separate `run_id` values for different interaction topics |
| **Missing interaction history** | Verify all messages in the interaction thread use the same `user_id` and `run_id` |
| **Too much irrelevant context** | Use more specific `run_id` values to separate different interaction types |
<Snippet file="get-help.mdx" />
@@ -0,0 +1,201 @@
---
title: Criteria Retrieval
description: "Rank and retrieve memories based on custom-defined criteria like emotional tone, intent, and behavioral signals."
---
Mem0's Criteria Retrieval feature allows you to retrieve memories based on your defined criteria. It goes beyond generic semantic relevance and ranks memories based on what matters to your application: emotional tone, intent, behavioral signals, or other custom traits.
Instead of just searching for "how similar a memory is to this query," you can define what relevance truly means for your project. For example:
- Prioritize joyful memories when building a wellness assistant
- Downrank negative memories in a productivity-focused agent
- Highlight curiosity in a tutoring agent
You define criteria: custom attributes like "joy", "negativity", "confidence", or "urgency", and assign weights to control how they influence scoring. When you search, Mem0 uses these to re-rank semantically relevant memories, favoring those that better match your intent.
This gives you nuanced, intent-aware memory search that adapts to your use case.
## When to Use Criteria Retrieval
Use Criteria Retrieval if:
- Youre building an agent that should react to **emotions** or **behavioral signals**
- You want to guide memory selection based on **context**, not just content
- You have domain-specific signals like "risk", "positivity", "confidence", etc. that shape recall
## Setting Up Criteria Retrieval
Lets walk through how to configure and use Criteria Retrieval step by step.
### Initialize the Client
Before defining any criteria, make sure to initialize the `MemoryClient` with your credentials and project ID:
```python
from mem0 import MemoryClient
client = MemoryClient(api_key="your_mem0_api_key")
```
### Define Your Criteria
Each criterion includes:
- A `name` (used in scoring)
- A `description` (interpreted by the LLM)
- A `weight` (how much it influences the final score)
```python
retrieval_criteria = [
{
"name": "joy",
"description": "Measure the intensity of positive emotions such as happiness, excitement, or amusement expressed in the sentence. A higher score reflects greater joy.",
"weight": 3
},
{
"name": "curiosity",
"description": "Assess the extent to which the sentence reflects inquisitiveness, interest in exploring new information, or asking questions. A higher score reflects stronger curiosity.",
"weight": 2
},
{
"name": "emotion",
"description": "Evaluate the presence and depth of sadness or negative emotional tone, including expressions of disappointment, frustration, or sorrow. A higher score reflects greater sadness.",
"weight": 1
}
]
```
### Apply Criteria to Your Project
Once defined, register the criteria to your project:
```python
client.project.update(retrieval_criteria=retrieval_criteria)
```
Criteria apply project-wide. Once set, they affect all searches automatically.
## Example Walkthrough
After setting up your criteria, you can use them to filter and retrieve memories. Here's an example:
### Add Memories
```python
messages = [
{"role": "user", "content": "What a beautiful sunny day! I feel so refreshed and ready to take on anything!"},
{"role": "user", "content": "I've always wondered how storms form, what triggers them in the atmosphere?"},
{"role": "user", "content": "It's been raining for days, and it just makes everything feel heavier."},
{"role": "user", "content": "Finally I get time to draw something today, after a long time!! I am super happy today."}
]
client.add(messages, user_id="alice")
```
### Run Standard vs. Criteria-Based Search
```python
# Search with criteria enabled
filters = {"user_id": "alice"}
results_with_criteria = client.search(
query="Why I am feeling happy today?",
filters=filters
)
# To disable criteria for a specific search
results_without_criteria = client.search(
query="Why I am feeling happy today?",
filters=filters,
use_criteria=False # Disable criteria-based scoring
)
```
### Compare Results
### Search Results (with Criteria)
```text
[
{"memory": "User feels refreshed and ready to take on anything on a beautiful sunny day", "score": 0.666, ...},
{"memory": "User finally has time to draw something after a long time", "score": 0.616, ...},
{"memory": "User is happy today", "score": 0.500, ...},
{"memory": "User is curious about how storms form and what triggers them in the atmosphere.", "score": 0.400, ...},
{"memory": "It has been raining for days, making everything feel heavier.", "score": 0.116, ...}
]
```
### Search Results (without Criteria)
```text
[
{"memory": "User is happy today", "score": 0.607, ...},
{"memory": "User feels refreshed and ready to take on anything on a beautiful sunny day", "score": 0.512, ...},
{"memory": "It has been raining for days, making everything feel heavier.", "score": 0.4617, ...},
{"memory": "User is curious about how storms form and what triggers them in the atmosphere.", "score": 0.340, ...},
{"memory": "User finally has time to draw something after a long time", "score": 0.336, ...},
]
```
## Search Results Comparison
1. **Memory Ordering**: With criteria, memories with high joy scores (like feeling refreshed and drawing) are ranked higher. Without criteria, the most relevant memory ("User is happy today") comes first.
2. **Score Distribution**: With criteria, scores are more spread out (0.116 to 0.666) and reflect the criteria weights. Without criteria, scores are more clustered (0.336 to 0.607) and based purely on relevance.
3. **Trait Sensitivity**: "Rainy day" content is penalized due to negative tone, while "Storm curiosity" is recognized and scored accordingly.
## Key Differences vs. Standard Search
| Aspect | Standard Search | Criteria Retrieval |
|-------------------------|--------------------------------------|-------------------------------------------------|
| Ranking Logic | Semantic similarity only | Semantic + LLM-based criteria scoring |
| Control Over Relevance | None | Fully customizable with weighted criteria |
| Memory Reordering | Static based on similarity | Dynamically re-ranked by intent alignment |
| Emotional Sensitivity | No tone or trait awareness | Incorporates emotion, tone, or custom behaviors |
| Activation | Default (no criteria defined) | Enabled when criteria are defined in project |
<Note>
If no criteria are defined for a project, search behaves normally based on semantic similarity only.
</Note>
## Best Practices
- Choose 3-5 criteria that reflect your application's intent
- Make descriptions clear and distinct; these are interpreted by an LLM
- Use stronger weights to amplify the impact of important traits
- Avoid redundant or ambiguous criteria (e.g., "positivity" and "joy")
- Always handle empty result sets in your application logic
## How It Works
1. **Criteria Definition**: Define custom criteria with a name, description, and weight. These describe what matters in a memory (e.g., joy, urgency, empathy).
2. **Project Configuration**: Register these criteria using `project.update()`. They apply at the project level and automatically influence all searches.
3. **Memory Retrieval**: When you perform a search, Mem0 first retrieves relevant memories based on the query.
4. **Weighted Scoring**: Each retrieved memory is evaluated and scored against your defined criteria and weights.
This lets you prioritize memories that align with your agent's goals and not just those that look similar to the query.
<Note>
Criteria retrieval is automatically enabled when criteria are defined in your project. Use `use_criteria=False` in search to temporarily disable it for a specific query. `use_criteria` is a server-side parameter passed through to the Platform API: it is not a typed option in the SDK's `SearchMemoryOptions` interface, but the server accepts and processes it when included in the request body.
</Note>
## Summary
- Define what "relevant" means using criteria
- Apply them per project via `project.update()`
- Criteria-aware search activates automatically when criteria are configured
- Build agents that reason not just with relevance, but **contextual importance**
---
Need help designing or tuning your criteria?
<Snippet file="get-help.mdx" />
@@ -0,0 +1,336 @@
---
title: Custom Categories
description: "Replace default memory tags with custom category labels that match your product terminology, set once per project or per individual add call."
---
# Custom Categories
Mem0 automatically tags every memory, but the default labels (travel, sports, music, etc.) may not match the names your app uses. Custom categories let you replace that list so the tags line up with your own wording.
<Info>
**Use custom categories when…**
- You need Mem0 to tag memories with names your product team already uses.
- You want clean reports or automations that rely on those tags.
- Youre moving from the open-source version and want the same labels here.
</Info>
You can set the list once for the whole project, or pass a different list on an individual `add` call.
## Configure access
- Ensure `MEM0_API_KEY` is set in your environment or pass it to the SDK constructor.
- If you scope work to a specific organization/project, initialize the client with those identifiers.
## How it works
- **Default list**: Each project starts with 15 broad categories like `travel`, `sports`, and `music`.
- **Project override**: When you call `project.update(custom_categories=[...])`, that list replaces the defaults for future memories.
- **Per-call override**: When you pass `custom_categories=[...]` to `client.add(...)`, that list is used for the memories extracted from that call.
- **Automatic tags**: As new memories come in, Mem0 picks the closest matches from the active list and saves them in the `categories` field.
### Which list wins
Mem0 resolves the category catalog for each `add` call in this order, and stops at the first one it finds:
1. `custom_categories` passed on the `add` call
2. `custom_categories` set on the project
3. The built-in default catalog
A per-call list **fully replaces** the project list for that call. The two are not merged, so a memory added with a per-call list can only be tagged with categories from that list.
Categories are applied at ingestion time. Changing the project list, or passing a new per-call list, does not re-tag memories that already exist.
<Note>
Default catalog: `personal_details`, `family`, `professional_details`, `sports`, `travel`, `food`, `music`, `health`, `technology`, `hobbies`, `fashion`, `entertainment`, `milestones`, `user_preferences`, `misc`.
</Note>
## Configure it
### 1. Set custom categories at the project level
<CodeGroup>
```python Code
import os
from mem0 import MemoryClient
os.environ["MEM0_API_KEY"] = "your-api-key"
client = MemoryClient()
# Update custom categories
new_categories = [
{"lifestyle_management_concerns": "Tracks daily routines, habits, hobbies and interests including cooking, time management and work-life balance"},
{"seeking_structure": "Documents goals around creating routines, schedules, and organized systems in various life areas"},
{"personal_information": "Basic information about the user including name, preferences, and personality traits"}
]
response = client.project.update(custom_categories=new_categories)
print(response)
```
```json Output
{
"message": "Updated custom categories"
}
```
</CodeGroup>
### 2. Confirm the active catalog
<CodeGroup>
```python Code
# Get current custom categories
categories = client.project.get(fields=["custom_categories"])
print(categories)
```
```json Output
{
"custom_categories": [
{"lifestyle_management_concerns": "Tracks daily routines, habits, hobbies and interests including cooking, time management and work-life balance"},
{"seeking_structure": "Documents goals around creating routines, schedules, and organized systems in various life areas"},
{"personal_information": "Basic information about the user including name, preferences, and personality traits"}
]
}
```
</CodeGroup>
`get` echoes back the shape you set. `update` also accepts a plain list of names, such as `["billing", "support"]`, in which case `get` returns that same list of names. Descriptions are optional here, and the classifier uses them to disambiguate when it has them.
<Warning>
`add` is stricter than `update`. Every entry in a per-call `custom_categories` list must be an object mapping a name to a description. Passing bare names to `add` fails with `400 Expected a dictionary of items but got type "str"`.
</Warning>
### 3. Override categories on a single add call
Pass `custom_categories` directly to `add` when one call needs a different catalog than the project default. The memories created by that call are tagged from the list you pass, and the project list is left untouched.
<CodeGroup>
```python Python
health_messages = [
{"role": "user", "content": "My doctor bumped my metformin to 1000mg and I see her again on the 14th."},
{"role": "assistant", "content": "Noted the new dosage and the follow-up appointment."},
]
health_categories = [
{"symptoms": "Reported physical or mental symptoms"},
{"medications": "Prescriptions, dosages, and adherence"},
{"appointments": "Scheduled visits and follow-ups"},
]
client.add(
health_messages,
user_id="alice",
custom_categories=health_categories,
)
```
```javascript JavaScript
const healthMessages = [
{ role: "user", content: "My doctor bumped my metformin to 1000mg and I see her again on the 14th." },
{ role: "assistant", content: "Noted the new dosage and the follow-up appointment." },
];
const healthCategories = [
{ symptoms: "Reported physical or mental symptoms" },
{ medications: "Prescriptions, dosages, and adherence" },
{ appointments: "Scheduled visits and follow-ups" },
];
await client.add(healthMessages, {
userId: "alice",
customCategories: healthCategories,
});
```
```text Resulting categories
["medications", "appointments"]
```
</CodeGroup>
The memory is tagged from `health_categories` alone. The project catalog is not consulted for this call, and it is not modified.
#### Per-user categories inside one project
The main reason to reach for a per-call list is to give different users, tenants, or entities their own vocabulary without splitting them across projects. Keep one project, and pass the list that fits the entity you are writing for.
<CodeGroup>
```python Python
patient_categories = [
{"symptoms": "Reported physical or mental symptoms"},
{"medications": "Prescriptions, dosages, and adherence"},
]
clinician_categories = [
{"caseload": "Patients under this clinician's care"},
{"availability": "Shift patterns and on-call windows"},
]
client.add("My metformin is now 1000mg.", user_id="alice", custom_categories=patient_categories)
client.add("I'm on call Tuesdays and Thursdays.", user_id="dr-reyes", custom_categories=clinician_categories)
```
</CodeGroup>
## See it in action
### Add a memory (uses the project catalog automatically)
<CodeGroup>
```python Code
messages = [
{"role": "user", "content": "My name is Alice. I need help organizing my daily schedule better. I feel overwhelmed trying to balance work, exercise, and social life."},
{"role": "assistant", "content": "I understand how overwhelming that can feel. Let's break this down together. What specific areas of your schedule feel most challenging to manage?"},
{"role": "user", "content": "I want to be more productive at work, maintain a consistent workout routine, and still have energy for friends and hobbies."},
{"role": "assistant", "content": "Those are great goals for better time management. What's one small change you could make to start improving your daily routine?"},
]
# Add memories with project-level custom categories
client.add(messages, user_id="alice")
```
</CodeGroup>
### Retrieve memories and inspect categories
`get_all` returns a paginated object. The memories are under `results`, and each one carries its own `categories` list.
<CodeGroup>
```python Code
response = client.get_all(filters={"user_id": "alice"})
for memory in response["results"]:
print(memory["memory"], memory["categories"])
```
```text Output
User introduced herself as Alice and expressed a desire for help organizing her daily schedule. ['lifestyle_management_concerns', 'seeking_structure', 'personal_information']
User feels overwhelmed trying to balance work responsibilities, regular exercise, and a social life, indicating difficulty managing time across these areas. ['lifestyle_management_concerns']
User's goals include becoming more productive at work, maintaining a consistent workout routine, and preserving enough energy for friends and hobbies. ['lifestyle_management_concerns', 'seeking_structure']
```
</CodeGroup>
Extraction is model driven, so the exact wording and the number of memories vary between runs. The categories are drawn from the active list.
<Info>
**Sample memory payload**
```json
{
"id": "638008c4-***",
"memory": "User is seeking to balance work responsibilities with regular workout sessions and requests a personalized schedule to manage both.",
"user_id": "alice",
"metadata": null,
"categories": ["lifestyle_management_concerns", "seeking_structure"],
"created_at": "2026-07-10T06:13:12-07:00",
"updated_at": "2026-07-10T06:13:20-07:00",
"expiration_date": null,
"structured_attributes": {
"year": 2026,
"month": 7,
"day": 10,
"hour": 13,
"minute": 13,
"day_of_week": "friday",
"week_of_year": 28,
"day_of_year": 191,
"quarter": 3,
"is_weekend": false
}
}
```
</Info>
Categorization runs asynchronously, a moment after the memory itself is written. A memory fetched immediately after `add` may not show up in `get_all` yet, or can come back with `categories: null` and pick up its tags a moment later. Poll until `categories` is populated rather than reading once.
<Note>
Need ad-hoc labels for a single call? Pass `custom_categories` on that `add` call. Use `metadata` instead when the label is a fixed value you already know, rather than something the classifier should infer.
</Note>
## Default categories (fallback)
If you do nothing, memories are tagged with the built-in set below.
```
- personal_details
- family
- professional_details
- sports
- travel
- food
- music
- health
- technology
- hobbies
- fashion
- entertainment
- milestones
- user_preferences
- misc
```
<CodeGroup>
```python Code
import os
from mem0 import MemoryClient
os.environ["MEM0_API_KEY"] = "your-api-key"
client = MemoryClient()
messages = [
{"role": "user", "content": "Hi, my name is Alice."},
{"role": "assistant", "content": "Hi Alice, what sports do you like to play?"},
{"role": "user", "content": "I love playing badminton, football, and basketball. I'm quite athletic!"},
{"role": "assistant", "content": "That's great! Alice seems to enjoy both individual sports like badminton and team sports like football and basketball."},
{"role": "user", "content": "Sometimes, I also draw and sketch in my free time."},
{"role": "assistant", "content": "That's cool! I'm sure you're good at it."}
]
# Add memories with default categories
client.add(messages, user_id='alice')
```
```text Memories with categories
# Following categories will be created for the memories added
Sometimes draws and sketches in free time (hobbies)
Is quite athletic (sports)
Loves playing badminton, football, and basketball (sports)
Name is Alice (personal_details)
```
</CodeGroup>
You can verify the defaults are active by checking:
<CodeGroup>
```python Code
client.project.get(["custom_categories"])
```
```json Output
{
"custom_categories": null
}
```
</CodeGroup>
A project that has never set a list returns `null`. One you have reset with `project.update(custom_categories=[])` returns `[]`. Both mean the default catalog is active.
## Verify the feature is working
- `client.project.get(["custom_categories"])` returns the category list you set.
- `client.get_all(filters={"user_id": ...})` shows populated `categories` lists on new memories.
- The Mem0 dashboard (Project → Memories) displays the custom labels in the Category column.
## Best practices
- Keep category descriptions concise but specific; the classifier uses them to disambiguate.
- Review memories with empty `categories` to see where you might extend or rename your list.
- Set the catalog your app uses most often at the project level, and reserve per-call lists for the calls that genuinely need a different vocabulary.
- If a per-call list should also keep the project categories, include them in the list you pass. Passing a list replaces, it does not extend.
<CardGroup cols={2}>
<Card title="Advanced Memory Operations" icon="wand-magic-sparkles" href="/platform/advanced-memory-operations">
Explore other ingestion tunables like custom prompts and selective writes.
</Card>
<Card title="Travel Assistant Cookbook" icon="plane-up" href="/cookbooks/companions/travel-assistant">
See custom tagging drive personalization in a full agent workflow.
</Card>
</CardGroup>
@@ -0,0 +1,336 @@
---
title: Custom Instructions
description: 'Control how Mem0 extracts and stores memories using natural language guidelines'
---
## What are Custom Instructions?
Custom instructions are natural language guidelines that let you define exactly what Mem0 should include or exclude when creating memories from conversations. This gives you precise control over what information is extracted, acting as smart filters so your AI application only remembers what matters for your use case.
<CodeGroup>
```python Python
# Simple example: Health app focusing on wellness
prompt = """
Extract only health and wellness information:
- Symptoms, medications, and treatments
- Exercise routines and dietary habits
- Doctor appointments and health goals
Exclude: Personal identifiers, financial data
"""
client.project.update(custom_instructions=prompt)
```
```javascript JavaScript
// Simple example: Health app focusing on wellness
const prompt = `
Extract only health and wellness information:
- Symptoms, medications, and treatments
- Exercise routines and dietary habits
- Doctor appointments and health goals
Exclude: Personal identifiers, financial data
`;
await client.project.update({ customInstructions: prompt });
```
</CodeGroup>
## Why Use Custom Instructions?
- **Focus on What Matters**: Only capture information relevant to your application
- **Maintain Privacy**: Explicitly exclude sensitive data like passwords or personal identifiers
- **Ensure Consistency**: All memories follow the same extraction rules across your project
- **Improve Quality**: Filter out noise and irrelevant conversations
## How to Set Custom Instructions
### Basic Setup
<CodeGroup>
```python Python
# Set instructions for your project
client.project.update(custom_instructions="Your guidelines here...")
# Retrieve current instructions
response = client.project.get(fields=["custom_instructions"])
print(response["custom_instructions"])
```
```javascript JavaScript
// Set instructions for your project
await client.project.update({ customInstructions: "Your guidelines here..." });
// Retrieve current instructions
const response = await client.project.get({ fields: ["customInstructions"] });
console.log(response.customInstructions);
```
</CodeGroup>
### Best Practice Template
Structure your instructions using this proven template:
```
Your Task: [Brief description of what to extract]
Information to Extract:
1. [Category 1]:
- [Specific details]
- [What to look for]
2. [Category 2]:
- [Specific details]
- [What to look for]
Guidelines:
- [Processing rules]
- [Quality requirements]
Exclude:
- [Sensitive data to avoid]
- [Irrelevant information]
```
## Real-World Examples
<Tabs>
<Tab title="E-commerce Customer Support">
<CodeGroup>
```python Python
instructions = """
Extract customer service information for better support:
1. Product Issues:
- Product names, SKUs, defects
- Return/exchange requests
- Quality complaints
2. Customer Preferences:
- Preferred brands, sizes, colors
- Shopping frequency and habits
- Price sensitivity
3. Service Experience:
- Satisfaction with support
- Resolution time expectations
- Communication preferences
Exclude: Payment card numbers, passwords, personal identifiers.
"""
client.project.update(custom_instructions=instructions)
```
```javascript JavaScript
const instructions = `
Extract customer service information for better support:
1. Product Issues:
- Product names, SKUs, defects
- Return/exchange requests
- Quality complaints
2. Customer Preferences:
- Preferred brands, sizes, colors
- Shopping frequency and habits
- Price sensitivity
3. Service Experience:
- Satisfaction with support
- Resolution time expectations
- Communication preferences
Exclude: Payment card numbers, passwords, personal identifiers.
`;
await client.project.update({ customInstructions: instructions });
```
</CodeGroup>
</Tab>
<Tab title="Personalized Learning Platform">
<CodeGroup>
```python Python
education_prompt = """
Extract learning-related information for personalized education:
1. Learning Progress:
- Course completions and current modules
- Skills acquired and improvement areas
- Learning goals and objectives
2. Student Preferences:
- Learning styles (visual, audio, hands-on)
- Time availability and scheduling
- Subject interests and career goals
3. Performance Data:
- Assignment feedback and patterns
- Areas of struggle or strength
- Study habits and engagement
Exclude: Specific grades, personal identifiers, financial information.
"""
client.project.update(custom_instructions=education_prompt)
```
```javascript JavaScript
const educationPrompt = `
Extract learning-related information for personalized education:
1. Learning Progress:
- Course completions and current modules
- Skills acquired and improvement areas
- Learning goals and objectives
2. Student Preferences:
- Learning styles (visual, audio, hands-on)
- Time availability and scheduling
- Subject interests and career goals
3. Performance Data:
- Assignment feedback and patterns
- Areas of struggle or strength
- Study habits and engagement
Exclude: Specific grades, personal identifiers, financial information.
`;
await client.project.update({ customInstructions: educationPrompt });
```
</CodeGroup>
</Tab>
<Tab title="AI Financial Advisor">
<CodeGroup>
```python Python
finance_prompt = """
Extract financial planning information for advisory services:
1. Financial Goals:
- Retirement and investment objectives
- Risk tolerance and preferences
- Short-term and long-term goals
2. Life Events:
- Career and income changes
- Family changes (marriage, children)
- Major planned purchases
3. Investment Interests:
- Asset allocation preferences
- ESG or ethical investment interests
- Previous investment experience
Exclude: Account numbers, SSNs, passwords, specific financial amounts.
"""
client.project.update(custom_instructions=finance_prompt)
```
```javascript JavaScript
const financePrompt = `
Extract financial planning information for advisory services:
1. Financial Goals:
- Retirement and investment objectives
- Risk tolerance and preferences
- Short-term and long-term goals
2. Life Events:
- Career and income changes
- Family changes (marriage, children)
- Major planned purchases
3. Investment Interests:
- Asset allocation preferences
- ESG or ethical investment interests
- Previous investment experience
Exclude: Account numbers, SSNs, passwords, specific financial amounts.
`;
await client.project.update({ customInstructions: financePrompt });
```
</CodeGroup>
</Tab>
</Tabs>
## Advanced Techniques
### Conditional Processing
Handle different conversation types with conditional logic:
<CodeGroup>
```python Python
advanced_prompt = """
Extract information based on conversation context:
IF customer support conversation:
- Issue type, severity, resolution status
- Customer satisfaction indicators
IF sales conversation:
- Product interests, budget range
- Decision timeline and influencers
IF onboarding conversation:
- User experience level
- Feature interests and priorities
Always exclude personal identifiers and maintain professional context.
"""
client.project.update(custom_instructions=advanced_prompt)
```
</CodeGroup>
### Testing Your Instructions
Always test your custom instructions with real message examples:
<CodeGroup>
```python Python
# Test with sample messages
messages = [
{"role": "user", "content": "I'm having billing issues with my subscription"},
{"role": "assistant", "content": "I can help with that. What's the specific problem?"},
{"role": "user", "content": "I'm being charged twice each month"}
]
# Add the messages and check extracted memories
result = client.add(messages, user_id="test_user")
memories = client.get_all(filters={"AND": [{"user_id": "test_user"}]})
# Review if the right information was extracted
for memory in memories:
print(f"Extracted: {memory['memory']}")
```
</CodeGroup>
## Best Practices
### ✅ Do
- **Be specific** about what information to extract
- **Use clear categories** to organize your instructions
- **Test with real conversations** before deploying
- **Explicitly state exclusions** for privacy and compliance
- **Start simple** and iterate based on results
### ❌ Don't
- Make instructions too long or complex
- Create conflicting rules within your guidelines
- Be overly restrictive (balance specificity with flexibility)
- Forget to exclude sensitive information
- Skip testing with diverse conversation examples
## Common Issues and Solutions
| Issue | Solution |
|-------|----------|
| **Instructions too long** | Break into focused categories, keep concise |
| **Missing important data** | Add specific examples of what to capture |
| **Capturing irrelevant info** | Strengthen exclusion rules and be more specific |
| **Inconsistent results** | Clarify guidelines and test with more examples |
+109
View File
@@ -0,0 +1,109 @@
---
title: Direct Import
description: 'Bypass the memory deduction phase and directly store pre-defined memories for efficient retrieval'
---
## How to Use Direct Import
The Direct Import feature allows users to skip the memory deduction phase and directly input pre-defined memories into the system for storage and retrieval. To enable this feature, set the `infer` parameter to `False` in the `add` method.
<CodeGroup>
```python Python
messages = [
{"role": "user", "content": "Alice loves playing badminton"},
{"role": "assistant", "content": "That's great! Alice is a fitness freak"},
{"role": "user", "content": "Alice mostly cooks at home because of her gym plan"},
]
client.add(messages, user_id="alice", infer=False)
```
```markdown Output
[]
```
</CodeGroup>
You can see that the output of the add call is an empty list.
<Note>Only messages with the role "user" will be used for storage. Messages with roles such as "assistant" or "system" will be ignored during the storage process.</Note>
<Warning>
Direct import skips the inference pipeline, so it also skips duplicate detection. If you later send the same fact with `infer=True`, Mem0 will store a second copy. Pick one mode per memory source unless you truly want both versions.
</Warning>
## How to Retrieve Memories
You can retrieve memories using the `search` method.
<CodeGroup>
```python Python
client.search("What is Alice's favorite sport?", filters={"user_id": "alice"})
```
```json Output
{
"results": [
{
"id": "19d6d7aa-2454-4e58-96fc-e74d9e9f8dd1",
"memory": "Alice loves playing badminton",
"user_id": "pc123",
"metadata": null,
"categories": null,
"created_at": "2024-10-15T21:52:11.474901-07:00",
"updated_at": "2024-10-15T21:52:11.474912-07:00"
}
]
}
```
</CodeGroup>
## How to Retrieve All Memories
You can retrieve all memories using the `get_all` method.
<Callout type="warning" title="Filters Required">
`get_all()` now requires filters to be specified.
</Callout>
<CodeGroup>
```python Python
client.get_all(filters={"AND": [{"user_id": "alice"}]})
```
```json Output
{
"results": [
{
"id": "19d6d7aa-2454-4e58-96fc-e74d9e9f8dd1",
"memory": "Alice loves playing badminton",
"user_id": "pc123",
"metadata": null,
"categories": null,
"created_at": "2024-10-15T21:52:11.474901-07:00",
"updated_at": "2024-10-15T21:52:11.474912-07:00"
},
{
"id": "8557f05d-7b3c-47e5-b409-9886f9e314fc",
"memory": "Alice mostly cooks at home because of her gym plan",
"user_id": "pc123",
"metadata": null,
"categories": null,
"created_at": "2024-10-15T21:52:11.474929-07:00",
"updated_at": "2024-10-15T21:52:11.474932-07:00"
}
]
}
```
</CodeGroup>
If you have any questions, please feel free to reach out to us using one of the following methods:
<Snippet file="get-help.mdx" />
@@ -0,0 +1,201 @@
---
title: Entity-Scoped Memory
description: Scope conversations by user, agent, app, and session so memories land exactly where they belong.
---
Mem0's Platform API lets you separate memories for different users, agents, and apps. By tagging each write and query with the right identifiers, you can prevent data from mixing between them, maintain clear audit trails, and control data retention.
<Note>
**Entity IDs vs. graph entities.** This page covers the `user_id` / `agent_id` / `app_id` / `run_id` identifiers used to *scope* memories. These are different from the **graph entities** (the people, places, and concepts surfaced in [Graph Memory](/platform/features/graph-memory)).
</Note>
<Tip icon="layers">
Want the long-form tutorial? The <Link href="/cookbooks/essentials/entity-partitioning-playbook">Partition Memories by Entity</Link> cookbook walks through multi-agent storage, debugging, and cleanup step by step.
</Tip>
<Info>
**You'll use this when…**
- You run assistants for multiple customers who each need private memory spaces
- Different agents (like a planner and a critic) need separate context for the same user
- Sessions should expire on their own schedule, making debugging and data removal more precise
</Info>
## Configure access
```python
from mem0 import MemoryClient
client = MemoryClient(api_key="m0-...")
```
Call `client.project.get()` to verify your connection. It should return your project details including `org_id` and `project_id`. If you get a 401 error, generate a new API key in the Mem0 dashboard.
## Feature anatomy
| Dimension | Field | When to use it | Example value |
| ----------- | ---------- | ------------------------------------------------ | ------------------- |
| User | `user_id` | Persistent persona or account | `"customer_6412"` |
| Agent | `agent_id` | Distinct agent persona or tool | `"meal_planner"` |
| Application | `app_id` | White-label app or product surface | `"ios_retail_demo"` |
| Session | `run_id` | Short-lived flow, ticket, or conversation thread | `"ticket-9241"` |
- **Writes** (`client.add`) accept any combination of these fields. Absent fields default to `null`.
- **Reads** (`client.search`, `client.get_all`, exports, deletes) accept the same identifiers inside the `filters` JSON object.
- **Implicit null scoping**: Passing only `{"user_id": "alice"}` automatically restricts results to records where `agent_id`, `app_id`, and `run_id` are `null`. Add wildcards (`"*"`), explicit lists, or additional filters when you need broader joins.
<Warning>
**Common Pitfall**: If you create a memory with `user_id="alice"` but the other fields default to `null`, then search with `{"AND": [{"user_id": "alice"}, {"agent_id": "bot"}]}` will return nothing because you're looking for a memory where `agent_id="bot"`, not `null`.
</Warning>
## Choose the right identifier
| Identifier | Purpose | Example Use Cases |
|------------|---------|-------------------|
| `user_id` | Store preferences, profile details, and historical actions that follow a person everywhere | Dietary restrictions, seat preferences, meeting habits |
| `agent_id` | Keep an agent's personality, operating modes, or brand voice in one place | Travel agent vs concierge vs customer support personas |
| `app_id` | Tag every write from a partner app or deployment for tenant separation | White-label deployments, partner integrations |
| `run_id` | Isolate temporary flows that should reset or expire independently | Support tickets, chat sessions, experiments |
For more detailed examples, see the Partition Memories by Entity cookbook.
## Configure it
The example below adds memories with entity tags:
```python
messages = [
{"role": "user", "content": "I teach ninth-grade algebra."},
{"role": "assistant", "content": "I'll tailor study plans to algebra topics."}
]
client.add(
messages,
user_id="teacher_872",
agent_id="study_planner",
app_id="district_dashboard",
run_id="prep-period-2025-09-02"
)
```
The response will include one or more memory IDs. Check the dashboard → Memories to confirm the entry appears under the correct user, agent, app, and run.
<Warning>
Platform writes that include both `user_id` and `agent_id` (or other combinations) are persisted as separate records per entity so we can enforce privacy boundaries. Each record carries exactly one primary entity, which is why `{"AND": [{"user_id": ...}, {"agent_id": ...}]}` never returns results. Plan searches per entity scope or combine scopes with `OR`.
</Warning>
The HTTP equivalent uses `POST /v1/memories/` with the same identifiers in the JSON body. See the Add Memories API reference for REST details.
## See it in action
**1. Store scoped memories**
```python
traveler_messages = [
{"role": "user", "content": "I prefer boutique hotels and avoid shellfish."},
{"role": "assistant", "content": "Logged your travel preferences for future itineraries."}
]
client.add(
traveler_messages,
user_id="customer_6412",
agent_id="travel_planner",
app_id="concierge_portal",
run_id="itinerary-2025-apr",
metadata={"category": "preferences"}
)
```
**2. Retrieve by user scope**
```python
user_scope = {
"AND": [
{"user_id": "customer_6412"},
{"app_id": "concierge_portal"},
{"run_id": "itinerary-2025-apr"}
]
}
user_results = client.search("Any dietary flags?", filters=user_scope)
print(user_results)
```
**3. Retrieve by agent scope**
```python
agent_scope = {
"AND": [
{"agent_id": "travel_planner"},
{"app_id": "concierge_portal"}
]
}
agent_results = client.search("Any dietary flags?", filters=agent_scope)
print(agent_results)
```
<Tip icon="compass">
Writes can include multiple identifiers, but searches resolve one entity space at a time. Query user scope *or* agent scope in a given call: combining both returns an empty list today.
</Tip>
<Tip icon="sparkles">
Want to experiment with AND/OR logic, nested operators, or wildcards? The <Link href="/platform/features/v2-memory-filters">Memory Filters v2 guide</Link> walks through every filter pattern with working examples.
</Tip>
**4. Audit everything for an app**
```python
app_scope = {
"AND": [
{"app_id": "concierge_portal"}
],
"OR": [
{"user_id": "*"},
{"agent_id": "*"}
]
}
page = client.get_all(filters=app_scope, page=1, page_size=20)
```
<Info>
Wildcards (`"*"`) include only non-null values. Use them when you want "any agent" or "any user" without limiting results to null-only records.
</Info>
**5. Clean up a session**
```python
client.delete_all(
user_id="customer_6412",
run_id="itinerary-2025-apr"
)
```
<Info icon="check">
A successful delete returns `{"message": "Memories deleted successfully!"}`. Run the previous `get_all` call again to confirm the session memories were removed.
</Info>
## Verify the feature is working
- Run `client.search` with your filters and confirm only expected memories appear. Mismatched identifiers usually mean a typo in your scoping.
- Check the Mem0 dashboard filter pills. User, agent, app, and run should all show populated values for your memory entry.
- Call `client.delete_all` with a unique `run_id` and confirm other sessions remain intact (the count in `get_all` should only drop for that run).
## Best practices
- Use consistent identifier formats (like `team-alpha` or `app-ios-retail`) so you can query or delete entire groups later
- When debugging, print your filters before each call to verify wildcards (`"*"`), lists, and run IDs are spelled correctly
- Combine entity filters with metadata filters (categories, created_at) for precise exports or audits
- Use `run_id` for temporary sessions like support tickets or experiments, then schedule cleanup jobs to delete them
For a complete walkthrough, see the Partition Memories by Entity cookbook.
{/* DEBUG: verify CTA targets */}
<CardGroup cols={2}>
<Card
title="Master Memory Filters"
description="Deep dive into JSON logic, operators, and wildcard behavior."
icon="sliders"
href="/platform/features/v2-memory-filters"
/>
<Card
title="Partition Memories in Practice"
description="Follow the essentials cookbook to implement scoped workflows."
icon="book-open"
href="/cookbooks/essentials/entity-partitioning-playbook"
/>
</CardGroup>
@@ -0,0 +1,203 @@
---
title: Feedback Mechanism
description: "Provide positive or negative feedback on generated memories to continuously improve accuracy and search results."
---
Mem0's Feedback Mechanism allows you to provide feedback on the memories generated by your application. This feedback is used to improve the accuracy of the memories and search results.
## How it works
The feedback mechanism is a simple API that allows you to provide feedback on the memories generated by your application. The feedback is stored in the database and used to improve the accuracy of the memories and search results. Over time, Mem0 continuously learns from this feedback, refining its memory generation and search capabilities for better performance.
## Give Feedback
You can give feedback on a memory by calling the `feedback` method on the Mem0 client.
<CodeGroup>
```python Python
from mem0 import MemoryClient
client = MemoryClient(api_key="your_api_key")
client.feedback(memory_id="your-memory-id", feedback="NEGATIVE", feedback_reason="I don't like this memory because it is not relevant.")
```
```javascript JavaScript
import MemoryClient from 'mem0ai';
const client = new MemoryClient({ apiKey: 'your-api-key'});
client.feedback({
memory_id: "your-memory-id",
feedback: "NEGATIVE",
feedback_reason: "I don't like this memory because it is not relevant."
})
```
</CodeGroup>
## Feedback Types
The `feedback` parameter can be one of the following values:
- `POSITIVE`: The memory is useful.
- `NEGATIVE`: The memory is not useful.
- `VERY_NEGATIVE`: The memory is not useful at all.
## Parameters
The `feedback` method accepts these parameters:
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `memory_id` | string | Yes | The ID of the memory to give feedback on |
| `feedback` | string | No | Type of feedback: `POSITIVE`, `NEGATIVE`, or `VERY_NEGATIVE` |
| `feedback_reason` | string | No | Optional explanation for the feedback |
<Note>
Pass `None` or `null` to the `feedback` and `feedback_reason` parameters to remove existing feedback for a memory.
</Note>
## Bulk Feedback Operations
For applications with high volumes of feedback, you can provide feedback on multiple memories at once:
<CodeGroup>
```python Python
from mem0 import MemoryClient
client = MemoryClient(api_key="your_api_key")
# Bulk feedback example
feedback_data = [
{
"memory_id": "memory-1",
"feedback": "POSITIVE",
"feedback_reason": "Accurately captured the user's preference"
},
{
"memory_id": "memory-2",
"feedback": "NEGATIVE",
"feedback_reason": "Contains outdated information"
}
]
for item in feedback_data:
client.feedback(**item)
```
```javascript JavaScript
import MemoryClient from 'mem0ai';
const client = new MemoryClient({ apiKey: 'your-api-key'});
// Bulk feedback example
const feedbackData = [
{
memory_id: "memory-1",
feedback: "POSITIVE",
feedback_reason: "Accurately captured the user's preference"
},
{
memory_id: "memory-2",
feedback: "NEGATIVE",
feedback_reason: "Contains outdated information"
}
];
for (const item of feedbackData) {
await client.feedback(item);
}
```
</CodeGroup>
## Best Practices
### When to Provide Feedback
- Immediately after memory retrieval when you can assess relevance
- During user interactions when users explicitly indicate satisfaction or dissatisfaction
- Through automated evaluation using your application's success metrics
### Effective Feedback Reasons
Provide specific, actionable feedback reasons:
**Good examples:**
- "Contains outdated contact information"
- "Accurately captured the user's dietary restrictions"
- "Irrelevant to the current conversation context"
**Avoid vague reasons:**
- "Bad memory"
- "Wrong"
- "Not good"
### Feedback Strategy
1. Be consistent: Apply the same criteria across similar memories
2. Be specific: Detailed reasons help improve the system faster
3. Monitor patterns: Regular feedback analysis helps identify improvement areas
## Error Handling
Handle potential errors when submitting feedback:
<CodeGroup>
```python Python
from mem0 import MemoryClient
from mem0.exceptions import MemoryNotFoundError, NetworkError
client = MemoryClient(api_key="your_api_key")
try:
client.feedback(
memory_id="memory-123",
feedback="POSITIVE",
feedback_reason="Helpful context for user query"
)
print("Feedback submitted successfully")
except MemoryNotFoundError:
print("Memory not found")
except NetworkError as e:
print(f"Network error: {e}")
except Exception as e:
print(f"Unexpected error: {e}")
```
```javascript JavaScript
import MemoryClient from 'mem0ai';
const client = new MemoryClient({ apiKey: 'your-api-key'});
try {
await client.feedback({
memory_id: "memory-123",
feedback: "POSITIVE",
feedback_reason: "Helpful context for user query"
});
console.log("Feedback submitted successfully");
} catch (error) {
if (error.status === 404) {
console.log("Memory not found");
} else {
console.log(`Error: ${error.message}`);
}
}
```
</CodeGroup>
## Feedback Analytics
Track the impact of your feedback by monitoring memory performance over time. Consider implementing:
- Feedback completion rates: What percentage of memories receive feedback
- Feedback distribution: Balance of positive vs. negative feedback
- Memory quality trends: How accuracy improves with feedback volume
- User satisfaction metrics: Correlation between feedback and user experience
+98
View File
@@ -0,0 +1,98 @@
---
title: "Graph Memory"
description: "Mem0 Platform builds a native graph linking people, places, and concepts across your memories, with no external graph database to provision."
---
Mem0 Platform automatically organizes your memories into a **graph**: the **graph entities** mentioned across your memories (the people, places, organizations, and concepts they refer to) become nodes, and memories that share an entity are connected. This is how Mem0 reasons across separate facts, for example linking everything it knows about a person, a company, or a project, without you defining any schema.
Graph Memory is **built in**. There is no Neo4j, Memgraph, or other graph store to deploy, no connection strings to manage, and nothing to enable. It runs natively inside the platform and is always on.
<Info>
**Graph Memory matters when…**
- You ask entity-centric questions like "what do we know about Alice?" and expect facts pulled from many different conversations
- Your app needs multi-hop recall, connecting a fact in one memory to a related fact in another
- You previously used an external graph store and want the same cross-memory connections with zero infrastructure
</Info>
<Note>
**Graph entities vs. entity IDs.** The entities in your graph (people, places, and concepts extracted from memory text) are different from the *entity IDs* (`user_id`, `agent_id`, `app_id`, `run_id`) used to scope memories. Those are covered in [Entity-Scoped Memory](/platform/features/entity-scoped-memory).
</Note>
<Note>
Graph Memory is the native successor to Mem0's earlier graph store integration. Earlier versions connected an external graph database (Neo4j and others) and exposed a `relations` field. Mem0 now builds the graph itself from your memories. See [What changed from the external graph store](#what-changed-from-the-external-graph-store) below.
</Note>
## How it works
Graph Memory is built and used across the two phases of the memory pipeline: **extraction** (when you add memories) and **retrieval** (when you search).
### 1. Entities become nodes
Every time you add a memory, Mem0 extracts the **entities** it contains: the proper nouns, names, and key phrases that identify a specific person, place, organization, product, or concept (for example *Alice*, *San Francisco*, *Acme Corp*, *the Q1 roadmap*). Each distinct entity is stored once and embedded, so entities that refer to the same thing can be matched even when they are phrased differently.
### 2. Shared entities become connections
When the same entity appears in more than one memory, those memories are **linked** through that entity. Over time this forms a graph: a web of entities, each connecting all the memories that mention it. The connections are derived directly from your data. There is no relationship schema to define and nothing to label by hand.
### 3. The graph powers retrieval
At search time, Mem0 extracts the entities from your query and matches them against the graph. Memories connected to those entities receive a ranking boost, which is combined with semantic (vector) and keyword (BM25) scores into the single `score` returned on each result.
This is what lets Mem0 answer entity-centric and multi-hop questions: a query about *Alice* surfaces facts about Alice that live in completely different memories, because the graph connects them. The connecting-facts-across-memories behavior contributes to Mem0's gains on multi-hop and temporal benchmarks. See [Memory Evaluation](/core-concepts/memory-evaluation).
<Info>
Graph Memory affects **ranking**, not the response shape. Search results come back in the normal format with a combined `score`; there is no separate graph payload to parse.
</Info>
## What's in the graph
| Element | What it is |
| --- | --- |
| **Graph entity** (node) | A distinct person, place, organization, product, or concept extracted from your memories (e.g. *Alice*, *Acme Corp*). Distinct from the user/agent/app/run *entity IDs* used to scope memories. |
| **Memory node** | An individual memory (fact) stored for a user, agent, or session. |
| **Connection** | A link between an entity and every memory that mentions it. Two entities are related when they co-occur in one or more memories. |
Graph Memory captures **which entities your memories are about and how they connect through shared context**. It does not assign typed, labeled relationships between entities (it won't, for example, record a "manages" edge from one person to another); connections are inferred from co-occurrence rather than declared. This is what makes it schema-free and zero-configuration.
## Availability
Graph Memory has two parts, and they are gated differently:
| What | Availability |
| --- | --- |
| **Graph memory**: entity extraction, linking, and the retrieval boost | **All plans**, automatic |
| **Graph view**: interactive visualization in the dashboard | **Pro and Enterprise** |
Every plan gets the graph working behind the scenes to sharpen retrieval. **Pro and Enterprise** unlock the interactive **Graph view**, where you can explore your entities, trace how memories connect, and search and filter the whole graph right in your dashboard.
```python
from mem0 import MemoryClient
client = MemoryClient(api_key="your-api-key")
# Entities are extracted and linked into the graph automatically on add
client.add(
messages=[
{"role": "user", "content": "I work at Acme Corp with Alice on the Q1 roadmap"}
],
user_id="jordan",
)
# Entity matches from the query are used to connect and boost related memories
results = client.search(
query="who does jordan work with?",
filters={"user_id": "jordan"},
)
```
## What changed from the external graph store
Earlier versions of Mem0 offered graph memory by connecting an **external graph database** (Neo4j, Memgraph, Kuzu, Apache AGE, or Neptune) through an `enable_graph` flag and a `graph_store` configuration block. That integration has been replaced by **native, built-in Graph Memory**:
- **No external graph store.** The graph is built inside Mem0 from your memories. There is nothing to provision or connect.
- **Always on, all plans.** The `enable_graph` flag is no longer needed; Graph Memory is automatic. (If you still send the parameter, it is ignored.)
- **Connections power retrieval directly.** Entity connections are folded into the combined `score` on each result. The standalone `relations` field that the external graph store returned is no longer populated. If your application read that field, see the migration guide below.
<Card title="Platform Migration Guide" icon="arrow-right" href="/migration/platform-v2-to-v3">
Full details on the move to the new algorithm, including the `relations` field change.
</Card>
+293
View File
@@ -0,0 +1,293 @@
---
title: Group Chat
description: 'Enable multi-participant conversations with automatic memory attribution to individual speakers'
---
## Overview
The Group Chat feature enables Mem0 to process conversations involving multiple participants and automatically attribute memories to individual speakers. This allows for precise tracking of each participant's preferences, characteristics, and contributions in collaborative discussions, team meetings, or multi-agent conversations.
When you provide messages with participant names, Mem0 automatically:
- Extracts memories from each participant's messages separately
- Attributes each memory to the correct speaker using their name as the `user_id` or `agent_id`
- Maintains individual memory profiles for each participant
## How Group Chat Works
Mem0 automatically detects group chat scenarios when messages contain a `name` field:
```json
{
"role": "user",
"name": "Alice",
"content": "Hey team, I think we should use React for the frontend"
}
```
When names are present, Mem0:
- Formats messages as `"Alice (user): content"` for processing
- Extracts memories with proper attribution to each speaker
- Stores memories with the speaker's name as the `user_id` (for users) or `agent_id` (for assistants/agents)
### Memory Attribution Rules
- **User Messages**: The `name` field becomes the `user_id` in stored memories
- **Assistant/Agent Messages**: The `name` field becomes the `agent_id` in stored memories
- **Messages without names**: Fall back to standard processing using role as identifier
## Using Group Chat
### Basic Group Chat
Add memories from a multi-participant conversation:
<CodeGroup>
```python Python
from mem0 import MemoryClient
client = MemoryClient(api_key="your-api-key")
# Group chat with multiple users
messages = [
{"role": "user", "name": "Alice", "content": "Hey team, I think we should use React for the frontend"},
{"role": "user", "name": "Bob", "content": "I disagree, Vue.js would be better for our use case"},
{"role": "user", "name": "Charlie", "content": "What about considering Angular? It has great enterprise support"},
{"role": "assistant", "content": "All three frameworks have their merits. Let me summarize the pros and cons of each."}
]
response = client.add(
messages,
run_id="group_chat_1",
infer=True
)
print(response)
```
```json Output
{
"results": [
{
"id": "4d82478a-8d50-47e6-9324-1f65efff5829",
"event": "ADD",
"memory": "prefers using React for the frontend"
},
{
"id": "1d8b8f39-7b17-4d18-8632-ab1c64fa35b9",
"event": "ADD",
"memory": "prefers Vue.js for our use case"
},
{
"id": "147559a8-c5f7-44d0-9418-91f53f7a89a4",
"event": "ADD",
"memory": "suggests considering Angular because it has great enterprise support"
}
]
}
```
</CodeGroup>
## Retrieving Group Chat Memories
### Get All Memories for a Session
Retrieve all memories from a specific group chat session:
<CodeGroup>
```python Python
# Get all memories for a specific run_id
# Use wildcard "*" for user_id to match all participants
filters = {
"AND": [
{"user_id": "*"},
{"run_id": "group_chat_1"}
]
}
all_memories = client.get_all(filters=filters, page=1)
print(all_memories)
```
```json Output
{
"count": 3,
"next": null,
"previous": null,
"results": [
{
"id": "147559a8-c5f7-44d0-9418-91f53f7a89a4",
"memory": "suggests considering Angular because it has great enterprise support",
"user_id": "charlie",
"run_id": "group_chat_1",
"created_at": "2025-06-21T05:51:11.007223-07:00",
"updated_at": "2025-06-21T05:51:11.626562-07:00"
},
{
"id": "1d8b8f39-7b17-4d18-8632-ab1c64fa35b9",
"memory": "prefers Vue.js for our use case",
"user_id": "bob",
"run_id": "group_chat_1",
"created_at": "2025-06-21T05:51:08.675301-07:00",
"updated_at": "2025-06-21T05:51:09.319269-07:00"
},
{
"id": "4d82478a-8d50-47e6-9324-1f65efff5829",
"memory": "prefers using React for the frontend",
"user_id": "alice",
"run_id": "group_chat_1",
"created_at": "2025-06-21T05:51:05.943223-07:00",
"updated_at": "2025-06-21T05:51:06.982539-07:00"
}
]
}
```
</CodeGroup>
### Get Memories for a Specific Participant
Retrieve memories from a specific participant in a group chat:
<CodeGroup>
```python Python
# Get memories for a specific participant
filters = {
"AND": [
{"user_id": "charlie"},
{"run_id": "group_chat_1"}
]
}
charlie_memories = client.get_all(filters=filters, page=1)
print(charlie_memories)
```
```json Output
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "147559a8-c5f7-44d0-9418-91f53f7a89a4",
"memory": "suggests considering Angular because it has great enterprise support",
"user_id": "charlie",
"run_id": "group_chat_1",
"created_at": "2025-06-21T05:51:11.007223-07:00",
"updated_at": "2025-06-21T05:51:11.626562-07:00"
}
]
}
```
</CodeGroup>
### Search Within Group Chat Context
Search for specific information within a group chat session:
<CodeGroup>
```python Python
# Search within group chat context
filters = {
"AND": [
{"user_id": "charlie"},
{"run_id": "group_chat_1"}
]
}
search_response = client.search(
query="What are the tasks?",
filters=filters
)
print(search_response)
```
```json Output
{
"results": [
{
"id": "147559a8-c5f7-44d0-9418-91f53f7a89a4",
"memory": "suggests considering Angular because it has great enterprise support",
"user_id": "charlie",
"run_id": "group_chat_1",
"created_at": "2025-06-21T05:51:11.007223-07:00",
"updated_at": "2025-06-21T05:51:11.626562-07:00"
}
]
}
```
</CodeGroup>
## Async Mode Support
Group chat supports async processing for improved performance. Memory additions are processed asynchronously by default.
<CodeGroup>
```python Python
# Group chat: async processing is the default
response = client.add(
messages,
run_id="groupchat_async",
infer=True,
)
print(response)
```
</CodeGroup>
## Message Format Requirements
### Required Fields
Each message in a group chat must include:
- `role`: The participant's role (`"user"`, `"assistant"`, `"agent"`)
- `content`: The message content
- `name`: The participant's name (required for group chat detection)
### Example Message Structure
```json
{
"role": "user",
"name": "Alice",
"content": "I think we should use React for the frontend"
}
```
### Supported Roles
- **`user`**: Human participants (memories stored with `user_id`)
- **`assistant`**: AI assistants (memories stored with `agent_id`)
## Best Practices
1. **Consistent Naming**: Use consistent names for participants across sessions to maintain proper memory attribution.
2. **Clear Role Assignment**: Ensure each participant has the correct role (`user`, `assistant`, or `agent`) for proper memory categorization.
3. **Session Management**: Use meaningful `run_id` values to organize group chat sessions and enable easy retrieval.
4. **Memory Filtering**: Use filters to retrieve memories from specific participants or sessions when needed.
5. **Async Processing**: Memory additions are processed asynchronously by default, which is ideal for large group conversations.
6. **Search Context**: Leverage the search functionality to find specific information within group chat contexts.
## Use Cases
- **Team Meetings**: Track individual team member preferences and contributions
- **Customer Support**: Maintain separate memory profiles for different customers
- **Multi-Agent Systems**: Manage conversations with multiple AI assistants
- **Collaborative Projects**: Track individual preferences and expertise areas
- **Group Discussions**: Maintain context for each participant's viewpoints
If you have any questions, please feel free to reach out to us using one of the following methods:
<Snippet file="get-help.mdx" />
+191
View File
@@ -0,0 +1,191 @@
---
title: Memory Decay
description: "Boost recently-used memories and gently dampen stale ones at search time, without filtering anything out."
---
# Memory Decay
Older memories drift in relevance at different speeds. A user's coffee order matters every morning; a one-off project name from last quarter rarely matters again. Memory Decay makes that intuition explicit at search time: every time a memory is returned in a search it gets a small reinforcement, and memories that haven't been touched in a while have their ranking score gently dampened.
It is **a soft ranking bias, never a filter.** Decay never zeroes a candidate out: at worst it scales its score by `0.3×`. Anything that would have surfaced without decay can still surface with decay on, just with a different ranking among similarly-scored results.
<Info>
**Use Memory Decay when…**
- Search results are crowded with old facts the user no longer cares about.
- You want recently-used memories to drift to the top automatically: without writing custom scoring logic.
- You want this preference applied per project so cohorts can be compared side-by-side.
</Info>
<Warning>
Memory Decay is **opt-in per project** and **off by default**. Search behavior is bit-identical to today until you turn it on. The toggle applies to v3 search only.
</Warning>
## How it works
Every memory carries a small piece of bookkeeping: when was it last retrieved, and how often. Memory Decay turns that history into a *scaling factor* in the range `0.3×` to `1.5×` and multiplies it into the ranking score at search time.
| Memory state | Scaling factor | Ranking effect |
|---|---|---|
| Just accessed | ≈ **1.5×** | Strong boost |
| Touched today | 1.2 1.4× | Mild boost |
| Idle for a few days | 0.6 1.0× | Mild dampening |
| Idle for weeks | 0.4 0.6× | Stronger dampening |
| Idle for many months / years | ≈ **0.3×** | Floor: never lower |
The bounds matter: `0.3` is the floor and `1.5` is the ceiling, so decay can meaningfully reorder candidates without ever dominating the underlying relevance score.
At search time the pipeline:
1. Widens the candidate pool (`top_k × 3`, with a floor of 50) so reordering has room.
2. Multiplies each candidate's score by its scaling factor.
3. Sorts on the unclamped product so the full `0.3×–1.5×` range can rearrange candidates.
4. Returns the public `score` clamped to `[0, 1]` so the API contract is preserved.
5. Truncates to the `top_k` you requested.
6. Records a fire-and-forget reinforcement against each returned memory: its access history grows by one, capped at the most recent 20 touches.
Memories created before decay was enabled don't yet have an access history. They use a sensible fallback: their `updated_at` is treated as a single past touch, so the same scale above applies based on how stale that update is: a recently-updated legacy memory enters near the neutral band, a long-stale one sits closer to the floor. Once surfaced in a search after decay is on, they accumulate access history naturally and behave like any other memory.
## Configure access
- Set `MEM0_API_KEY` in your environment, or pass it to the SDK constructor.
- Initialize the client with the organization and project you want to scope to.
The toggle lives on the project. You enable decay by patching the project's `decay` field; everything else: your `add` calls, your `search` calls, your application code: stays exactly the same.
## Enable decay for a project
### 1. Turn the flag on
The toggle is exposed on the standard project-update endpoint, the same place where `multilingual` and `custom_categories` live.
<CodeGroup>
```python Python
client.project.update(decay=True)
```
```javascript JavaScript
await client.project.update({ decay: true });
```
```bash cURL
curl -X PATCH https://api.mem0.ai/api/v1/orgs/organizations/$ORG_ID/projects/$PROJECT_ID/ \
-H "Authorization: Token $MEM0_API_KEY" \
-H "Content-Type: application/json" \
-d '{"decay": true}'
```
```json Response
{ "message": "Updated decay" }
```
</CodeGroup>
### 2. Confirm the state
`decay` is returned on every project read. To fetch only this field, use `?fields=decay`.
<CodeGroup>
```python Python
response = client.project.get(fields=["decay"])
print(response["decay"])
```
```javascript JavaScript
const response = await client.project.get({ fields: ["decay"] });
console.log(response.decay);
```
```bash cURL
curl "https://api.mem0.ai/api/v1/orgs/organizations/$ORG_ID/projects/$PROJECT_ID/?fields=decay" \
-H "Authorization: Token $MEM0_API_KEY"
```
```json Response
{ "decay": true }
```
</CodeGroup>
### 3. Turn it back off
The toggle is fully reversible. Setting it to `false` immediately restores the pre-decay ranking; nothing about your stored memories is modified or lost.
<CodeGroup>
```python Python
client.project.update(decay=False)
```
```javascript JavaScript
await client.project.update({ decay: false });
```
```bash cURL
curl -X PATCH https://api.mem0.ai/api/v1/orgs/organizations/$ORG_ID/projects/$PROJECT_ID/ \
-H "Authorization: Token $MEM0_API_KEY" \
-H "Content-Type: application/json" \
-d '{"decay": false}'
```
</CodeGroup>
<Note>
The toggle is idempotent. Re-applying the same value is a no-op, and access history accumulated while decay was on is preserved if you flip it back on later.
</Note>
## What changes when decay is on
- **Search ranking reorders.** A relevant memory you reinforced an hour ago will tend to outrank an equally-relevant memory that was last touched a month ago.
- **The candidate pool over-fetches** to give the scaling factor room to reorder. You still get exactly the `top_k` you requested, but the items returned can come from a deeper slice of the pre-decay ranking than before.
- **The public `score` field stays in `[0, 1]`.** Even when the internal product exceeds 1, the field returned to the client is clamped, so existing assertions and downstream UI logic continue to work.
## What stays the same
- **Public API shape**: every endpoint accepts the same parameters and returns the same fields. You don't touch your client code.
- **Threshold semantics on the request side**: your `threshold` is still applied during candidate selection.
- **Memory creation and storage**: every new memory still lands the same way. Decay is a search-time concern.
- **Per-memory data**: categories, metadata, timestamps, embeddings: untouched.
<Warning>
Because the scaling factor is applied *after* the threshold filter has already run, an item that passed the request `threshold` can come back with a public `score` slightly below it (a stale candidate dampened by `0.3×`). This is intentional: decay is a soft bias, not a filter. If you require a hard `score >= threshold` invariant on the response, filter client-side after the call.
</Warning>
## Lifecycle of a memory under decay
| Stage | Scaling factor | Effect |
|---|---|---|
| Just added | ≈ 1.5× | Strong boost: fresh facts surface easily. |
| Reinforced on a recent search | 1.2 1.5× | Sustains its boost for the next several searches. |
| Idle for a few days | 0.6 1.0× | Falls back into the neutral band. |
| Idle for weeks | 0.4 0.6× | Mild dampening: can still surface for strong matches. |
| Pre-decay legacy memory (no access history) | 0.3 1.0× | Falls back to `updated_at`: recently-updated entries land near 1.0×, long-stale entries approach the 0.3× floor. |
The reinforcement is bounded: each memory tracks at most the last 20 access timestamps, so the boost stays well-behaved no matter how many times a memory is retrieved.
## FAQ
**Will decay ever drop a result that would otherwise surface?**
No. The floor is `0.3×`: the scaling factor can dampen a score, never zero it. Threshold filtering happens *before* decay, so any candidate that cleared the threshold is in the pool decay reorders.
**Why is the public score sometimes below my requested threshold?**
The threshold is applied to the candidate pool pre-decay; the scaling factor then reshapes scores in the `0.3×–1.5×` band. A stale-but-relevant candidate can come back with a final score slightly under your threshold by design: the candidate stays visible but visibly dampened. Filter client-side if you need a hard floor on the response.
**Does decay change how I add memories?**
No. The `client.add(...)` path is unchanged. Decay is a search-time ranking adjustment.
**What if I had memories before turning decay on?**
They use a fallback: the memory's `updated_at` is treated as a single historical touch, so the same scaling applies based on how stale that update is: a recently-updated legacy memory enters near the neutral band (~1.0×), a long-stale one closer to the floor (~0.3×). Once retrieved they accumulate access history and behave like any other memory.
**Can I tune how aggressively decay scales scores?**
Not in this version. The current scaling is calibrated to be conservative: wide enough to meaningfully reorder candidates, narrow enough to never dominate the underlying relevance score. Per-project tuning is on the roadmap.
**Can I see the scaling factor per result?**
Internal scoring details are persisted on the search Event for support and debugging. They aren't exposed in the public response by design: the response surface stays a single `score` field.
**Does decay interact with reranking?**
Yes: they layer cleanly. The reranker produces a richer relevance score; decay then biases that score by reinforcement history before final truncation to `top_k`.
## What's next
This release is deliberately the simplest version of decay we could ship: every memory contributes to ranking through its access history alone, so the signal can be evaluated in isolation. On the roadmap:
- **Category-aware weighting.** A fact tagged `health` will be able to carry more weight than a passing observation tagged `misc`, so important categories don't get dampened the same way as noise.
- **Auto-tuning per project.** Project-scoped automatic adjustment of how aggressively decay scales scores, based on observed access patterns: replacing the fixed scaling band with one that fits your workload.
Both extensions are forward-compatible: no migration on your side will be needed when they ship.
@@ -0,0 +1,175 @@
---
title: Memory Expiration
description: "Give a memory a shelf life: set an expiration date and it stops surfacing in search once that date passes, without deleting the record."
---
# Memory Expiration
Some facts are only true for a while. A trial plan ends, a seasonal preference goes stale, a support ticket ages past its retention window. Set an `expiration_date` on a memory and Mem0 stops surfacing it once that date passes, so you don't need a cleanup job hunting for rows to delete.
**Expiration hides a memory, it does not delete it.** The record stays in storage untouched. `search()` and `get_all()` skip it, fetching it by ID still returns it, and clearing the date brings it straight back.
## How it works
- **Format**: a plain `YYYY-MM-DD` date. No time component, no timezone offset.
- **Evaluated in UTC**, never against the caller's local timezone.
- **Inclusive of the date itself**: a memory set to expire on `2030-01-31` stays visible all through `2030-01-31` UTC and disappears on `2030-02-01`.
- **Only list-shaped reads filter**: `search()` and `get_all()` (`getAll()` in TypeScript) hide expired memories. <Link href="/api-reference/memory/get-memory">`get(memory_id)`</Link> always returns the memory, so there is no `show_expired` parameter on that path.
- **No expiration date means never expires.** That is the default for every memory.
- **Malformed dates fail open**: a stored value Mem0 can't parse is treated as *not* expired. A bad date never makes a memory silently vanish.
## Set an expiration date
Set it when you add the memory:
<CodeGroup>
```python Python
# Mem0 Platform
from mem0 import MemoryClient
client = MemoryClient(api_key="your-api-key")
messages = [{"role": "user", "content": "My Pro trial ends soon."}]
client.add(messages, user_id="alice", expiration_date="2030-01-31")
# Mem0 OSS
from mem0 import Memory
memory = Memory()
memory.add(messages, user_id="alice", expiration_date="2030-01-31")
```
```javascript JavaScript
// Mem0 Platform
import { MemoryClient } from "mem0ai";
const client = new MemoryClient({ apiKey: "your-api-key" });
const messages = [{ role: "user", content: "My Pro trial ends soon." }];
await client.add(messages, { userId: "alice", expirationDate: "2030-01-31" });
// Mem0 OSS
import { Memory } from "mem0ai/oss";
const memory = new Memory();
await memory.add(messages, { userId: "alice", expirationDate: "2030-01-31" });
```
</CodeGroup>
Or attach it to a memory that already exists, using `update()`:
<CodeGroup>
```python Python
client.update("mem_123", expiration_date="2030-01-31") # Platform
memory.update("mem_123", expiration_date="2030-01-31") # OSS
```
```javascript JavaScript
await client.update("mem_123", { expirationDate: "2030-01-31" }); // Platform
await memory.update("mem_123", { expirationDate: "2030-01-31" }); // OSS
```
</CodeGroup>
Full field lists live in the <Link href="/api-reference/memory/add-memories">Add Memories</Link> and <Link href="/api-reference/memory/update-memory">Update Memory</Link> references.
## Read expired memories back
Pass `show_expired` (`showExpired` in TypeScript) to include them. It defaults to `false` on every client.
<CodeGroup>
```python Python
client.get_all(filters={"user_id": "alice"}, show_expired=True)
client.search("What plan is Alice on?", filters={"user_id": "alice"}, show_expired=True)
```
```javascript JavaScript
await client.getAll({ filters: { user_id: "alice" }, showExpired: true });
await client.search("What plan is Alice on?", {
filters: { user_id: "alice" },
showExpired: true,
});
```
</CodeGroup>
The same parameter and spelling work on the OSS `Memory` class. See <Link href="/api-reference/memory/search-memories">Search Memories</Link> and <Link href="/api-reference/memory/get-memories">Get Memories</Link>.
<Note>
Expired memories are dropped *before* your `top_k` is applied, so Mem0 widens the internal candidate pool first and short result sets are rare. They are not impossible: if nearly every memory in a scope has expired, a call can still return fewer than `top_k` results. Pass `show_expired: true` to get the full set back.
</Note>
## Clear an expiration date
Pass an explicit `None` (Python) or `null` (TypeScript) to make the memory permanent again. The SDKs deliberately preserve that null instead of treating it as "argument not supplied".
<CodeGroup>
```python Python
client.update("mem_123", expiration_date=None) # Platform
memory.update("mem_123", expiration_date=None) # OSS
```
```javascript JavaScript
await client.update("mem_123", { expirationDate: null }); // Platform
await memory.update("mem_123", { expirationDate: null }); // OSS
```
</CodeGroup>
<Note>
`update()` needs at least one of `text`, `metadata`, or `expiration_date`, and raises if you pass none of them. Clearing the date satisfies that on its own: the memory's content and metadata are left alone.
</Note>
## What each client accepts
| Client | Accepted input | Notes |
| --- | --- | --- |
| Python (Platform and OSS) | `str` in `YYYY-MM-DD` form, or a `date` / `datetime` object | Normalized to `YYYY-MM-DD` before storage. |
| TypeScript (Platform and OSS) | `string` in `YYYY-MM-DD` form only | Stricter than `new Date()`: rejects `12/31/2099`, `2099-12-31T23:00:00`, and non-days like `2099-02-30` or `2100-02-29`. |
| Self-hosted REST server | `string` in `YYYY-MM-DD` form | Same normalization as OSS Python underneath. |
| CLI (`mem0 add --expires`) | `string` in `YYYY-MM-DD` form | Must be strictly in the future, checked against the local system date. The SDKs have no such restriction. Platform only: the CLI has no OSS backend. |
## Reading the field back
Most clients return expiration as a top-level field on the memory: `expiration_date` in Python (Platform and OSS) and in the REST API, `expirationDate` in the Platform TypeScript SDK.
<Info>
The OSS TypeScript SDK is the one exception. There, expiration round-trips under **`result.metadata.expiration_date`**, not `result.expirationDate`, on both `get()` and `getAll()`.
</Info>
## Expiration, decay, and delete
These three get conflated. They solve different problems:
| | Memory Expiration | Memory Decay | Delete |
| --- | --- | --- | --- |
| What it does | Hides a memory once a date you set passes | Re-ranks results by how recently a memory was used | Removes a memory permanently |
| Data still stored? | Yes | Yes | No |
| Filters results? | Yes, after the date | Never, it only reorders scores | Yes, permanently |
| Reversible? | Yes, clear or push back the date | Yes, toggle `decay` off | No |
| Set where | Per memory, by you | Per project, opt-in | Per call |
| Available in | Platform and OSS | Platform only | Platform and OSS |
Reach for <Link href="/platform/features/memory-decay">Memory Decay</Link> when old memories should rank lower but stay searchable, expiration when a memory should stop appearing after a specific known date, and <Link href="/core-concepts/memory-operations/delete">Delete</Link> when it should be gone for good.
## Common patterns
**Trial and subscription facts.** "Alice is on the Pro trial" is true until the trial ends. Set `expiration_date` to that end date when you write the fact. If she upgrades, clear the date and the memory becomes permanent. If she doesn't, it stops surfacing the next day on its own.
**Seasonal preferences.** "Alex wants gift ideas for the holidays" matters in December and is noise in July. A short-lived expiration date keeps it from competing with evergreen preferences in every search.
**Retention windows.** Data-retention policies usually want a soft window before a hard delete: keep a ticket's memories searchable for 90 days, stop surfacing them, purge them later on a schedule. Expiration is the soft step, and a scheduled <Link href="/core-concepts/memory-operations/delete">delete</Link> is the permanent one.
<CardGroup cols={2}>
<Card
title="Memory Decay"
description="Rank stale memories lower instead of hiding them outright."
icon="chart-line"
href="/platform/features/memory-decay"
/>
<Card
title="Delete Memories"
description="Remove memories permanently instead of hiding them."
icon="trash"
href="/core-concepts/memory-operations/delete"
/>
</CardGroup>
<Snippet file="get-help.mdx" />
+262
View File
@@ -0,0 +1,262 @@
---
title: Memory Export
description: 'Export memories in a structured format using customizable Pydantic schemas'
---
## Overview
The Memory Export feature allows you to create structured exports of memories using customizable Pydantic schemas. This process enables you to transform your stored memories into specific data formats that match your needs. You can apply various filters to narrow down which memories to export and define exactly how the data should be structured.
## Creating a Memory Export
To create a memory export, you'll need to:
1. Define your schema structure
2. Submit an export job
3. Retrieve the exported data
### Define Schema
Here's an example schema for extracting professional profile information:
```json
{
"$defs": {
"EducationLevel": {
"enum": ["high_school", "bachelors", "masters"],
"title": "EducationLevel",
"type": "string"
},
"EmploymentStatus": {
"enum": ["full_time", "part_time", "student"],
"title": "EmploymentStatus",
"type": "string"
}
},
"properties": {
"full_name": {
"anyOf": [
{
"maxLength": 100,
"minLength": 2,
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The professional's full name",
"title": "Full Name"
},
"current_role": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Current job title or role",
"title": "Current Role"
}
},
"title": "ProfessionalProfile",
"type": "object"
}
```
### Submit Export Job
You can optionally provide additional instructions to guide how memories are processed and structured during export using the `export_instructions` parameter.
<CodeGroup>
```python Python
# Basic export request
filters = {"user_id": "alice"}
response = client.create_memory_export(
schema=json_schema,
filters=filters
)
# Export with custom instructions and additional filters
export_instructions = """
1. Create a comprehensive profile with detailed information in each category
2. Only mark fields as "None" when absolutely no relevant information exists
3. Base all information directly on the user's memories
4. When contradictions exist, prioritize the most recent information
5. Clearly distinguish between factual statements and inferences
"""
filters = {
"AND": [
{"user_id": "alex"},
{"created_at": {"gte": "2024-01-01"}}
]
}
response = client.create_memory_export(
schema=json_schema,
filters=filters,
export_instructions=export_instructions # Optional
)
print(response)
```
```javascript JavaScript
// Basic Export request
const basicFilters = {"user_id": "alice"};
const response = await client.createMemoryExport({
schema: json_schema,
filters: basicFilters
});
// Export with custom instructions and additional filters
const export_instructions = `
1. Create a comprehensive profile with detailed information in each category
2. Only mark fields as "None" when absolutely no relevant information exists
3. Base all information directly on the user's memories
4. When contradictions exist, prioritize the most recent information
5. Clearly distinguish between factual statements and inferences
`;
// For create operation, using only user_id filter as requested
const exportFilters = {
"AND": [
{"user_id": "alex"},
{"created_at": {"gte": "2024-01-01"}}
]
};
const responseWithInstructions = await client.createMemoryExport({
schema: json_schema,
filters: exportFilters,
exportInstructions: export_instructions
});
console.log(responseWithInstructions);
```
```bash cURL
curl -X POST "https://api.mem0.ai/v1/memories/export/" \
-H "Authorization: Token your-api-key" \
-H "Content-Type: application/json" \
-d '{
"schema": {json_schema},
"filters": {"user_id": "alice"},
"export_instructions": "1. Create a comprehensive profile with detailed information\n2. Only mark fields as \"None\" when absolutely no relevant information exists"
}'
```
```json Output
{
"message": "Memory export request received. The export will be ready in a few seconds.",
"id": "550e8400-e29b-41d4-a716-446655440000"
}
```
</CodeGroup>
### Retrieve Export
Once the export job is complete, you can retrieve the structured data in two ways:
#### Using Export ID
<CodeGroup>
```python Python
# Retrieve using export ID
response = client.get_memory_export(memory_export_id="550e8400-e29b-41d4-a716-446655440000")
print(response)
```
```javascript JavaScript
// Retrieve using export ID
const memoryExportId = "550e8400-e29b-41d4-a716-446655440000";
const response = await client.getMemoryExport({
memoryExportId: memoryExportId
});
console.log(response);
```
```json Output
{
"full_name": "John Doe",
"current_role": "Senior Software Engineer",
"years_experience": 8,
"employment_status": "full_time",
"education_level": "masters",
"skills": ["Python", "AWS", "Machine Learning"]
}
```
</CodeGroup>
#### Using Filters
<CodeGroup>
```python Python
# Retrieve using filters
filters = {
"AND": [
{"created_at": {"gte": "2024-07-10", "lte": "2024-07-20"}},
{"user_id": "alex"}
]
}
response = client.get_memory_export(filters=filters)
print(response)
```
```javascript JavaScript
// Retrieve using filters
const filters = {
"AND": [
{"created_at": {"gte": "2024-07-10", "lte": "2024-07-20"}},
{"user_id": "alex"}
]
}
const response = await client.getMemoryExport({
filters: filters
});
console.log(response);
```
```json Output
{
"full_name": "John Doe",
"current_role": "Senior Software Engineer",
"years_experience": 8,
"employment_status": "full_time",
"education_level": "masters",
"skills": ["Python", "AWS", "Machine Learning"]
}
```
</CodeGroup>
## Available Filters
You can apply various filters to customize which memories are included in the export:
- `user_id`: Filter memories by specific user
- `agent_id`: Filter memories by specific agent
- `run_id`: Filter memories by specific run
- `created_at`: Filter memories by date
<Note>
The export process may take some time to complete, especially when dealing with a large number of memories or complex schemas.
</Note>
If you have any questions, please feel free to reach out to us using one of the following methods:
<Snippet file="get-help.mdx" />
@@ -0,0 +1,303 @@
---
title: Multimodal Support
description: Integrate images and documents into your interactions with Mem0
---
Mem0 extends its capabilities beyond text by supporting multimodal data, including images and documents. With this feature, users can seamlessly integrate visual and document content into their interactions, allowing Mem0 to extract relevant information from various media types and enrich the memory system.
## How It Works
When a user submits an image or document, Mem0 processes it to extract textual information and other pertinent details. These details are then added to the user's memory, enhancing the system's ability to understand and recall multimodal inputs.
<CodeGroup>
```python Python
import os
from mem0 import MemoryClient
os.environ["MEM0_API_KEY"] = "your-api-key"
client = MemoryClient()
messages = [
{
"role": "user",
"content": "Hi, my name is Alice."
},
{
"role": "assistant",
"content": "Nice to meet you, Alice! What do you like to eat?"
},
{
"role": "user",
"content": {
"type": "image_url",
"image_url": {
"url": "https://www.superhealthykids.com/wp-content/uploads/2021/10/best-veggie-pizza-featured-image-square-2.jpg"
}
}
},
]
# Calling the add method to ingest messages into the memory system
client.add(messages, user_id="alice")
```
```typescript TypeScript
import MemoryClient from "mem0ai";
const client = new MemoryClient();
const messages = [
{
role: "user",
content: "Hi, my name is Alice."
},
{
role: "assistant",
content: "Nice to meet you, Alice! What do you like to eat?"
},
{
role: "user",
content: {
type: "image_url",
image_url: {
url: "https://www.superhealthykids.com/wp-content/uploads/2021/10/best-veggie-pizza-featured-image-square-2.jpg"
}
}
},
]
await client.add(messages, { userId: "alice" })
```
```json Output
{
"results": [
{
"memory": "Name is Alice",
"event": "ADD",
"id": "7ae113a3-3cb5-46e9-b6f7-486c36391847"
},
{
"memory": "Likes large pizza with toppings including cherry tomatoes, black olives, green spinach, yellow bell peppers, diced ham, and sliced mushrooms",
"event": "ADD",
"id": "56545065-7dee-4acf-8bf2-a5b2535aabb3"
}
]
}
```
</CodeGroup>
## Supported Media Types
Mem0 currently supports the following media types:
1. **Images** - JPG, PNG, and other common image formats
2. **Documents** - MDX, TXT, and PDF files
## Integration Methods
### 1. Images
#### Using an Image URL
You can include an image by providing its direct URL. This method is simple and efficient for online images.
```python {2, 5-13}
# Define the image URL
image_url = "https://www.superhealthykids.com/wp-content/uploads/2021/10/best-veggie-pizza-featured-image-square-2.jpg"
# Create the message dictionary with the image URL
image_message = {
"role": "user",
"content": {
"type": "image_url",
"image_url": {
"url": image_url
}
}
}
client.add([image_message], user_id="alice")
```
#### Using Base64 Image Encoding for Local Files
For local images or when embedding the image directly is preferable, you can use a Base64-encoded string.
<CodeGroup>
```python Python
import base64
# Path to the image file
image_path = "path/to/your/image.jpg"
# Encode the image in Base64
with open(image_path, "rb") as image_file:
base64_image = base64.b64encode(image_file.read()).decode("utf-8")
# Create the message dictionary with the Base64-encoded image
image_message = {
"role": "user",
"content": {
"type": "image_url",
"image_url": {
"url": f"data:image/jpeg;base64,{base64_image}"
}
}
}
client.add([image_message], user_id="alice")
```
```typescript TypeScript
import MemoryClient from "mem0ai";
import fs from 'fs';
const imagePath = 'path/to/your/image.jpg';
const base64Image = fs.readFileSync(imagePath, { encoding: 'base64' });
const imageMessage = {
role: "user",
content: {
type: "image_url",
image_url: {
url: `data:image/jpeg;base64,${base64Image}`
}
}
};
await client.add([imageMessage], { userId: "alice" })
```
</CodeGroup>
### 2. Text Documents (MDX/TXT)
Mem0 supports both online and local text documents in MDX or TXT format.
#### Using a Document URL
```python
# Define the document URL
document_url = "https://www.w3.org/TR/2003/REC-PNG-20031110/iso_8859-1.txt"
# Create the message dictionary with the document URL
document_message = {
"role": "user",
"content": {
"type": "mdx_url",
"mdx_url": {
"url": document_url
}
}
}
client.add([document_message], user_id="alice")
```
#### Using Base64 Encoding for Local Documents
```python
import base64
# Path to the document file
document_path = "path/to/your/document.txt"
# Function to convert file to Base64
def file_to_base64(file_path):
with open(file_path, "rb") as file:
return base64.b64encode(file.read()).decode('utf-8')
# Encode the document in Base64
base64_document = file_to_base64(document_path)
# Create the message dictionary with the Base64-encoded document
document_message = {
"role": "user",
"content": {
"type": "mdx_url",
"mdx_url": {
"url": base64_document
}
}
}
client.add([document_message], user_id="alice")
```
### 3. PDF Documents
Mem0 supports PDF documents via URL.
```python
# Define the PDF URL
pdf_url = "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
# Create the message dictionary with the PDF URL
pdf_message = {
"role": "user",
"content": {
"type": "pdf_url",
"pdf_url": {
"url": pdf_url
}
}
}
client.add([pdf_message], user_id="alice")
```
## Complete Example with Multiple File Types
Here's a comprehensive example showing how to work with different file types:
```python
import base64
from mem0 import MemoryClient
client = MemoryClient()
def file_to_base64(file_path):
with open(file_path, "rb") as file:
return base64.b64encode(file.read()).decode('utf-8')
# Example 1: Using an image URL
image_message = {
"role": "user",
"content": {
"type": "image_url",
"image_url": {
"url": "https://example.com/sample-image.jpg"
}
}
}
# Example 2: Using a text document URL
text_message = {
"role": "user",
"content": {
"type": "mdx_url",
"mdx_url": {
"url": "https://www.w3.org/TR/2003/REC-PNG-20031110/iso_8859-1.txt"
}
}
}
# Example 3: Using a PDF URL
pdf_message = {
"role": "user",
"content": {
"type": "pdf_url",
"pdf_url": {
"url": "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
}
}
}
# Add each message to the memory system
client.add([image_message], user_id="alice")
client.add([text_message], user_id="alice")
client.add([pdf_message], user_id="alice")
```
Using these methods, you can seamlessly incorporate various media types into your interactions, further enhancing Mem0's multimodal capabilities.
If you have any questions, please feel free to reach out to us using one of the following methods:
<Snippet file="get-help.mdx" />
@@ -0,0 +1,144 @@
---
title: Temporal Reasoning
description: "Time-aware memory retrieval for Mem0 Platform v3 so queries like 'last week', 'upcoming', and 'right now' return the right memories."
badge: "v3"
---
Some memories matter because of **when** they happened, not just because they sound similar. Temporal Reasoning lets Mem0 Platform v3 understand time-aware queries and return the most contextually appropriate results.
<Info>
**Use Temporal Reasoning when…**
- Users ask questions like "what happened last week?" or "what do I have coming up?"
- Your app stores both past events and future plans for the same person
- You want time-aware retrieval without building your own date-parsing layer
</Info>
<Warning>
Temporal Reasoning is a **Mem0 Platform v3** feature. It is not available on OSS memory stores or older Platform endpoints.
</Warning>
## Configure access
Confirm your `MEM0_API_KEY` is set and that you are using the v3 Platform client:
```python
from mem0 import MemoryClient
client = MemoryClient(api_key="your-api-key")
```
## How it works
When a memory describes an event, a future plan, or an ongoing state, Temporal Reasoning recognizes the time context so the right results surface at search time.
A query like `what did I do last week?` should return a completed past event: not an upcoming appointment and not a stable fact that hasn't changed. Temporal Reasoning handles that distinction automatically.
### Memory types Temporal Reasoning handles
| Type | What it represents | Example |
| --- | --- | --- |
| Dated occurrence | Something that happened at a known time | "I finished the Q1 review on March 10, 2025." |
| Future plan | A future commitment or scheduled item | "I have a dentist appointment on March 18, 2025." |
| Ongoing state | A fact that remains true over time | "I am the product lead at Acme Corp." |
| Relationship | A durable connection between people or entities | "Priya manages Jordan." |
| Preference | A stable preference or habit | "I prefer morning meetings." |
Results come back in the normal search response shape: Temporal Reasoning affects ranking, not the response format.
## Configure it
Temporal Reasoning is enabled by default for all v3 searches and writes. There is no per-request toggle.
Two parameters give you precise control when you need it:
- `timestamp` on `add()`: anchors an imported memory to the time it actually happened, rather than the time it was added to Mem0
- `reference_date` on `search()`: resolves relative phrases like `last week` against a fixed point in time
<CodeGroup>
```python Python
from datetime import datetime, timezone
from mem0 import MemoryClient
client = MemoryClient(api_key="your-api-key")
# Import a historical memory anchored to when it happened
client.add(
[{"role": "user", "content": "I finished the Q1 review on March 10, 2025."}],
user_id="jordan",
timestamp=int(datetime(2025, 3, 10, tzinfo=timezone.utc).timestamp()),
)
# Search with a relative query anchored to a known date
results = client.search(
"what did I do last week?",
filters={"user_id": "jordan"},
reference_date="2025-03-21T00:00:00Z",
)
```
```javascript JavaScript
import { MemoryClient } from "mem0ai";
const client = new MemoryClient({ apiKey: "your-api-key" });
// Import a historical memory anchored to when it happened
await client.add(
[{ role: "user", content: "I finished the Q1 review on March 10, 2025." }],
{
userId: "jordan",
timestamp: Math.floor(new Date("2025-03-10T00:00:00Z").getTime() / 1000),
}
);
// Search with a relative query anchored to a known date
const results = await client.search("what did I do last week?", {
filters: { user_id: "jordan" },
referenceDate: "2025-03-21T00:00:00Z",
});
```
</CodeGroup>
<Tip>
`reference_date` is especially useful in automated tests and demos because it makes relative phrases like `last week` resolve consistently every time.
</Tip>
## Supported query patterns
<AccordionGroup>
<Accordion title="Historical questions">
Examples: `last week`, `last month`, `in March 2025`, `on 2025-03-10`
</Accordion>
<Accordion title="Upcoming questions">
Examples: `upcoming`, `next week`, `tomorrow`, `what do I have coming up?`
</Accordion>
<Accordion title="Current-state questions">
Examples: `right now`, `currently`, `where do I work now?`
</Accordion>
<Accordion title="As-of questions">
Examples: `as of March 2025`, `where was I living as of 2024?`
</Accordion>
<Accordion title="Duration questions">
Examples: `how long have I lived here?`, `since when have I worked there?`
</Accordion>
</AccordionGroup>
## Verify the feature is working
- Run a temporal search with a time-aware query (e.g., "what did I do last week?") and confirm the memory that fits the time window ranks first.
- Use `reference_date` in test queries so relative phrases resolve consistently across runs.
- For backfilled data, pass `timestamp` on `add()` to confirm the memory reflects the right point in time.
## Best practices
- Use explicit dates in source conversations when events or plans matter temporally.
- Pass `timestamp` during historical imports so the ingestion time does not become the only time anchor.
- Scope searches with `filters` so time-aware ranking operates inside the right user boundary.
- Use `reference_date` in automated tests and reproducible demos.
<CardGroup cols={1}>
<Card title="Memory Timestamps" icon="calendar" href="/platform/features/timestamp">
Anchor imported memories to when they actually happened.
</Card>
</CardGroup>
<Snippet file="get-help.mdx" />
+143
View File
@@ -0,0 +1,143 @@
---
title: Memory Timestamps
description: 'Add timestamps to your memories to maintain chronological accuracy and historical context'
---
## Overview
The Memory Timestamps feature allows you to specify when a memory was created, regardless of when it's actually added to the system. This powerful capability enables you to:
- Maintain accurate chronological ordering of memories
- Import historical data with proper timestamps
- Create memories that reflect when events actually occurred
- Build timelines with precise temporal information
By leveraging custom timestamps, you can ensure that your memory system maintains an accurate representation of when information was generated or events occurred.
## Benefits of Custom Timestamps
Custom timestamps offer several important benefits:
- **Historical Accuracy**: Preserve the exact timing of past events and information.
- **Data Migration**: Seamlessly migrate existing data while maintaining original timestamps.
- **Time-Sensitive Analysis**: Enable time-based analysis and pattern recognition across memories.
- **Consistent Chronology**: Maintain proper ordering of memories for coherent storytelling.
## Using Custom Timestamps
When adding new memories, you can specify a custom timestamp to indicate when the memory was created. This timestamp will be used instead of the current time.
### Adding Memories with Custom Timestamps
<CodeGroup>
```python Python
import os
import time
from datetime import datetime, timedelta
from mem0 import MemoryClient
os.environ["MEM0_API_KEY"] = "your-api-key"
client = MemoryClient()
# Get the current time
current_time = datetime.now()
# Calculate 5 days ago
five_days_ago = current_time - timedelta(days=5)
# Convert to Unix timestamp (seconds since epoch)
unix_timestamp = int(five_days_ago.timestamp())
# Add memory with custom timestamp
messages = [
{"role": "user", "content": "I'm travelling to SF"}
]
client.add(messages, user_id="user1", timestamp=unix_timestamp)
```
```javascript JavaScript
import MemoryClient from 'mem0ai';
const client = new MemoryClient({ apiKey: 'your-api-key' });
// Get the current time
const currentTime = new Date();
// Calculate 5 days ago
const fiveDaysAgo = new Date();
fiveDaysAgo.setDate(currentTime.getDate() - 5);
// Convert to Unix timestamp (seconds since epoch)
const unixTimestamp = Math.floor(fiveDaysAgo.getTime() / 1000);
// Add memory with custom timestamp
const messages = [
{"role": "user", "content": "I'm travelling to SF"}
]
client.add(messages, { userId: "user1", timestamp: unixTimestamp })
.then(response => console.log(response))
.catch(error => console.error(error));
```
```bash cURL
curl -X POST "https://api.mem0.ai/v1/memories/" \
-H "Authorization: Token your-api-key" \
-H "Content-Type: application/json" \
-d '{
"messages": [{"role": "user", "content": "I'm travelling to SF"}],
"user_id": "user1",
"timestamp": 1721577600
}'
```
```json Output
{
"results": [
{
"id": "a1b2c3d4-e5f6-4g7h-8i9j-k0l1m2n3o4p5",
"data": {"memory": "Travelling to SF"},
"event": "ADD"
}
]
}
```
</CodeGroup>
### Timestamp Format
When specifying a custom timestamp, you should provide a Unix timestamp (seconds since epoch). This is an integer representing the number of seconds that have elapsed since January 1, 1970 (UTC).
For example, to create a memory with a timestamp of January 1, 2023:
<CodeGroup>
```python Python
# January 1, 2023 timestamp
january_2023_timestamp = 1672531200 # Unix timestamp for 2023-01-01 00:00:00 UTC
messages = [
{"role": "user", "content": "I'm travelling to SF"}
]
client.add(messages, user_id="user1", timestamp=january_2023_timestamp)
```
```javascript JavaScript
// January 1, 2023 timestamp
const january2023Timestamp = 1672531200; // Unix timestamp for 2023-01-01 00:00:00 UTC
const messages = [
{"role": "user", "content": "I'm travelling to SF"}
]
client.add(messages, { userId: "user1", timestamp: january2023Timestamp })
.then(response => console.log(response))
.catch(error => console.error(error));
```
</CodeGroup>
If you have any questions, please feel free to reach out to us using one of the following methods:
<Snippet file="get-help.mdx" />
@@ -0,0 +1,433 @@
---
title: Memory Filters
description: Query and retrieve memories with powerful filtering capabilities. Filter by users, agents, content, time ranges, and more.
---
> Memory filters provide a flexible way to query and retrieve specific memories from your memory store. You can filter by users, agents, content categories, time ranges, and combine multiple conditions using logical operators.
## When to use filters
When working with large-scale memory stores, you need precise control over which memories to retrieve. Filters help you:
* **Isolate user data**: Retrieve memories for specific users while maintaining privacy
* **Debug and audit**: Export specific memory subsets for analysis
* **Target content**: Find memories with specific categories or metadata
* **Time-based queries**: Retrieve memories within specific date ranges
* **Performance optimization**: Reduce query complexity by pre-filtering
## Filter structure
Filters use a nested JSON structure with logical operators at the root:
```python
# Basic structure
{
"AND": [ # or "OR", "NOT"
{ "field": "value" },
{ "field": { "operator": "value" } }
]
}
```
## Available fields and operators
### Entity fields
| Field | Operators | Example |
|-------|-----------|---------|
| `user_id` | `eq`, `ne`, `in`, `*` | `{"user_id": "user_123"}` |
| `agent_id` | `eq`, `ne`, `in`, `*` | `{"agent_id": "*"}` |
| `app_id` | `eq`, `ne`, `in`, `*` | `{"app_id": {"in": ["app1", "app2"]}}` |
| `run_id` | `eq`, `ne`, `in`, `*` | `{"run_id": "*"}` |
### Time fields
| Field | Operators | Example |
|-------|-----------|---------|
| `created_at` | `gt`, `gte`, `lt`, `lte`, `eq`, `ne` | `{"created_at": {"gte": "2024-01-01"}}` |
| `updated_at` | `gt`, `gte`, `lt`, `lte`, `eq`, `ne` | `{"updated_at": {"lt": "2024-12-31"}}` |
| `timestamp` | `gt`, `gte`, `lt`, `lte`, `eq`, `ne` | `{"timestamp": {"gt": "2024-01-01"}}` |
### Content fields
| Field | Operators | Example |
|-------|-----------|---------|
| `categories` | `eq`, `ne`, `in`, `contains` | `{"categories": {"in": ["finance"]}}` |
| `metadata` | `eq`, `ne`, `contains` | `{"metadata": {"key": "value"}}` |
| `keywords` | `contains`, `icontains` | `{"keywords": {"icontains": "invoice"}}` |
### Special fields
| Field | Operators | Example |
|-------|-----------|---------|
| `memory_ids` | `in` | `{"memory_ids": ["id1", "id2"]}` |
<Callout type="warning" icon="exclamation-triangle" color="#F7B731">
The `*` wildcard matches any non-null value. Records with null values for that field are excluded.
</Callout>
<Callout type="info" icon="keyboard" color="#00A8FF">
Use operator keywords exactly as shown (`eq`, `ne`, `gte`, etc.). SQL-style symbols such as `>=` or `!=` are rejected by the Platform API.
</Callout>
## Common filter patterns
Use these ready-made filters to target typical retrieval scenarios without rebuilding logic from scratch.
<AccordionGroup>
<Accordion title="Single user">
```python
# Narrow to one user's memories
filters = {"AND": [{"user_id": "user_123"}]}
memories = client.get_all(filters=filters)
```
</Accordion>
<Accordion title="All users">
```python
# Wildcard skips null user_id entries
filters = {"AND": [{"user_id": "*"}]}
memories = client.get_all(filters=filters)
```
</Accordion>
<Accordion title="User across all runs">
```python
# Pair a user filter with a run wildcard
filters = {
"AND": [
{"user_id": "user_123"},
{"run_id": "*"}
]
}
memories = client.get_all(filters=filters)
```
</Accordion>
</AccordionGroup>
<Callout type="warning" icon="exclamation-triangle" color="#E74C3C">
Metadata filters only support bare values/`eq`, `contains`, and `ne`. Operators such as `in`, `gt`, or `lt` trigger a `FilterValidationError`. For multi-value checks, wrap multiple equality clauses in `OR`.
</Callout>
```python
# Multi-value metadata workaround
filters = {
"OR": [
{"metadata": {"type": "semantic"}},
{"metadata": {"type": "episodic"}}
]
}
```
### Content search
Find memories containing specific text, categories, or metadata values.
<AccordionGroup>
<Accordion title="Text search">
```python
# Case-insensitive match
filters = {
"AND": [
{"user_id": "user_123"},
{"keywords": {"icontains": "pizza"}}
]
}
# Case-sensitive match
filters = {
"AND": [
{"user_id": "user_123"},
{"keywords": {"contains": "Invoice_2024"}}
]
}
```
</Accordion>
<Accordion title="Categories">
```python
# Match against category list
filters = {
"AND": [
{"user_id": "user_123"},
{"categories": {"in": ["finance", "health"]}}
]
}
# Partial category match
filters = {
"AND": [
{"user_id": "user_123"},
{"categories": {"contains": "finance"}}
]
}
```
</Accordion>
<Accordion title="Metadata">
```python
# Pin to a metadata attribute
filters = {
"AND": [
{"user_id": "user_123"},
{"metadata": {"source": "email"}}
]
}
```
</Accordion>
</AccordionGroup>
### Time-based filtering
Retrieve memories within specific date ranges using time operators.
<AccordionGroup>
<Accordion title="Date range">
```python
# Created in January 2024
filters = {
"AND": [
{"user_id": "user_123"},
{"created_at": {"gte": "2024-01-01T00:00:00Z"}},
{"created_at": {"lt": "2024-02-01T00:00:00Z"}}
]
}
# Updated recently
filters = {
"AND": [
{"user_id": "user_123"},
{"updated_at": {"gte": "2024-12-01T00:00:00Z"}}
]
}
```
</Accordion>
</AccordionGroup>
### Multiple criteria
Combine various filters for complex queries across different dimensions.
<AccordionGroup>
<Accordion title="Multiple users">
```python
# Expand scope to a short user list
filters = {
"AND": [
{"user_id": {"in": ["user_1", "user_2", "user_3"]}}
]
}
```
</Accordion>
<Accordion title="OR logic">
```python
# Return matches on either condition
filters = {
"OR": [
{"user_id": "user_123"},
{"run_id": "run_456"}
]
}
```
</Accordion>
<Accordion title="Exclude categories">
```python
# Wrap negative logic with NOT
filters = {
"AND": [
{"user_id": "user_123"},
{"NOT": {
"categories": {"in": ["spam", "test"]}
}}
]
}
```
</Accordion>
<Accordion title="Specific memory IDs">
```python
# Fetch a fixed set of memory IDs
filters = {
"AND": [
{"user_id": "user_123"},
{"memory_ids": ["mem_1", "mem_2", "mem_3"]}
]
}
```
</Accordion>
<Accordion title="All entities populated (single entity scope)">
```python
# Require user_id plus non-null run/app IDs
# (Memories are stored separately per entity, so scope one dimension at a time.)
filters = {
"AND": [
{"user_id": "user_123"},
{"run_id": "*"},
{"app_id": "*"}
]
}
```
</Accordion>
</AccordionGroup>
## Advanced examples
Level up foundational patterns with compound filters that coordinate entity scope, tighten time windows, and weave in exclusion rules for high-precision retrievals.
<AccordionGroup>
<Accordion title="Multi-dimensional filtering">
```python
# Invoice memories in Q1 2024
filters = {
"AND": [
{"user_id": "user_123"},
{"keywords": {"icontains": "invoice"}},
{"categories": {"in": ["finance"]}},
{"created_at": {"gte": "2024-01-01T00:00:00Z"}},
{"created_at": {"lt": "2024-04-01T00:00:00Z"}}
]
}
```
</Accordion>
<Accordion title="Entity-specific retrieval">
```python
# Query agent scope on its own
filters = {
"AND": [
{"agent_id": "finance_bot"}
]
}
# Or broaden within that scope using wildcards
filters = {
"AND": [
{"agent_id": "finance_bot"},
{"run_id": "*"}
]
}
```
</Accordion>
<Accordion title="Nested NOT/OR logic">
```python
# User memories from 2024, excluding spam and test
filters = {
"AND": [
{"user_id": "user_123"},
{"created_at": {"gte": "2024-01-01T00:00:00Z"}},
{"NOT": {
"OR": [
{"categories": {"in": ["spam"]}},
{"categories": {"in": ["test"]}}
]
}}
]
}
```
</Accordion>
</AccordionGroup>
## Best practices
<Callout type="tip" icon="lightbulb" color="#26A17B">
The root must be `AND`, `OR`, or `NOT` with an array of conditions.
</Callout>
<Callout type="tip" icon="lightbulb" color="#26A17B">
Use `"*"` to match any non-null value for a field.
</Callout>
<Callout type="warning" icon="exclamation-triangle" color="#E74C3C">
Memories are stored per-entity (user, agent, app, run). Combining `user_id` **and** `agent_id` in the same `AND` clause returns no results because no record contains both values at once. Query one entity scope at a time or use `OR` logic for parallel lookups.
</Callout>
## Troubleshooting
<AccordionGroup>
<Accordion title="Missing results with agent_id">
**Problem**: Filtered by `user_id` but don't see agent memories.
**Solution**: User and agent memories are stored as separate records. Use OR to query both scopes:
```python
{"OR": [{"user_id": "user_123"}, {"agent_id": "agent_name"}]}
```
</Accordion>
<Accordion title="ne operator returns too much">
**Problem**: `ne` comparison pulls in records with null values.
**Solution**: Pair `ne` with a wildcard guard:
```python
{"AND": [{"agent_id": "*"}, {"agent_id": {"ne": "old_agent"}}]}
```
</Accordion>
<Accordion title="Case-insensitive search">
**Solution**: Swap to `icontains` to normalize casing.
</Accordion>
<Accordion title="Date range between two dates">
**Solution**: Use `gte` for the start and `lt` for the end boundary:
```python
{"AND": [
{"created_at": {"gte": "2024-01-01"}},
{"created_at": {"lt": "2024-02-01"}}
]}
```
</Accordion>
<Accordion title="Metadata filter not working">
**Solution**: Match top-level metadata keys exactly:
```python
{"metadata": {"source": "email"}}
```
</Accordion>
</AccordionGroup>
## FAQ
<AccordionGroup>
<Accordion title="Do I need AND/OR/NOT?">
Yes. The root must be a logical operator with an array.
</Accordion>
<Accordion title="What does * match?">
Any non-null value. Nulls are excluded.
</Accordion>
<Accordion title="Why use wildcards?">
Unspecified fields default to NULL. Use `"*"` to include non-null values.
</Accordion>
<Accordion title="Is = required?">
No. Equality is the default: `{"user_id": "u1"}` works.
</Accordion>
<Accordion title="Can I filter nested metadata?">
Only top-level keys are supported.
</Accordion>
<Accordion title="How to search text?">
Use `keywords` with `contains` (case-sensitive) or `icontains` (case-insensitive).
</Accordion>
<Accordion title="Can I nest AND/OR?">
```python
{
"AND": [
{"user_id": "user_123"},
{"OR": [
{"categories": "finance"},
{"categories": "health"}
]}
]
}
```
</Accordion>
</AccordionGroup>
## Known limitations
- Entity filters operate on a single scope per record. Use separate queries or `OR` logic to compare users vs agents.
- Metadata supports only bare/`eq`, `contains`, and `ne` comparisons.
- Wildcards (`"*"` ) match only records where the field is already non-null.
+209
View File
@@ -0,0 +1,209 @@
---
title: Webhooks
description: 'Configure and manage webhooks to receive real-time notifications about memory events'
---
## Overview
Webhooks enable real-time notifications for memory events in your Mem0 project. Webhooks are configured at the project level, meaning each webhook is tied to a specific project and receives events solely from that project. You can configure webhooks to send HTTP POST requests to your specified URLs whenever memories are created, updated, deleted, or categorized.
## Managing Webhooks
### Create Webhook
Create a webhook for your project. It will receive events only from that project:
<CodeGroup>
```python Python
import os
from mem0 import MemoryClient
os.environ["MEM0_API_KEY"] = "your-api-key"
client = MemoryClient()
# Create webhook in a specific project
webhook = client.create_webhook(
url="https://your-app.com/webhook",
name="Memory Logger",
project_id="proj_123",
event_types=["memory_add", "memory_categorize"]
)
print(webhook)
```
```javascript JavaScript
const { MemoryClient } = require('mem0ai');
const client = new MemoryClient({ apiKey: 'your-api-key'});
// Create webhook in a specific project
const webhook = await client.createWebhook({
url: "https://your-app.com/webhook",
name: "Memory Logger",
projectId: "proj_123",
eventTypes: ["memory_add", "memory_categorize"]
});
console.log(webhook);
```
```json Output
{
"webhook_id": "wh_123",
"name": "Memory Logger",
"url": "https://your-app.com/webhook",
"event_types": ["memory_add"],
"project": "default-project",
"is_active": true,
"created_at": "2025-02-18T22:59:56.804993-08:00",
"updated_at": "2025-02-18T23:06:41.479361-08:00"
}
```
</CodeGroup>
### Get Webhooks
Retrieve all webhooks for your project:
<CodeGroup>
```python Python
# Get webhooks for a specific project
webhooks = client.get_webhooks(project_id="proj_123")
print(webhooks)
```
```javascript JavaScript
// Get webhooks for a specific project
const webhooks = await client.getWebhooks({projectId: "proj_123"});
console.log(webhooks);
```
```json Output
[
{
"webhook_id": "wh_123",
"url": "https://mem0.ai",
"name": "mem0",
"owner": "john",
"event_types": ["memory_add"],
"project": "default-project",
"is_active": true,
"created_at": "2025-02-18T22:59:56.804993-08:00",
"updated_at": "2025-02-18T23:06:41.479361-08:00"
}
]
```
</CodeGroup>
### Update Webhook
Update an existing webhooks configuration by specifying its `webhook_id`:
<CodeGroup>
```python Python
# Update webhook for a specific project
updated_webhook = client.update_webhook(
name="Updated Logger",
url="https://your-app.com/new-webhook",
event_types=["memory_update", "memory_add"],
webhook_id="wh_123"
)
print(updated_webhook)
```
```javascript JavaScript
// Update webhook for a specific project
const updatedWebhook = await client.updateWebhook({
name: "Updated Logger",
url: "https://your-app.com/new-webhook",
eventTypes: ["memory_update", "memory_add"],
webhookId: "wh_123"
});
console.log(updatedWebhook);
```
```json Output
{
"message": "Webhook updated successfully"
}
```
</CodeGroup>
### Delete Webhook
Delete a webhook by providing its `webhook_id`:
<CodeGroup>
```python Python
# Delete webhook from a specific project
response = client.delete_webhook(webhook_id="wh_123")
print(response)
```
```javascript JavaScript
// Delete webhook from a specific project
const response = await client.deleteWebhook({webhookId: "wh_123"});
console.log(response);
```
```json Output
{
"message": "Webhook deleted successfully"
}
```
</CodeGroup>
## Event Types
Mem0 supports the following event types for webhooks:
- `memory_add`: Triggered when a memory is added.
- `memory_update`: Triggered when an existing memory is updated.
- `memory_delete`: Triggered when a memory is deleted.
- `memory_categorize`: Triggered when a memory is categorized.
## Webhook Payload
When a memory event occurs, Mem0 sends an HTTP POST request to your webhook URL with the following payload:
**Memory add/update/delete payload:**
```json
{
"event_details": {
"id": "a1b2c3d4-e5f6-4g7h-8i9j-k0l1m2n3o4p5",
"data": {
"memory": "Name is Alex"
},
"event": "ADD"
}
}
```
**Memory categorize payload:**
```json
{
"event_details": {
"event": "CATEGORIZE",
"memory_id": "a1b2c3d4-e5f6-4g7h-8i9j-k0l1m2n3o4p5",
"categories": ["hobbies", "travel"]
}
}
```
## Best Practices
1. **Implement Retry Logic**: Ensure your webhook endpoint can handle temporary failures.
2. **Verify Webhook Source**: Implement security measures to verify that webhook requests originate from Mem0.
3. **Process Events Asynchronously**: Process webhook events asynchronously to avoid timeouts and ensure reliable handling.
4. **Monitor Webhook Health**: Regularly review your webhook logs to ensure functionality and promptly address delivery failures.
If you have any questions, please feel free to reach out to us using one of the following methods:
<Snippet file="get-help.mdx" />
+212
View File
@@ -0,0 +1,212 @@
---
title: "Mem0 MCP"
description: "Connect any AI client to Mem0 using Model Context Protocol in minutes"
icon: "puzzle-piece"
estimatedTime: "~2 minutes"
---
<Info>
**Prerequisites**
- Mem0 Platform account (<a href="https://app.mem0.ai?utm_source=oss&utm_medium=platform-mem0-mcp" rel="nofollow">Sign up here</a>)
- API key (<a href="https://app.mem0.ai/settings/api-keys?utm_source=oss&utm_medium=platform-mem0-mcp" rel="nofollow">Get one from dashboard</a>)
- Node.js 14+ (for npx)
- An MCP-compatible client (Claude, Claude Code, Codex, Cursor, Windsurf, VS Code, OpenCode)
</Info>
## What is Mem0 MCP?
Mem0 MCP Server exposes Mem0's memory capabilities as MCP tools, letting AI agents decide when to save, search, or update information. The cloud-hosted MCP server requires no local installation: just connect and start using memory.
## Quick Setup
Add Mem0 MCP to your preferred clients with a single command:
```bash
npx mcp-add \
--name mem0-mcp \
--type http \
--url "https://mcp.mem0.ai/mcp" \
--clients "claude,claude code,cursor,windsurf,vscode,opencode"
```
This automatically configures Mem0 MCP for all supported clients at once.
## Available Tools
The MCP server exposes these memory tools to your AI client:
| Tool | Description |
|------|-------------|
| `add_memory` | Save text or conversation history for a user/agent |
| `search_memories` | Semantic search across existing memories with filters |
| `get_memories` | List memories with structured filters and pagination |
| `get_memory` | Retrieve one memory by its `memory_id` |
| `update_memory` | Overwrite a memory's text after confirming the ID |
| `delete_memory` | Delete a single memory by `memory_id` |
| `delete_all_memories` | Bulk delete all memories in scope |
| `delete_entities` | Delete a user/agent/app/run entity and its memories |
| `list_entities` | Enumerate users/agents/apps/runs stored in Mem0 |
| `list_events` | List memory operation events with filters and pagination |
| `get_event_status` | Check the status of an async memory operation by `event_id` |
---
## Client-Specific Setup
You can also configure individual clients:
<AccordionGroup>
<Accordion title="Claude Desktop">
```bash
npx mcp-add \
--name mem0-mcp \
--type http \
--url "https://mcp.mem0.ai/mcp" \
--clients "claude"
```
Or manually add to your Claude Desktop configuration (`claude_desktop_config.json`):
```json
{
"mcpServers": {
"mem0-mcp": {
"type": "http",
"url": "https://mcp.mem0.ai/mcp"
}
}
}
```
</Accordion>
<Accordion title="Claude Code">
```bash
npx mcp-add \
--name mem0-mcp \
--type http \
--url "https://mcp.mem0.ai/mcp" \
--clients "claude code"
```
</Accordion>
<Accordion title="Codex">
**Direct MCP (fastest, MCP only).** Codex reads MCP servers from `~/.codex/config.toml` as TOML (not JSON). Add:
```toml
[mcp_servers.mem0]
url = "https://mcp.mem0.ai/mcp"
bearer_token_env_var = "MEM0_API_KEY"
```
Export `MEM0_API_KEY` in the shell you launch Codex from, then restart Codex. `codex mcp add` only supports stdio servers, so HTTP servers must be added via `config.toml` directly, or via the **Plugins → Connect to a custom MCP → Streamable HTTP** UI in the Codex app.
<Note>
Codex uses the server name `mem0` (not `mem0-mcp` like the other clients on this page) so it matches the name the bundled plugin registers if you ever sideload it later.
</Note>
**Sideloaded plugin (full experience).** If you want the memory protocol skill, Mem0 SDK skill, and opt-in lifecycle hooks alongside the MCP server, sideload the plugin from a clone of `mem0ai/mem0`. The repo ships a marketplace manifest at `.agents/plugins/marketplace.json`, so you can register it with one CLI call:
```bash
git clone https://github.com/mem0ai/mem0.git ~/codex-plugins/mem0-source
codex plugin marketplace add ~/codex-plugins/mem0-source
```
Then run `codex` and `/plugins`, browse the **Mem0 Plugins** marketplace, and install **Mem0**. Don't combine this with the Direct MCP setup above; the sideloaded plugin auto-registers `mem0` via `.codex-mcp.json`, so a manual `[mcp_servers.mem0]` block would create a duplicate.
See the [Codex integration guide](/integrations/codex) for full details, lifecycle-hook setup, and management commands (`codex plugin marketplace upgrade` / `remove`).
</Accordion>
<Accordion title="Cursor">
```bash
npx mcp-add \
--name mem0-mcp \
--type http \
--url "https://mcp.mem0.ai/mcp" \
--clients "cursor"
```
Or go to Cursor → Settings → MCP and add:
```json
{
"mcpServers": {
"mem0-mcp": {
"type": "http",
"url": "https://mcp.mem0.ai/mcp"
}
}
}
```
</Accordion>
<Accordion title="Windsurf">
```bash
npx mcp-add \
--name mem0-mcp \
--type http \
--url "https://mcp.mem0.ai/mcp" \
--clients "windsurf"
```
</Accordion>
<Accordion title="VS Code">
```bash
npx mcp-add \
--name mem0-mcp \
--type http \
--url "https://mcp.mem0.ai/mcp" \
--clients "vscode"
```
</Accordion>
<Accordion title="OpenCode">
```bash
npx mcp-add \
--name mem0-mcp \
--type http \
--url "https://mcp.mem0.ai/mcp" \
--clients "opencode"
```
</Accordion>
</AccordionGroup>
---
## Verify Your Setup
Once configured, your AI client can:
- Automatically save information with `add_memory`
- Search memories with `search_memories`
- Update memories with `update_memory`
- Delete memories with `delete_memory`
**Sample Interactions:**
```
User: Remember that I love tiramisu
Agent: Got it! I've saved that you love tiramisu.
User: What do you know about my food preferences?
Agent: Based on your memories, you love tiramisu.
User: Update my project: the mobile app is now 80% complete
Agent: Updated your project status successfully.
```
<Info icon="check">
If you get "Connection failed", ensure you have a valid API key from <a href="https://app.mem0.ai/settings/api-keys?utm_source=oss&utm_medium=platform-mem0-mcp" rel="nofollow">Mem0 Dashboard</a>.
</Info>
---
## Quick Recovery
- **"Connection refused"** → Check your internet connection and ensure the MCP client is correctly configured
- **"Invalid API key"** → Get a new key from <a href="https://app.mem0.ai/settings/api-keys?utm_source=oss&utm_medium=platform-mem0-mcp" rel="nofollow">Mem0 Dashboard</a>
- **"npx command not found"** → Install Node.js from [nodejs.org](https://nodejs.org)
---
## Next steps
- [Platform Quickstart](/platform/quickstart) - direct SDK/API integration guide
- [MCP Specification](https://modelcontextprotocol.io) - the Model Context Protocol standard
- [Gemini with Mem0 MCP](/cookbooks/frameworks/gemini-3-with-mem0-mcp) - example integration cookbook
+62
View File
@@ -0,0 +1,62 @@
---
title: "Overview"
description: "Managed memory layer for AI agents, production-ready in minutes"
icon: "cloud"
---
Mem0 Platform is the fully managed memory layer for your AI apps and agents. Your users stop repeating themselves and your agents keep context across sessions, with no vector store, reranker, or infrastructure to run.
## Why teams pick the Platform
- **Personalized replies.** Memories persist across users and agents, cutting prompt bloat and repeat questions.
- **Zero infrastructure.** Mem0 runs the vector store and rerankers, so there is nothing to provision, tune, or maintain.
- **Enterprise-ready.** Audit logs and workspace governance ship by default.
## How it works
<Steps>
<Step title="Add">
Send Mem0 your messages and conversations.
</Step>
<Step title="Extract and store">
Mem0 distills them into facts and links entities across memories.
</Step>
<Step title="Recall">
At query time, Mem0 returns only the most relevant memories.
</Step>
</Steps>
For the full pipeline, see [How Mem0 works](/core-concepts/how-it-works).
<AccordionGroup>
<Accordion title="What you get with Mem0 Platform" icon="sparkles">
| Feature | Why it helps |
| --- | --- |
| Fast setup | Add a few lines of code and you're production-ready, with no vector database or LLM configuration required. |
| Production scale | Automatic scaling, high availability, and managed infrastructure so you focus on product work. |
| Advanced features | Webhooks, multimodal support, and custom categories are ready to enable. |
| Enterprise ready | Audit logs, workspace governance, and dedicated support keep security and governance covered. |
</Accordion>
</AccordionGroup>
## Explore the Platform
<CardGroup cols={2}>
<Card title="How Mem0 works" icon="diagram-project" href="/core-concepts/how-it-works">
The extraction and retrieval pipeline, end to end.
</Card>
<Card title="Run the quickstart" icon="rocket" href="/platform/quickstart">
Get an API key and save your first memory.
</Card>
<Card title="Understand memory types" icon="brain" href="/core-concepts/memory-types">
How user, agent, run, and session memory differ.
</Card>
<Card title="Add, search, and update" icon="layer-group" href="/core-concepts/memory-operations/add">
The core memory operations, end to end.
</Card>
</CardGroup>
<Tip>
Deciding whether to self-host? Compare hosting models in the <Link href="/platform/platform-vs-oss">Platform vs OSS guide</Link>, or switch tabs to the Open Source docs to run Mem0 yourself.
</Tip>
+140
View File
@@ -0,0 +1,140 @@
---
title: "Platform vs Open Source"
description: "Compare Mem0 Platform and Open Source to choose the right solution for managed hosting or self-hosted deployment."
icon: "code-compare"
---
## Which Mem0 is right for you?
Mem0 offers two powerful ways to add memory to your AI applications. Choose based on your priorities:
<CardGroup cols={2}>
<Card
title="Mem0 Platform"
icon="cloud"
href="/platform/quickstart"
>
**Managed, hassle-free**
Get started in 5 minutes with our hosted solution. Perfect for fast iteration and production apps.
</Card>
<Card
title="Open Source"
icon="code-branch"
href="/open-source/python-quickstart"
>
**Self-hosted, full control**
Deploy on your infrastructure. Choose your vector DB, LLM, and configure everything.
</Card>
</CardGroup>
---
## Feature Comparison
<AccordionGroup>
<Accordion title="Setup & Getting Started" icon="rocket">
| Feature | Platform | Open Source |
|---------|----------|-------------|
| **Time to first memory** | 5 minutes | 15-30 minutes |
| **Infrastructure needed** | None | Vector DB + Python/Node env |
| **API key setup** | One environment variable | Configure LLM + embedder + vector DB |
| **Maintenance** | Fully managed by Mem0 | Self-managed |
</Accordion>
<Accordion title="Core Memory Features" icon="brain">
| Feature | Platform | Open Source |
|---------|----------|-------------|
| **User & agent memories** | ✅ | ✅ |
| **Smart deduplication** | ✅ | ✅ |
| **Semantic search** | ✅ | ✅ |
| **Memory updates** | ✅ | ✅ |
| **Multi-language SDKs** | Python, JavaScript | Python, JavaScript |
</Accordion>
<Accordion title="Advanced Capabilities" icon="sparkles">
| Feature | Platform | Open Source |
|---------|----------|-------------|
| **Multimodal support** | ✅ | ✅ |
| **Custom categories** | ✅ | Limited |
| **Advanced retrieval** | ✅ | ✅ |
| **Criteria retrieval** | ✅ | ❌ |
| **Temporal reasoning** | ✅ (v3) | ❌ |
| **Memory decay** | ✅ (v3) | ❌ |
| **Graph memory** | ✅ Built-in | ✅ External graph store |
| **Memory filters v2** | ✅ | ⚠️ (via metadata) |
| **Webhooks** | ✅ | ❌ |
| **Memory export** | ✅ | ❌ |
</Accordion>
<Accordion title="Infrastructure & Scaling" icon="server">
| Feature | Platform | Open Source |
|---------|----------|-------------|
| **Hosting** | Managed by Mem0 | Self-hosted |
| **Auto-scaling** | ✅ | Manual |
| **High availability** | ✅ Built-in | DIY setup |
| **Vector DB choice** | Managed | 20+ stores: Qdrant, Pinecone, Chroma, Weaviate, Milvus, pgvector |
| **LLM choice** | Managed (optimized) | 15+ providers: OpenAI, Anthropic, Gemini, Groq, Ollama, Together |
| **Data residency** | US (expandable) | Your choice |
</Accordion>
<Accordion title="Pricing & Cost" icon="dollar-sign">
| Aspect | Platform | Open Source |
|--------|----------|-------------|
| **License** | Usage-based pricing | Apache 2.0 (free) |
| **Infrastructure costs** | Included in pricing | You pay for VectorDB + LLM + hosting |
| **Support** | Included | Community + GitHub |
| **Best for** | Fast iteration, production apps | Cost-sensitive, custom requirements |
</Accordion>
<Accordion title="Development & Integration" icon="code">
| Feature | Platform | Open Source |
|---------|----------|-------------|
| **REST API** | ✅ | ✅ (self-hosted server) |
| **Python SDK** | ✅ | ✅ |
| **JavaScript SDK** | ✅ | ✅ |
| **Framework integrations** | LangChain, CrewAI, LlamaIndex, and 20+ more | Same |
| **Dashboard** | ✅ Web-based | ❌ |
| **Analytics** | ✅ Built-in | DIY |
</Accordion>
</AccordionGroup>
---
## Decision Guide
**Choose Platform if you want:**
- Fast time to market: get your AI app with memory live in hours, not weeks.
- Production-ready hosting: auto-scaling, high availability, and managed infrastructure.
- Built-in analytics: track memory usage, query patterns, and user engagement through the dashboard.
- Advanced features: webhooks, memory export, custom categories, and priority support.
**Choose Open Source if you need:**
- Full data control: host everything on your infrastructure with complete data residency.
- Custom configuration: choose your own vector DB, LLM provider, embedder, and deployment strategy.
- Extensibility: modify the codebase, add custom features, and contribute back to the community.
- Cost optimization: use local LLMs (Ollama), self-hosted vector DBs, and optimize for your use case.
---
## Still not sure?
<CardGroup cols={2}>
<Card
title="Try Platform Free"
icon="rocket"
href="https://app.mem0.ai/login?utm_source=oss&utm_medium=platform-vs-oss"
>
Sign up and test the Platform with our free tier. No credit card required.
</Card>
<Card
title="Explore Open Source"
icon="github"
href="https://github.com/mem0ai/mem0"
>
Clone the repo and run locally to see how it works. Star us while you're there!
</Card>
</CardGroup>
+168
View File
@@ -0,0 +1,168 @@
---
title: Quickstart
description: "Set up your Mem0 Platform account, install the SDK, and store your first memory in under five minutes."
icon: "bolt"
iconType: "solid"
---
Get started with Mem0 Platform's hosted API in under 5 minutes. This guide shows you how to authenticate and store your first memory.
<Note>
**Are you an AI agent?** See [Sign up as an agent](/platform/agent-signup): mint a working API key in four commands, no email or dashboard required.
</Note>
## Prerequisites
- Mem0 Platform account (<a href="https://app.mem0.ai?utm_source=oss&utm_medium=platform-quickstart" rel="nofollow">Sign up here</a>)
- API key (<a href="https://app.mem0.ai/dashboard/settings?tab=api-keys&subtab=configuration" rel="nofollow">Get one from dashboard</a>)
- Python 3.10+, Node.js 18+, or cURL
## Installation
<Steps>
<Step title="Install SDK">
<CodeGroup>
```bash pip
pip install mem0ai
```
```bash npm
npm install mem0ai
```
</CodeGroup>
</Step>
<Step title="Set your API key">
<CodeGroup>
```python Python
from mem0 import MemoryClient
client = MemoryClient(api_key="your-api-key")
````
```javascript JavaScript
import MemoryClient from 'mem0ai';
const client = new MemoryClient({ apiKey: 'your-api-key' });
````
```bash cURL
export MEM0_API_KEY="your-api-key"
```
```bash CLI
mem0 init --api-key "your-api-key"
```
</CodeGroup>
</Step>
<Step title="Add a memory">
<CodeGroup>
```python Python
messages = [
{"role": "user", "content": "I'm a vegetarian and allergic to nuts."},
{"role": "assistant", "content": "Got it! I'll remember your dietary preferences."}
]
client.add(messages, user_id="user123")
````
```javascript JavaScript
const messages = [
{"role": "user", "content": "I'm a vegetarian and allergic to nuts."},
{"role": "assistant", "content": "Got it! I'll remember your dietary preferences."}
];
await client.add(messages, { userId: "user123" });
````
```bash cURL
curl -X POST https://api.mem0.ai/v3/memories/add/ \
-H "Authorization: Token $MEM0_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"role": "user", "content": "Im a vegetarian and allergic to nuts."},
{"role": "assistant", "content": "Got it! Ill remember your dietary preferences."}
],
"user_id": "user123"
}'
```
```bash CLI
mem0 add "I'm a vegetarian and allergic to nuts." --user-id user123
```
</CodeGroup>
</Step>
<Step title="Search memories">
<CodeGroup>
```python Python
results = client.search("What are my dietary restrictions?", filters={"user_id": "user123"})
print(results)
````
```javascript JavaScript
const results = await client.search("What are my dietary restrictions?", { filters: { user_id: "user123" } });
console.log(results);
````
```bash cURL
curl -X POST https://api.mem0.ai/v3/memories/search/ \
-H "Authorization: Token $MEM0_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "What are my dietary restrictions?",
"filters": {"user_id": "user123"}
}'
```
```bash CLI
mem0 search "What are my dietary restrictions?" --user-id user123
```
</CodeGroup>
**Output:**
```json
{
"results": [
{
"id": "14e1b28a-2014-40ad-ac42-69c9ef42193d",
"memory": "Allergic to nuts",
"user_id": "user123",
"categories": ["health"],
"created_at": "2025-10-22T04:40:22.864647-07:00",
"score": 0.30
}
]
}
```
</Step>
</Steps>
<Callout type="tip" icon="plug">
**Pro Tip**: Want AI agents to manage their own memory automatically? Use <Link href="/platform/mem0-mcp">Mem0 MCP</Link> to let LLMs decide when to save, search, and update memories.
</Callout>
## What's next?
You stored and searched your first memory. Keep going:
<CardGroup cols={3}>
<Card title="How it works" icon="diagram-project" href="/core-concepts/how-it-works">
See how Mem0 extracts, stores, and retrieves memories under the hood.
</Card>
<Card title="Memory operations" icon="database" href="/core-concepts/memory-operations/add">
Go beyond add and search: update, delete, and the full memory lifecycle.
</Card>
<Card title="Build an AI companion" icon="users" href="/cookbooks/essentials/building-ai-companion">
Put it to work in a real app, end to end, in about 10 minutes.
</Card>
</CardGroup>
Stuck on setup? See the [FAQs and troubleshooting](/platform/faqs).