From 92287bc6b21c5229737c633420ca96c3f302e467 Mon Sep 17 00:00:00 2001 From: kartik-mem0 Date: Fri, 14 Aug 2026 17:42:54 +0530 Subject: [PATCH] docs: correct the v2 filter allowlist, date operators, and OSS operator scope Probing production surfaced three more inaccuracies: - the allowlist row listed 'text' and 'keywords_search', which only exist on the search endpoint, and omitted the get_all-only fields - the time-field table listed 'eq', which every date field rejects with a 400, and omitted 'expiration_date' entirely - the nested AND/OR example filtered categories with a bare string, which the API rejects with "'categories' value must be a dictionary" Also scoped the OSS operator claim to the filter layer: Chroma falls back to equality for contains/icontains and Pinecone maps neither. --- docs/platform/features/v2-memory-filters.mdx | 11 ++++++----- docs/platform/platform-vs-oss.mdx | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/platform/features/v2-memory-filters.mdx b/docs/platform/features/v2-memory-filters.mdx index 0e725b707..3d5e08d07 100644 --- a/docs/platform/features/v2-memory-filters.mdx +++ b/docs/platform/features/v2-memory-filters.mdx @@ -42,9 +42,10 @@ Filters use a nested JSON structure with logical operators at the root: ### 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"}}` | +| `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 | @@ -421,8 +422,8 @@ A filter object with both an `AND` key and a sibling `OR` key at the same level "AND": [ {"user_id": "user_123"}, {"OR": [ - {"categories": "finance"}, - {"categories": "health"} + {"categories": {"in": ["finance"]}}, + {"categories": {"in": ["health"]}} ]} ] } diff --git a/docs/platform/platform-vs-oss.mdx b/docs/platform/platform-vs-oss.mdx index 4ea74c19a..92bcc27b4 100644 --- a/docs/platform/platform-vs-oss.mdx +++ b/docs/platform/platform-vs-oss.mdx @@ -82,8 +82,8 @@ The core memory loop is identical on both: `add`, `search`, `get`, `get_all`, `u | **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](/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`, `text`, `categories`, `metadata`, `keywords_search`, `memory_ids`, `keywords`, plus the `AND`/`OR`/`NOT` operators. Any other key is rejected with a `400` ([details](/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 full set on any key: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `nin`, `contains`, `icontains` | + | **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](/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](/open-source/features/metadata-filtering)) |