Memory Operations
Memory operations provide the primary interface for storing and retrieving contextual information. The system maintains dual storage: FalkorDB serves as the source of truth for graph data, while Qdrant provides semantic search capabilities.
All operations except /health require authentication via AUTOMEM_API_TOKEN. Authentication tokens can be passed via:
Authorization: Bearer <token>header (recommended)X-API-Key: <token>header?api_key=<token>query parameter
Available Endpoints
Section titled “Available Endpoints”| Endpoint | Method | Purpose | Authentication |
|---|---|---|---|
/memory | POST | Create new memory | API Token |
/memory/batch | POST | Batch ingest up to 500 memories | API Token |
/memory/:id | GET | Retrieve single memory by ID | API Token |
/recall | GET | Search/retrieve memories | API Token |
/memory/:id | PATCH | Update existing memory | API Token |
/memory/:id | DELETE | Remove memory | API Token |
/memory/by-tag | GET | Filter by tags (paginated) | API Token |
/memory/by-tag | DELETE | Bulk delete by tag | API Token |
POST /memory — Creating Memories
Section titled “POST /memory — Creating Memories”Creates a new memory node in FalkorDB and optionally stores its embedding in Qdrant. The operation executes synchronously for the primary write but queues background enrichment and embedding generation tasks.
Request Format
Section titled “Request Format”Required Fields:
content(string): Memory content, minimum 1 character
Optional Fields:
| Field | Type | Description |
|---|---|---|
type | string | One of Decision, Pattern, Preference, Style, Habit, Insight, Context (default: auto-classified) |
confidence | float | 0.0–1.0, classification confidence (default: 0.9 if type provided) |
tags | array | Categorization tags, supports hierarchical syntax with : or / delimiters |
importance | float | 0.0–1.0, importance score (default: 0.5) |
metadata | object | Arbitrary JSON metadata |
timestamp | string | ISO 8601 timestamp (default: current UTC time) |
embedding | array | Vector matching VECTOR_SIZE config (auto-generated if omitted) |
t_valid, t_invalid | string | Temporal validity bounds |
updated_at, last_accessed | string | Tracking timestamps |
The API ignores any caller-supplied id and generates a UUID server-side for every new memory.
Memory Data Model:
graph LR
subgraph "Request Schema"
Content["content<br/>string (required)<br/>Memory text"]
Type["type<br/>string (optional)<br/>Decision/Pattern/etc"]
Tags["tags<br/>string[] (optional)<br/>Categorization"]
Importance["importance<br/>float (0-1)<br/>Priority score"]
Metadata["metadata<br/>object (optional)<br/>Custom fields"]
Embedding["embedding<br/>float[] (optional)<br/>Pre-computed vector"]
Timestamp["timestamp<br/>ISO8601 (optional)<br/>Defaults to now"]
end
subgraph "Stored Properties"
ID["id<br/>UUID<br/>Auto-generated"]
TagPrefixes["tag_prefixes<br/>string[]<br/>Auto-computed"]
Confidence["confidence<br/>float (0-1)<br/>Type confidence"]
Enriched["enriched<br/>boolean<br/>Processing status"]
LastAccessed["last_accessed<br/>ISO8601<br/>Access tracking"]
UpdatedAt["updated_at<br/>ISO8601<br/>Modification time"]
end
Content --> ID
Type --> Confidence
Tags --> TagPrefixes
Timestamp --> UpdatedAt
Embedding --> ID
Example Request
Section titled “Example Request”curl -X POST https://your-automem-instance/memory \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "content": "Chose PostgreSQL over MongoDB. Need ACID guarantees for transactions. Impact: ensures data consistency.", "type": "Decision", "tags": ["project-alpha", "database", "architecture"], "importance": 0.9, "metadata": { "files_modified": ["db/config.py"], "alternatives": ["MongoDB", "MySQL"] } }'Memory Type Classification
Section titled “Memory Type Classification”The system uses MemoryClassifier to automatically determine memory type when not explicitly provided:
Classification Strategy:
- Explicit Type: If
typeparameter provided, use directly withconfidence=0.9 - Regex Patterns: Match content against predefined patterns for each memory type (fast, free)
- LLM Classification: Use OpenAI GPT-4o-mini as fallback for complex content
- Default: Assign
Contexttype with low confidence (0.3) if all methods fail
Memory Type Reference:
| Type | Typical Importance | Use Cases |
|---|---|---|
Decision | 0.9–1.0 | Architecture choices, library selections, pattern decisions |
Pattern | 0.7–0.9 | Code patterns, architectural patterns, reusable solutions |
Insight | 0.7–0.9 | Root cause discoveries, realizations, aha moments |
Preference | 0.6–0.9 | Style choices, tool preferences, workflow preferences |
Style | 0.6–0.8 | Coding conventions, formatting rules |
Habit | 0.5–0.7 | Development workflows, testing practices |
Context | 0.5–0.7 | Feature descriptions, project context, miscellaneous (default) |
Data Flow
Section titled “Data Flow”sequenceDiagram
participant Client
participant POST_memory as "/memory endpoint"
participant Classifier as "MemoryClassifier"
participant Graph as "state.memory_graph<br/>(FalkorDB)"
participant EnrichQ as "state.enrichment_queue"
participant EmbedQ as "state.embedding_queue"
participant Qdrant as "state.qdrant<br/>(QdrantClient)"
Client->>POST_memory: POST /memory<br/>{content, type?, tags, importance}
alt Type Not Provided
POST_memory->>Classifier: classify(content)
Classifier-->>POST_memory: (type, confidence)
end
POST_memory->>POST_memory: _normalize_tag_list(tags)
POST_memory->>POST_memory: _compute_tag_prefixes(tags)
POST_memory->>POST_memory: _normalize_timestamp(timestamp)
POST_memory->>Graph: MERGE Memory node<br/>(id, content, type, tags, importance,<br/>timestamp, metadata, confidence)
Graph-->>POST_memory: Node created
POST_memory->>EnrichQ: enqueue_enrichment(memory_id)
alt Embedding Provided
POST_memory->>Qdrant: upsert(id, embedding, payload)
Qdrant-->>POST_memory: Stored
else No Embedding
POST_memory->>EmbedQ: Queue for generation
end
POST_memory-->>Client: 201 Created<br/>{memory_id, type, confidence,<br/>enrichment: "queued"}
Processing Steps:
- Validation: Extract and validate required fields, normalize tags and timestamps
- Classification: Determine memory type if not provided (regex → LLM → default)
- Tag Processing: Compute hierarchical tag prefixes for efficient filtering
- Graph Write: Execute
MERGEoperation in FalkorDB (immediate, blocking) - Enrichment Queue: Add to background queue for entity extraction and relationship building
- Embedding Handling: Store a provided embedding or queue generation when Qdrant is configured
- Response: Return immediately with memory ID and enrichment status
Tag Processing
Section titled “Tag Processing”Tags support hierarchical structure using : or / delimiters. The system computes all prefixes for efficient filtering. For example, a tag of slack:channel:general generates prefixes: slack, slack:channel, and slack:channel:general.
This enables prefix matching queries like tags=slack to match slack:channel:general, slack:user:U123, etc.
Implementation functions:
normalize_tags()/normalize_tag_list(): Parse comma-separated or array tagscompute_tag_prefixes(): Split on:or/, generate cumulative prefixes, deduplicate and lowercase
Tagging Conventions (from platform templates):
Tags are bare strings. The shipped memory policy forbids platform and date-stamped tags; use a project/domain tag plus a category instead, and use t_valid / t_invalid for facts with a shelf life.
| Memory Type | Tag Pattern | Example |
|---|---|---|
| Project Decision | [project, decision] | ["ecommerce", "decision"] |
| Bug Fix | [project, bug-fix, component] | ["api-gateway", "bug-fix", "auth"] |
| Code Pattern | [project, pattern, component] | ["frontend", "pattern", "react"] |
| User Preference | [preference, domain] | ["preference", "code-style"] |
| Personal Note | [personal, category] | ["personal", "health"] |
Content Size Governance
Section titled “Content Size Governance”The MCP store_memory tool enforces a two-tier content size system:
| Limit Type | Threshold | Behavior |
|---|---|---|
| Target | 150–300 chars | Ideal size for semantic search quality |
| Soft Limit | 500 chars | Warning issued; backend may auto-summarize |
| Hard Limit | 2000 chars | Rejected immediately with error |
When content exceeds the soft limit, the backend AutoMem service may automatically summarize it using an LLM. The response then includes:
summarized: true— Flag indicating summarization occurredoriginal_length: number— Original content lengthsummarized_length: number— Post-summarization length
Importance Scoring Guidelines
Section titled “Importance Scoring Guidelines”| Range | Category | Examples |
|---|---|---|
| 0.9–1.0 | Critical | User preferences, major architecture decisions, breaking changes, corrections to AI outputs |
| 0.7–0.9 | Important | Patterns discovered, bug fixes with root cause, significant features |
| 0.5–0.7 | Standard | Minor decisions, helpful context, tool selections, configuration notes |
| 0.3–0.5 | Minor | Small fixes, temporary workarounds, low-impact notes |
| 0.0–0.3 | Low | Trivial changes (avoid storing these) |
Success Response (201 Created)
Section titled “Success Response (201 Created)”{ "status": "success", "memory_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "stored_at": "2025-01-15T10:30:00Z", "type": "Decision", "confidence": 0.9, "qdrant": "queued", "embedding_status": "queued", "enrichment": "queued", "metadata": {}, "timestamp": "2025-01-15T10:30:00Z", "updated_at": "2025-01-15T10:30:00Z", "last_accessed": "2025-01-15T10:30:00Z", "query_time_ms": 12.5}For a single store, qdrant is stored, failed, queued, unconfigured, or null: it is stored when a supplied embedding is upserted, failed when that upsert fails, queued when generation is queued, unconfigured when no Qdrant client is configured, and null when an embedding is supplied while Qdrant is unavailable.
MCP Tool: store_memory
Section titled “MCP Tool: store_memory”When using AutoMem via MCP, the store_memory tool corresponds to POST /memory:
Required Parameters:
content(string): The memory content. Must be under 2000 characters (hard limit).
Optional Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
tags | string[] | [] | Tags for categorization and filtering |
importance | number (0.0–1.0) | 0.5 | Importance score affecting recall ranking |
embedding | number[] | auto-generated | Vector matching VECTOR_SIZE config (default 1024, truncated from provider native dimensions via OpenAI dimensions parameter) for semantic search |
metadata | object | {} | Structured metadata (files modified, error signatures, etc.) |
timestamp | string (ISO 8601) | now() | When the memory was created |
supersedes_memory_id | string | — | Supersede mode: existing memory ID this new memory replaces or corrects |
supersede_relation | string | INVALIDATED_BY | Relationship from old → new (INVALIDATED_BY or EVOLVED_INTO) |
supersede_reason | string | — | Optional reason stored on the old memory’s metadata |
Supersede mode: Pass content plus supersedes_memory_id to store a replacement, mark the old memory invalid, and create the association. The MCP client orchestrates this as multiple HTTP calls (GET old memory → POST replacement → PATCH old → POST /associate); it is not a single POST /memory pass-through. Batch mode (memories: [...]) does not accept supersede fields.
MCP example:
{ "content": "Login failing on special characters. Root: missing input sanitization. Added validator. Files: auth/login.ts", "tags": ["auth", "bug-fix"], "importance": 0.8, "metadata": { "files_modified": ["auth/login.ts", "auth/validator.ts"], "error_signature": "ValidationError: special_chars", "solution_pattern": "input-sanitization" }}Best practices for content:
✅ "Chose PostgreSQL over MongoDB. Need ACID guarantees for transactions. Impact: ensures data consistency."✅ "Login failing on special characters. Root: missing input sanitization. Added validator. Files: auth/login.ts"✅ "Using early returns for validation. Reduces nesting, improves readability. Applied in all API routes."
❌ "Fixed typo" (too trivial, no context)❌ "Changed config" (what config? why?)❌ "[DECISION] Chose PostgreSQL..." (type prefix redundant, use type field instead)❌ "[3000 character essay...]" (exceeds hard limit)When to store:
- User corrections to AI outputs (importance: 0.9)
- Architectural decisions with rationale (importance: 0.9)
- Bug fixes with root cause (importance: 0.7–0.8)
- Patterns discovered during work (importance: 0.7–0.9)
Never store:
- Trivial edits (typos, formatting, simple renames)
- Already well-documented information
- Temporary file contents or debug output
- Sensitive credentials or API keys
Client retry logic:
- Network errors: Retried up to 3 times (500ms, 1s, 2s delays)
- 5xx server errors: Retried up to 3 times
- 4xx client errors: Not retried (auth/validation issues)
- Timeout: 25 seconds (to fit within Claude Desktop’s 30s MCP timeout)
POST /memory/batch — Batch Ingest
Section titled “POST /memory/batch — Batch Ingest”Ingests up to 500 memories in a single request. Batch items accept content, tags, importance, metadata, timestamp, type, and confidence; batch mode does not accept id, embedding, t_valid, or t_invalid.
Request Format
Section titled “Request Format”{ "memories": [ { "content": "First memory content", "type": "Decision", "tags": ["project-alpha"], "importance": 0.9 }, { "content": "Second memory content", "type": "Context", "tags": ["project-alpha"], "importance": 0.5 } ]}Send the request body as a JSON object with a non-empty memories array. A bare array is rejected with 400 Bad Request. The Content-Type must be application/json.
Example Request
Section titled “Example Request”curl -X POST https://your-automem-instance/memory/batch \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "memories": [ {"content": "Prefer PostgreSQL for transactional workloads", "type": "Preference", "importance": 0.9}, {"content": "Redis used for session caching layer", "type": "Context", "importance": 0.6} ] }'Response Format
Section titled “Response Format”{ "status": "success", "stored": 2, "memory_ids": ["abc-123", "def-456"], "qdrant": "stored (2)", "enrichment": "queued", "query_time_ms": 45.2}Each memory in the batch is written to FalkorDB synchronously. The handler synchronously generates embeddings and upserts successful vectors to Qdrant; only embedding failures are queued for retry. Batch qdrant values are stored (N), stored (N), queued (M), queued, queued (fallback), or unconfigured.
Validation responses use status, code, and message.
Status Codes
Section titled “Status Codes”| Status | Condition |
|---|---|
| 201 Created | All memories stored successfully |
| 400 Bad Request | Malformed, empty, and over-500 requests return 400 Bad Request, as do invalid items and missing content |
| 401 Unauthorized | Missing or invalid API token |
Validation Error Example:
{ "status": "error", "code": 400, "message": "Memory at index 2 missing 'content'"}GET /memory/:id — Retrieve Single Memory
Section titled “GET /memory/:id — Retrieve Single Memory”Retrieves a single memory by its UUID from FalkorDB.
Request Format
Section titled “Request Format”curl "https://your-automem-instance/memory/abc-123-def-456" \ -H "Authorization: Bearer YOUR_TOKEN"Response Format
Section titled “Response Format”{ "status": "success", "memory": { "id": "abc-123-def-456", "content": "Chose PostgreSQL over MongoDB. Need ACID guarantees for transactions.", "type": "Decision", "tags": ["project-alpha", "database"], "importance": 0.9, "confidence": 0.9, "timestamp": "2025-01-15T10:30:00Z", "updated_at": "2025-01-15T10:30:00Z", "last_accessed": "2025-01-16T08:00:00Z", "metadata": {}, "relations": [] }}Status Codes
Section titled “Status Codes”| Status | Condition |
|---|---|
| 404 Not Found | Memory ID does not exist in FalkorDB |
| 401 Unauthorized | Missing or invalid API token |
PATCH /memory/:id — Updating Memories
Section titled “PATCH /memory/:id — Updating Memories”Updates an existing memory node in FalkorDB and synchronizes changes to Qdrant. Content changes trigger automatic re-embedding.
Request Format
Section titled “Request Format”Updatable Fields:
| Field | Notes |
|---|---|
content | Triggers re-embedding if changed |
tags | Recomputes tag_prefixes automatically |
importance, confidence, type | Update directly |
metadata | Replaces existing metadata entirely (not merged) |
t_valid, t_invalid | Update temporal bounds |
timestamp | Override original creation time |
updated_at, last_accessed | Explicit tracking timestamps |
id remains immutable.
Update Data Flow
Section titled “Update Data Flow”sequenceDiagram
participant Client
participant PATCH_endpoint as "PATCH /memory/:id"
participant Graph as "state.memory_graph"
participant Qdrant as "state.qdrant"
Client->>PATCH_endpoint: PATCH /memory/:id<br/>{content?, tags?, importance?}
PATCH_endpoint->>Graph: MATCH (m:Memory {id: $id})<br/>RETURN m
Graph-->>PATCH_endpoint: Existing node or null
alt Memory Not Found
PATCH_endpoint-->>Client: 404 Not Found
end
PATCH_endpoint->>PATCH_endpoint: Validate update fields
PATCH_endpoint->>PATCH_endpoint: _compute_tag_prefixes(tags)
PATCH_endpoint->>Graph: MATCH (m:Memory {id: $id})<br/>SET m.content = $content,<br/>m.tags = $tags,<br/>m.tag_prefixes = $prefixes
Graph-->>PATCH_endpoint: Updated
alt Content Changed
PATCH_endpoint->>Qdrant: generate fresh embedding and upsert it
end
alt Qdrant Available
PATCH_endpoint->>Qdrant: retrieve existing vector or regenerate, then upsert
Qdrant-->>PATCH_endpoint: Vector and payload synchronized
end
PATCH_endpoint->>Graph: MATCH (m:Memory {id: $id})<br/>RETURN m
Graph-->>PATCH_endpoint: Refreshed node
PATCH_endpoint-->>Client: 200 OK<br/>{status: "success", memory_id: "..."}
Update process:
- Validation: Verify memory exists (404 if not found)
- Field Processing: Normalize tags, compute prefixes, validate types
- Graph Update: Execute Cypher
SEToperation with changed fields - Re-embedding: A content change synchronously generates a fresh embedding and upserts it to Qdrant
- Qdrant Sync: Without a content change, retrieve the existing vector (or regenerate it) and upsert the refreshed payload
- Response: Return the successful update after the synchronous graph write; Qdrant upsert failures are logged
Metadata Replace Behavior
Section titled “Metadata Replace Behavior”The metadata field uses replacement semantics — the supplied object replaces the entire existing metadata. Given existing metadata {"key1": "val1"} and an update with {"key2": "val2"}, the result is {"key2": "val2"}.
To preserve existing fields, read the current value first and include all desired keys in the update payload.
Example Request
Section titled “Example Request”curl -X PATCH https://your-automem-instance/memory/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "importance": 0.95, "tags": ["project-alpha", "database", "architecture", "reviewed"] }'Success Response (200 OK)
Section titled “Success Response (200 OK)”{ "status": "success", "memory_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"}MCP Tool: update_memory
Section titled “MCP Tool: update_memory”The update_memory MCP tool corresponds to PATCH /memory/:id.
Input Schema:
| Parameter | Type | Required | Constraints | Description |
|---|---|---|---|---|
memory_id | string | Yes | — | ID of memory to update |
content | string | No | — | New content (replaces existing) |
tags | array[string] | No | — | New tags (replaces existing) |
importance | number | No | 0–1 | New importance score |
metadata | object | No | — | Metadata (replaces existing; omit to preserve current value) |
timestamp | string | No | ISO format | Override creation timestamp |
updated_at | string | No | ISO format | Explicit update timestamp |
last_accessed | string | No | ISO format | Last access timestamp |
type | string | No | — | Memory type classification |
confidence | number | No | 0–1 | Confidence score |
DELETE /memory/:id — Deleting Memories
Section titled “DELETE /memory/:id — Deleting Memories”Removes a memory from both FalkorDB and Qdrant. The operation deletes the node, all its relationships, and the corresponding vector embedding.
No request body is required.
Deletion Data Flow
Section titled “Deletion Data Flow”sequenceDiagram
participant Client
participant DELETE_endpoint as "DELETE /memory/:id"
participant Graph as "state.memory_graph"
participant Qdrant as "state.qdrant"
Client->>DELETE_endpoint: DELETE /memory/:id
DELETE_endpoint->>Graph: MATCH (m:Memory {id: $id})<br/>DETACH DELETE m
Note over Graph: Deletes node + all relationships
Graph-->>DELETE_endpoint: Deleted
alt Qdrant Available
DELETE_endpoint->>Qdrant: delete(collection_name,<br/>points_selector=PointIdsList(<br/>points=[id]))
Qdrant-->>DELETE_endpoint: Vector deleted
else Qdrant Unavailable
Note over DELETE_endpoint: Continue without error
end
DELETE_endpoint-->>Client: 200 OK<br/>{status: "success",<br/>memory_id: "..."}
Deletion process:
- Graph Deletion: Execute Cypher
DETACH DELETEto remove node and relationships - Vector Deletion: Remove embedding from Qdrant (non-blocking failure)
- Response: Confirm deletion success
The DETACH DELETE clause ensures all incoming and outgoing relationships are automatically removed, preventing orphaned edges.
Example Request
Section titled “Example Request”curl -X DELETE https://your-automem-instance/memory/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \ -H "Authorization: Bearer YOUR_TOKEN"Success Response (200 OK)
Section titled “Success Response (200 OK)”{ "status": "success", "memory_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"}MCP Tool: delete_memory
Section titled “MCP Tool: delete_memory”The delete_memory MCP tool supports either DELETE /memory/:id or bulk deletion through DELETE /memory/by-tag.
| Parameter | Type | Required | Description |
|---|---|---|---|
memory_id | string | XOR with tags | ID of memory to delete |
tags | array[string] | XOR with memory_id | Delete every memory matching any tag; matching is exact, case-insensitive, and any-of |
The tool is annotated destructiveHint: true. A single delete preserves the HTTP API’s 404 response when the memory does not exist.
GET /memory/by-tag — Querying by Tags
Section titled “GET /memory/by-tag — Querying by Tags”Retrieves memories filtered by tags, ordered by importance and recency. More performant than /recall when only tag filtering is needed.
Query Parameters
Section titled “Query Parameters”| Parameter | Type | Description | Default |
|---|---|---|---|
tags | string[] | Tag filters (multiple values supported) | Required |
limit | integer | Max results per page (1–200) | 20 |
offset | integer | Number of results to skip for pagination | 0 |
Example Requests
Section titled “Example Requests”# Filter by single tagcurl "https://your-automem-instance/memory/by-tag?tags=project-alpha" \ -H "Authorization: Bearer YOUR_TOKEN"
# Filter by multiple tags (any match)curl "https://your-automem-instance/memory/by-tag?tags=project-alpha&tags=database&limit=20" \ -H "Authorization: Bearer YOUR_TOKEN"
# Paginate through a large tag (page 2, 50 per page)curl "https://your-automem-instance/memory/by-tag?tags=project-alpha&limit=50&offset=50" \ -H "Authorization: Bearer YOUR_TOKEN"Pagination
Section titled “Pagination”Results are ordered by importance DESC, timestamp DESC, id ASC — deterministic for stable paging. Each response includes a has_more boolean indicating whether another page exists. To walk the full result set, increment offset by the response count until has_more is false.
Implementation
Section titled “Implementation”Query Strategy:
- FalkorDB Direct: Queries FalkorDB graph directly using tag filters — does not use Qdrant vector search
- Ordering: Sort by
importance DESC, timestamp DESC, id ASC(deterministic for pagination) - Format: Return paginated stored-memory records; it does not hydrate related memories or include recall scoring
The query leverages tag arrays with direct index usage on the tags property in FalkorDB — no vector search or keyword extraction required, making it more efficient than /recall for tag-only filtering.
DELETE /memory/by-tag — Bulk Delete by Tag
Section titled “DELETE /memory/by-tag — Bulk Delete by Tag”Deletes every memory matching the given tags in both FalkorDB and Qdrant. Useful for clearing stale project scopes, wiping test data, or removing a noisy tag entirely after a recall audit.
Query Parameters
Section titled “Query Parameters”| Parameter | Type | Description | Default |
|---|---|---|---|
tags | string[] | Tag filters (multiple values; matches any) | Required |
Example Request
Section titled “Example Request”# Delete every memory tagged 'scratch' or 'test-run'curl -X DELETE "https://your-automem-instance/memory/by-tag?tags=scratch&tags=test-run" \ -H "Authorization: Bearer YOUR_TOKEN"Success Response (200 OK)
Section titled “Success Response (200 OK)”{ "status": "success", "tags": ["scratch", "test-run"], "deleted_count": 42}Implementation
Section titled “Implementation”The handler pages through matching memories in batches of 200, deletes each batch from both FalkorDB (graph + relations) and Qdrant (vector points), then repeats until no memories remain for the tag set. deleted_count reflects the total across all batches.
Error Responses
Section titled “Error Responses”All endpoints use the shared error envelope:
{ "status": "error", "code": 400, "message": "Description of what went wrong"}Validation failures use the same status / code / message shape; the message identifies the offending field or batch item where applicable.
| Status Code | Meaning |
|---|---|
| 400 Bad Request | Invalid or missing required fields |
| 401 Unauthorized | Missing or invalid API token |
| 404 Not Found | Memory ID does not exist |
| 503 Service Unavailable | FalkorDB unavailable |
Performance Considerations
Section titled “Performance Considerations”Embedding Generation
Section titled “Embedding Generation”- Single stores: A supplied embedding is upserted immediately; otherwise generation is queued when Qdrant is configured.
- Batch stores: Embeddings and Qdrant upserts run synchronously; failed embeddings are queued for retry.
- Fallback: A failed batch Qdrant upsert queues all batch embeddings as a fallback.
Relationship Limits
Section titled “Relationship Limits”The RECALL_RELATION_LIMIT constant (default: 5) caps the number of relationships fetched per memory to prevent performance degradation. For memories with many relationships, only the most relevant are returned.
Tag Prefix Optimization
Section titled “Tag Prefix Optimization”Hierarchical tags precompute all prefixes and store them in tag_prefixes array for O(1) filtering. This enables efficient prefix queries without runtime string operations.
Post-Storage: Creating Associations
Section titled “Post-Storage: Creating Associations”After storing certain memory types, create associations to build the knowledge graph:
| After Storing | Search For | Association Type |
|---|---|---|
| User correction | What’s being corrected | INVALIDATED_BY |
| Bug fix | Original bug discovery | DERIVED_FROM |
| Decision | Alternatives considered | PREFERS_OVER |
| Evolution | Superseded knowledge | EVOLVED_INTO |
See Relationship Operations for details on creating associations.