Skip to main content
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
Filters were introduced in v1.0.0 to provide precise control over memory retrieval.

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

Available fields and operators

Entity fields

FieldOperatorsExample
user_ideq, ne, in, *{"user_id": "user_123"}
agent_ideq, ne, in, *{"agent_id": "*"}
app_ideq, ne, in, *{"app_id": {"in": ["app1", "app2"]}}
run_ideq, ne, in, *{"run_id": "*"}

Time fields

FieldOperatorsExample
created_atgt, gte, lt, lte, eq, ne{"created_at": {"gte": "2024-01-01"}}
updated_atgt, gte, lt, lte, eq, ne{"updated_at": {"lt": "2024-12-31"}}
timestampgt, gte, lt, lte, eq, ne{"timestamp": {"gt": "2024-01-01"}}

Content fields

FieldOperatorsExample
categorieseq, ne, in, contains{"categories": {"in": ["finance"]}}
metadataeq, ne, contains{"metadata": {"key": "value"}}
keywordscontains, icontains{"keywords": {"icontains": "invoice"}}

Special fields

FieldOperatorsExample
memory_idsin{"memory_ids": ["id1", "id2"]}
The * wildcard matches any non-null value. Records with null values for that field are excluded.
Use operator keywords exactly as shown (eq, ne, gte, etc.). SQL-style symbols such as >= or != are rejected by the Platform API.

Common filter patterns

Use these ready-made filters to target typical retrieval scenarios without rebuilding logic from scratch.
# 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)
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.
# Multi-value metadata workaround
filters = {
    "OR": [
        {"metadata": {"type": "semantic"}},
        {"metadata": {"type": "episodic"}}
    ]
}
Find memories containing specific text, categories, or metadata values.
# 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"}}
    ]
}

Time-based filtering

Retrieve memories within specific date ranges using time operators.
# 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"}}
    ]
}

Multiple criteria

Combine various filters for complex queries across different dimensions.
# 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"]}
    ]
}
# 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": "*"}
    ]
}

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

Best practices

The root must be AND, OR, or NOT with an array of conditions.
Use "*" to match any non-null value for a field.
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.

Troubleshooting

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:
{"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 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"}}

FAQ

Yes. The root must be a logical operator with an array.
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.
Use keywords with contains (case-sensitive) or icontains (case-insensitive).
{
    "AND": [
        {"user_id": "user_123"},
        {"OR": [
            {"categories": "finance"},
            {"categories": "health"}
        ]}
    ]
}

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.