Platform REST API 与 CLI(2/6)

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:

# Basic structure
{
    "AND": [  # or "OR", "NOT"
        { "field": "value" },
        { "field": { "operator": "value" } }
    ]
}

A single bare condition needs no wrapper:

# Works: one condition, no wrapper needed
filters = {"user_id": "user_123"}

Sibling top-level keys in a flat object are accepted too: the API implicitly ANDs them, so the flat form and the explicit AND form are equivalent:

# Works: sibling keys are implicitly ANDed
filters = {
    "user_id": "user_123",
    "categories": {"in": ["finance"]}
}

# Equivalent, explicit form
filters = {
    "AND": [
        {"user_id": "user_123"},
        {"categories": {"in": ["finance"]}}
    ]
}

Reach for an explicit AND, OR, or NOT wrapper when you need OR or NOT semantics, or when you need to nest conditions. What the API does reject is an unrecognized top-level key:

# Rejected: unknown top-level key
filters = {"user_id": "user_123", "bogus_key": "z"}
# 400: Top-level key must be a logical operator or an allowed field:
# ['AND', 'OR', 'NOT', 'user_id', 'agent_id', 'app_id', 'run_id',
#  'created_at', 'updated_at', 'timestamp', 'expiration_date', 'text',
#  'categories', 'metadata', 'keywords_search', 'memory_ids', 'keywords']

<Callout type="info" icon="cloud"> Both the hosted Platform API and the self-hosted OSS SDK implicitly AND sibling top-level keys, so the flat and explicit AND forms behave the same way on either. The real differences: Platform validates each top-level key against a fixed allow-list and returns a 400 for anything else, and Platform has no nin operator. See Enhanced Metadata Filtering for the OSS grammar. </Callout>

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, ne, in. Explicit eq is rejected, pass a bare value instead {"created_at": {"gte": "2024-01-01"}}
updated_at gt, gte, lt, lte, ne, in. Explicit eq is rejected, pass a bare value instead {"updated_at": {"lt": "2024-12-31"}}
timestamp gt, gte, lt, lte, ne, in. Explicit eq is rejected, pass a bare value instead {"timestamp": {"gt": "2024-01-01"}}
expiration_date gt, gte, lt, lte, ne, in. Explicit eq is rejected, pass a bare value instead {"expiration_date": {"lte": "2026-12-31"}}

Content fields

Field Operators Example
categories in (takes a list, matches any category in it), contains (case-insensitive). eq and ne are rejected {"categories": {"in": ["finance"]}}
metadata eq, ne, contains {"metadata": {"key": "value"}}
keywords contains (case-sensitive), icontains (case-insensitive) {"keywords": {"icontains": "invoice"}}

Special fields

Field Operators Example
memory_ids in {"memory_ids": ["id1", "id2"]}

<Callout type="warning" icon="exclamation-triangle"> The * wildcard matches any non-null value. Records with null values for that field are excluded. </Callout>

<Callout type="info" icon="keyboard"> Use operator keywords exactly as shown (eq, ne, gte, etc.). SQL-style symbols such as >= or != are rejected by the Platform API. </Callout>

<Callout type="warning" icon="exclamation-triangle"> There is no nin ("not in") operator on Platform. It is an OSS-only operator; see Enhanced Metadata Filtering. To exclude a set of values on Platform, wrap an in clause in NOT:

{"NOT": {"categories": {"in": ["spam", "test"]}}}

</Callout>

Common filter patterns

Use these ready-made filters to target typical retrieval scenarios without rebuilding logic from scratch.

<AccordionGroup>

# Narrow to one user's memories
filters = {"AND": [{"user_id": "user_123"}]}
memories = client.get_all(filters=filters)
# Wildcard skips null user_id entries
filters = {"AND": [{"user_id": "*"}]}
memories = client.get_all(filters=filters)
# Pair a user filter with a run wildcard
filters = {
    "AND": [
        {"user_id": "user_123"},
        {"run_id": "*"}
    ]
}
memories = client.get_all(filters=filters)

</AccordionGroup>

<Callout type="warning" icon="exclamation-triangle"> 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>

# Multi-value metadata workaround
filters = {
    "OR": [
        {"metadata": {"type": "semantic"}},
        {"metadata": {"type": "episodic"}}
    ]
}

Find memories containing specific text, categories, or metadata values.

<AccordionGroup>

# Substring match on memory text via get_all
filters = {
    "AND": [
        {"user_id": "user_123"},
        {"keywords": {"icontains": "invoice"}}
    ]
}
memories = client.get_all(filters=filters)
Use `contains` for case-sensitive matching and `icontains` for case-insensitive.

&lt;Callout type="warning" icon="exclamation-triangle">
  A `keywords` filter works on `get_all`, but passing it to `search()` currently returns a `500` ([MEM-5746](https://linear.app/mem0/issue/MEM-5746)). For text relevance during a search, pass the text to the `query` argument instead of filtering on `keywords`.
&lt;/Callout>
# 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"}}
    ]
}
# Pin to a metadata attribute
filters = {
    "AND": [
        {"user_id": "user_123"},
        {"metadata": {"source": "email"}}
    ]
}

</AccordionGroup>

Time-based filtering

Retrieve memories within specific date ranges using time operators.

<AccordionGroup>

# 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"}}
    ]
}

</AccordionGroup>

Multiple criteria

Combine various filters for complex queries across different dimensions.

<AccordionGroup>

# Expand scope to a short user list
filters = {
    "AND": [
        {"user_id": {"in": ["user_1", "user_2", "user_3"]}}
    ]
}
# Return matches on either condition
filters = {
    "OR": [
        {"user_id": "user_123"},
        {"run_id": "run_456"}
    ]
}
# Wrap negative logic with NOT
filters = {
    "AND": [
        {"user_id": "user_123"},
        {"NOT": {
            "categories": {"in": ["spam", "test"]}
        }}
    ]
}
# Fetch a fixed set of memory IDs
filters = {
    "AND": [
        {"user_id": "user_123"},
        {"memory_ids": ["mem_1", "mem_2", "mem_3"]}
    ]
}
filters = {
    "AND": [
        {"user_id": "user_123"},
        {"run_id": "*"},
        {"app_id": "*"}
    ]
}
Matches records where `user_id` equals `user_123` and `run_id`/`app_id` are both non-null. It does not require other entity fields to be null.

</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>

filters = {
    "AND": [
        {"user_id": "user_123"},
        {"categories": {"in": ["finance"]}},
        {"keywords": {"icontains": "invoice"}},
        {"created_at": {"gte": "2024-01-01T00:00:00Z"}},
        {"created_at": {"lt": "2024-04-01T00:00:00Z"}}
    ]
}
memories = client.get_all(filters=filters)
# 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": "*"}
    ]
}
# 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"]}}
            ]
        }}
    ]
}

</AccordionGroup>

Best practices

<Callout type="tip" icon="lightbulb"> The root does not have to be AND, OR, or NOT. A bare filter like {"user_id": "alice"} works on its own, and several top-level keys in one flat filter are implicitly ANDed. Wrap conditions in a logical operator when you need OR/NOT semantics or nested grouping. </Callout>

<Callout type="tip" icon="lightbulb"> Use "*" to match any non-null value for a field. </Callout>

<Callout type="warning" icon="exclamation-triangle"> Combining user_id and agent_id in the same AND clause only returns records that have both values set. Memories created by a normal client.add never do: each extracted fact is attributed to its speaker, so it carries user_id or agent_id, not both. Use OR to match either scope. Only Direct Import (infer=False) writes both fields on one record.

A filter object with both an AND key and a sibling OR key at the same level silently drops the OR branch today. Nest the OR inside the AND array instead of placing them as siblings. </Callout>

Troubleshooting

<AccordionGroup>

**Problem**: Filtered by `user_id` but don't see agent memories.

**Solution**: A `user_id` filter only matches records that have that `user_id` set; it won't surface memories written with only `agent_id`. Use OR to query both scopes:
{"OR": [{"user_id": "user_123"}, {"agent_id": "agent_name"}]}
**Problem**: `ne` comparison pulls in records with null values.

**Solution**: Pair `ne` with a wildcard guard:
{"AND": [{"agent_id": "*"}, {"agent_id": {"ne": "old_agent"}}]}
**Solution**: Use `keywords` with `icontains` on `get_all`:
{"AND": [{"user_id": "user_123"}, {"keywords": {"icontains": "invoice"}}]}
This works on `get_all`. It is not supported on `search()` yet (returns a `500`, [MEM-5746](https://linear.app/mem0/issue/MEM-5746)) - for search, pass the text to the `query` argument instead.



**Solution**: Use `gte` for the start and `lt` for the end boundary:
{"AND": [
    {"created_at": {"gte": "2024-01-01"}},
    {"created_at": {"lt": "2024-02-01"}}
]}
**Solution**: Match top-level metadata keys exactly:
{"metadata": {"source": "email"}}

</AccordionGroup>

FAQ

<AccordionGroup>

No. A bare filter like `{"user_id": "u1"}` works on its own, and several top-level keys in one flat filter like `{"user_id": "u1", "agent_id": "a1"}` are implicitly ANDed. Reach for `AND`, `OR`, or `NOT` when you need OR/NOT semantics or nested grouping, not merely to combine conditions.



Any non-null value. Nulls are excluded.



Unspecified fields default to NULL. Use `"*"` to include non-null values.



No. Equality is the default: `{"user_id": "u1"}` works.



Only top-level keys are supported.



For a substring match, use the `keywords` filter with `contains`/`icontains` on `get_all`. For relevance-ranked search, pass the text to the `query` argument on `search()`. Note: `keywords` is not supported inside `search()` filters yet (returns a `500`, [MEM-5746](https://linear.app/mem0/issue/MEM-5746)).
{
    "AND": [
        {"user_id": "user_123"},
        {"OR": [
            {"categories": {"in": ["finance"]}},
            {"categories": {"in": ["health"]}}
        ]}
    ]
}

</AccordionGroup>

Known limitations

  • Filters only constrain the fields you mention; unmentioned entity fields are not required to be null. A record carries user_id or agent_id (never both) unless it came from Direct Import, plus whatever app_id and run_id were passed.
  • Metadata supports only bare/eq, contains, and ne comparisons.
  • Wildcards ("*" ) match only records where the field is already non-null.

Compare Mem0 Platform and Open Source to choose the right solution for managed hosting or self-hosted deployment.

Which Mem0 is right for you?

Mem0 offers two ways to add memory to your AI applications. Both run the same core extraction and retrieval logic; the Platform adds hosting, a small set of v3-only capabilities, and management surfaces that OSS does not have.

**Managed, hassle-free**

Get started in 5 minutes with our hosted solution. No vector store, LLM, or embedder to configure.



**Self-hosted, full control**

Deploy on your infrastructure. Choose your vector DB, LLM, and configure everything.

What's the same

The core memory loop is identical on both: add, search, get, get_all, update, delete, delete_all, and per-memory history all exist on the self-hosted Memory/AsyncMemory classes and on the hosted MemoryClient/AsyncMemoryClient. Both support:

  • Entity scoping by user_id, agent_id, and run_id
  • Filter grouping: both accept AND/OR/NOT wrappers, both implicitly AND a flat multi-key filter like {"user_id": "alice", "agent_id": "a1"}, and both accept * as a wildcard value. Which fields you may filter on, and which operators each field accepts, differ (see below)
  • Entity-aware ranking: both extract entities from memory text and use shared entities to boost related results at search time
  • Multimodal input, memory expiration (expiration_date), reranking, and custom extraction instructions (custom_instructions)
  • Python and JavaScript SDKs, plus a REST API (self-hosted via server/, or hosted)

What's actually different

<AccordionGroup>

| Feature                         | Platform               | Open Source                                |
| ------------------------------- | ---------------------- | ------------------------------------------ |
| **Vector store, LLM, embedder** | Run and tuned by Mem0  | You provision, configure, and pay for each |
| **Scaling & availability**      | Managed                | Your responsibility                        |
| **Web dashboard**               | `app.mem0.ai`          | Not included                               |
| **Time to first memory**        | Minutes (API key only) | Depends on your vector DB / LLM setup      |



| Feature                      | Platform                                                                                                                      | Open Source                                                     |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| **Scoping identifiers**      | `user_id`, `agent_id`, `run_id`, plus `app_id` for app/tenant separation                                                      | `user_id`, `agent_id`, `run_id` only, no `app_id`               |
| **Organizations & projects** | Multi-org, multi-project, with member roles ([API reference](https://docs.mem0.ai/api-reference/organization/get-org))                            | No org/project concept; a single local config                   |
| **Project-wide event feed**  | `GET /v1/events/` lists recent add/search/delete events per org and project, usable for dashboards, alerting, or audit trails | Only per-memory `history(memory_id)`, no project-wide event log |

See [Entity-Scoped Memory](https://docs.mem0.ai/platform/features/entity-scoped-memory) for the full `app_id` model.



| Feature                              | Platform                                                                                                                                                  | Open Source                                                                                                                                                                                                                                                                 |
| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Graph Memory**                     | Native, always-on graph over extracted entities; connections feed directly into the ranking `score` ([details](https://docs.mem0.ai/platform/features/graph-memory))          | Removed. OSS previously connected external graph stores (Neo4j, Memgraph, Kuzu, Apache AGE); that integration was dropped when the v3 pipeline landed. OSS still extracts entities and uses them to boost ranking, but there is no queryable graph and no `relations` field |
| **Memory Decay**                     | Opt-in per project; reinforces recently-used memories and gently dampens stale ones at search time ([details](https://docs.mem0.ai/platform/features/memory-decay))           | Not supported. Passing `decay` raises `"The decay parameter is not supported by the OSS Memory SDK."`                                                                                                                                                                       |
| **Temporal Reasoning**               | Boosts memories whose event dates match the time expressed in a query (`timestamp` / `reference_date`) ([details](https://docs.mem0.ai/platform/features/temporal-reasoning)) | Not supported. Both parameters raise a "not supported by the OSS Memory SDK" error                                                                                                                                                                                          |
| **Dream (background consolidation)** | Continuously synthesizes patterns, supersedes outdated facts, and merges duplicates per user ([details](https://docs.mem0.ai/platform/features/dream))                        | Not available                                                                                                                                                                                                                                                               |



| Feature                  | Platform                                                                                                                                                                                                                                                                                                                                                                       | Open Source                                                                                                                                                                                                                                                                               |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Custom categories**    | Set per project or per `add` call ([details](https://docs.mem0.ai/platform/features/custom-categories))                                                                                                                                                                                                                                                                                            | Not supported. `Memory.add()` has no `custom_categories` parameter, and OSS project updates are rejected outright                                                                                                                                                                         |
| **Webhooks**             | Project-scoped HTTP callbacks on memory and ingest events ([details](https://docs.mem0.ai/platform/features/webhooks))                                                                                                                                                                                                                                                                             | Not available                                                                                                                                                                                                                                                                             |
| **Memory Export**        | Schema-driven structured export jobs over filtered memories ([details](https://docs.mem0.ai/platform/features/memory-export))                                                                                                                                                                                                                                                                      | Not available                                                                                                                                                                                                                                                                             |
| **Batch operations**     | `batch_update` and `batch_delete` apply up to 1000 memories per call                                                                                                                                                                                                                                                                                                           | Not available. Loop over the single-memory `update`/`delete` calls                                                                                                                                                                                                                        |
| **Feedback**             | `feedback(memory_id, ...)` records `POSITIVE`, `NEGATIVE`, or `VERY_NEGATIVE` signals against a retrieved memory ([details](https://docs.mem0.ai/platform/features/feedback-mechanism))                                                                                                                                                                                                            | Not available                                                                                                                                                                                                                                                                             |
| **Summaries**            | `get_summary(filters)` returns a generated summary over the matching memories                                                                                                                                                                                                                                                                                                  | Not available                                                                                                                                                                                                                                                                             |
| **Filterable fields**    | Top-level filter keys come from a fixed allowlist: `user_id`, `agent_id`, `app_id`, `run_id`, `created_at`, `updated_at`, `timestamp`, `expiration_date`, `categories`, `metadata`, `keywords`, `memory_ids`, plus the `AND`/`OR`/`NOT` operators and a few endpoint-specific extras. Any other key is rejected with a `400` ([details](https://docs.mem0.ai/platform/features/v2-memory-filters)) | Any metadata key is filterable directly, with no allowlist                                                                                                                                                                                                                                |
| **Comparison operators** | Depends on the field: `metadata` accepts `eq`, `ne`, `contains`; `categories` accepts `contains`, `in`; the date fields accept the range operators                                                                                                                                                                                                                             | The filter layer accepts the full set on any key: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `nin`, `contains`, `icontains`. What actually runs depends on the vector store you configured, so confirm operator coverage for yours ([details](https://docs.mem0.ai/open-source/features/metadata-filtering)) |



| Channel                     | Platform                                                    | Open Source                                                       |
| --------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------- |
| **Community & maintainers** | Discord, GitHub Discussions, direct calls with the founders | Same: Discord, GitHub Discussions, direct calls with the founders |

Support channels are currently the same for both. If you need something contractual (a support SLA, for example), ask before assuming it exists: it is not documented as a Platform benefit today.

</AccordionGroup>

User Profiles are not listed above. The feature is still being finalized internally, so this page does not present it as an available Platform benefit.


Decision Guide

Choose Platform if you want:

  • Zero infrastructure: no vector store, LLM, or embedder to provision or tune.
  • The v3-only ranking features: Graph Memory, Memory Decay, Temporal Reasoning, and Dream.
  • App-level and org/project-level scoping, plus webhooks, memory export, and custom categories.

Choose Open Source if you need:

  • Full data control: host everything on your own infrastructure.
  • Custom configuration: your own vector DB, LLM provider, and embedder (25 vector stores, 18 LLM providers, 11 embedders at the time of writing).
  • Extensibility: modify the codebase, add custom providers, and contribute back.
  • Cost optimization: local LLMs (Ollama), self-hosted vector DBs, no usage-based billing.

Still not sure?

Sign up and test the Platform with our free tier. No credit card required.



Clone the repo and run locally to see how it works. Star us while you're there!