Memories Endpoints
Memories are the core data units in zkstash. These endpoints allow you to store, retrieve, and manage the long-term memory of your agents.
Create Memory
This endpoint supports two modes:
- Extraction Mode: Pass a
conversationarray to let zkstash’s AI extract memories automatically. - Direct Mode: Pass a
memoriesarray to store structured data directly without LLM processing.
Endpoint: POST /memories
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
agentId | string | Yes | Unique identifier for the agent. |
subjectId | string | No | Subject ID for multi-tenant isolation. |
conversation | array | No* | List of message objects for AI extraction. |
memories | array | No* | List of structured memories to store directly. |
threadId | string | No | Identifier for the conversation thread. |
schemas | string[] | No | List of schema names to use for extraction. |
ttl | string | No | Default TTL for all memories (e.g., "1h", "24h", "7d"). |
expiresAt | number | No | Default expiry timestamp (ms) for all memories. |
Note: Either
conversationormemoriesmust be provided. Incremental extraction is automatic—if you provide messageids, the server will skip any messages it has already processed.
Conversation Object:
{
"id": "msg_123", // Recommended for automatic incremental extraction
"role": "user" | "assistant" | "system",
"content": "string"
}Direct Memory Object:
{
"kind": "UserProfile", // Must match a registered schema
"data": { "name": "Alice", "age": 30 },
"id": "mem_123", // Optional (see below)
"ttl": "7d", // Optional: memory-specific TTL
"expiresAt": 1735689600000 // Optional: explicit expiry timestamp (ms)
}TTL Priority: Memory-level
ttl/expiresAtoverrides request-level defaults. Memories without TTL are permanent.
ID Behavior:
- Schemas with
uniqueOn(e.g.,UserProfile): ID is auto-generated. New memories automatically supersede existing ones matching the unique fields.- Schemas without
uniqueOn(e.g.,Interaction): Omitidto create, includeidto update an existing record.
Example: Extraction Mode
{
"agentId": "agent-007",
"conversation": [
{ "role": "user", "content": "My favorite color is blue." },
{ "role": "assistant", "content": "Noted." }
]
}Example: Direct Mode
{
"agentId": "agent-007",
"memories": [
{ "kind": "UserProfile", "data": { "favoriteColor": "blue" } }
]
}Example: With TTL
{
"agentId": "agent-007",
"ttl": "24h",
"memories": [
{ "kind": "SessionContext", "data": { "task": "booking" } },
{ "kind": "Reminder", "data": { "text": "Follow up" }, "ttl": "1h" }
]
}Response
Returns the created and updated memories.
{
"success": true,
"created": [
{
"kind": "UserProfile",
"metadata": { "favoriteColor": "blue" }
}
],
"updated": []
}Search Memories
Search for memories using semantic similarity and metadata filters. Supports searching your own memories and shared memories from other agents via grants.
Endpoint: GET /memories/search
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | Yes | The natural language query to search for (e.g., “user preferences”). |
agentId | string | No | Filter by agent ID. |
subjectId | string | No | Filter by subject ID (tenant). |
threadId | string | No | Filter by specific thread ID. |
kind | string | No | Filter by memory schema type (e.g., UserProfile). |
tags | string | No | Comma-separated list of tags to filter by. |
limit | number | No | Max number of results (default: 10). |
mode | string | No | Response format: llm (default), answer (QA), or map (Graph). |
scope | string | No | Search scope: own, shared, or all (default). See Memory Sharing. |
Response Modes
| Mode | Description |
|---|---|
llm | Default. Returns semantically structured memories optimized for LLM consumption. |
answer | Returns a concise, grounded answer to the query. |
map | Returns a memory map with topical clusters. |
Headers
| Header | Type | Description |
|---|---|---|
X-Grants | string | Base64-encoded JSON array of signed grants for accessing shared memories. |
Search Scope
The scope parameter controls which namespaces are searched:
| Scope | Searches Own | Searches Shared | Notes |
|---|---|---|---|
own | ✅ | ❌ | Only your memories, grants are ignored |
shared | ❌ | ✅ | Only granted namespaces (requires grants) |
all | ✅ | ✅ | Both own and granted (default) |
Using Grants
To search shared memories, include grants in the X-Grants header:
# Create base64-encoded grants
GRANTS=$(echo '[{"p":{"f":"0xGrantor...","g":"0xYourAddress...","e":1735689600},"s":"0x...","c":"evm"}]' | base64)
# Search with grants
curl "https://api.zkstash.ai/v1/memories/search?query=findings&agentId=researcher" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Grants: $GRANTS"Example Request
GET /memories/search?query=What+does+he+like?&agentId=agent-007&limit=5Response (LLM Mode - Default)
The default llm mode returns semantically structured memories optimized for LLM consumption:
{
"success": true,
"memories": [
{
"id": "mem_123",
"kind": "UserProfile",
"quality": {
"relevance": 0.89,
"confidence": 0.95
},
"data": {
"favoriteColor": "blue",
"theme": "dark"
},
"context": {
"when": "2024-01-15T10:30:00Z",
"mentions": [
{ "name": "User", "type": "person" }
],
"tags": ["preferences"],
"isLatest": true
},
"source": "own"
},
{
"id": "mem_456",
"kind": "ResearchFinding",
"quality": {
"relevance": 0.85,
"confidence": 0.90
},
"data": {
"topic": "AI agents",
"summary": "Key findings about agent memory..."
},
"context": {
"mentions": [
{ "name": "AI agents", "type": "concept" }
],
"tags": ["research"],
"isLatest": true
},
"source": "shared:researcher"
}
],
"searchedAt": "2024-01-20T14:30:00Z"
}Response Fields
| Field | Description |
|---|---|
id | Memory identifier for updates/references. |
kind | Schema type (e.g., UserProfile, temporal_event). |
quality.relevance | Search relevance score (0-1). |
quality.confidence | Extraction certainty (0-1). |
data | User-defined schema fields (the actual content). |
context.when | ISO 8601 event timestamp (if temporal). |
context.mentions | Typed entity references for disambiguation. |
context.tags | Topical tags. |
context.isLatest | true if not superseded by newer memory. |
source | Provenance: own, shared, or shared:{agentId}. |
searchedAt | Query timestamp for relative temporal reasoning. |
Get Memory
Retrieve a single memory by its ID.
Endpoint: GET /memories/[id]
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The unique ID of the memory. |
Response
{
"success": true,
"memory": {
"id": "mem_123...",
"kind": "UserProfile",
"data": { ... }
}
}Update Memory
Update a memory’s metadata or expiration.
Endpoint: PATCH /memories/[id]
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
tags | string[] | No | New list of tags for the memory. |
expiresAt | number | null | No | Set expiry timestamp (ms), or null to remove expiry and make permanent. |
Example: Update Tags
{
"tags": ["important", "verified"]
}Example: Set Expiry
{
"expiresAt": 1735689600000
}Example: Remove Expiry (Make Permanent)
{
"expiresAt": null
}Response
{
"success": true,
"memory": { ... }
}Delete Memory
Delete a single memory by ID.
Endpoint: DELETE /memories/[id]
Response
{
"success": true
}Batch Operations
For improved performance when working with multiple memories, use batch endpoints. Batch operations use flat pricing (2× single operation) regardless of batch size, offering significant savings at scale.
| Endpoint | Cost | Max Items | vs Individual |
|---|---|---|---|
batch/search | 4 CC | 10 queries | Up to 80% savings |
batch/delete | 2 CC | 100 IDs | Up to 98% savings |
batch/update | 4 CC | 100 IDs | Up to 98% savings |
Batch Search
Search multiple queries in parallel.
Endpoint: POST /memories/batch/search
| Field | Type | Required | Description |
|---|---|---|---|
queries | array | Yes | Array of search queries (max 10). |
scope | string | No | Search scope: own, shared, or all (default). |
{
"queries": [
{ "query": "user preferences", "filters": { "agentId": "assistant" } },
{ "query": "recent tasks", "filters": { "agentId": "assistant" } }
]
}Response:
{
"success": true,
"results": [
{ "memories": [...] },
{ "memories": [...] }
]
}Batch Delete
Delete multiple memories by ID.
Endpoint: POST /memories/batch/delete
| Field | Type | Required | Description |
|---|---|---|---|
ids | string[] | Yes | Array of memory IDs to delete (max 100). |
{
"ids": ["mem_abc123", "mem_def456"]
}Response:
{
"success": true,
"deleted": 2
}Batch Update
Update multiple memories with the same changes.
Endpoint: POST /memories/batch/update
| Field | Type | Required | Description |
|---|---|---|---|
ids | string[] | Yes | Array of memory IDs to update (max 100). |
update | object | Yes | Update payload (same as single update). |
{
"ids": ["mem_abc123", "mem_def456"],
"update": {
"tags": ["archived"],
"expiresAt": 1735689600000
}
}Response:
{
"success": true,
"updated": 2
}