API Reference
Kore Memory exposes a REST API on http://localhost:8765 by default. All endpoints accept and return JSON. Interactive API documentation is available at /docs.
Headers
| Header | Required | Description |
|---|---|---|
Content-Type | Yes (POST/PUT) | Must be application/json |
X-Agent-Id | Optional | Agent namespace identifier. Defaults to "default". |
X-Kore-Key | Conditional | API key. Required for non-localhost requests when KORE_LOCAL_ONLY=0. |
Core Endpoints
Save Memory
POST /save
Save a single memory with optional auto-importance scoring.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
content | string | Yes | Memory text, 3--4000 characters |
category | string | No | One of: general, project, trading, finance, person, preference, task, decision. Default: general |
importance | integer | No | 1 = auto-score, 2--5 = explicit. Default: 1 |
ttl_hours | integer or null | No | Auto-expire after N hours (1--8760). Default: null (never) |
Example:
curl -X POST http://localhost:8765/save \
-H "Content-Type: application/json" \
-H "X-Agent-Id: my-agent" \
-d '{
"content": "User prefers concise responses in Italian",
"category": "preference",
"importance": 4
}'
Response (201):
{
"id": 42,
"content": "User prefers concise responses in Italian",
"category": "preference",
"importance": 4,
"decay_score": 1.0,
"created_at": "2025-01-15T10:30:00Z"
}
Batch Save
POST /save/batch
Save up to 100 memories in a single request.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
memories | array | Yes | Array of memory objects (same schema as single save) |
Example:
curl -X POST http://localhost:8765/save/batch \
-H "Content-Type: application/json" \
-H "X-Agent-Id: my-agent" \
-d '{
"memories": [
{"content": "React 19 supports server components", "category": "project"},
{"content": "Always use parameterized queries", "category": "decision", "importance": 5}
]
}'
Response (201):
{
"saved": 2,
"memories": [
{"id": 43, "importance": 3, "decay_score": 1.0},
{"id": 44, "importance": 5, "decay_score": 1.0}
]
}
Search Memories
GET /search
Search memories using FTS5 full-text or semantic similarity.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
q | string | (required) | Search query |
limit | integer | 10 | Maximum results (1--100) |
offset | integer | 0 | Pagination offset |
category | string | (all) | Filter by category |
semantic | boolean | false | Use semantic search instead of FTS5 |
Example:
curl "http://localhost:8765/search?q=user+preferences&limit=5&semantic=true" \
-H "X-Agent-Id: my-agent"
Response (200):
{
"results": [
{
"id": 42,
"content": "User prefers concise responses in Italian",
"category": "preference",
"importance": 4,
"decay_score": 0.92,
"effective_score": 0.87,
"created_at": "2025-01-15T10:30:00Z",
"tags": ["language", "preference"]
}
],
"total": 1,
"limit": 5,
"offset": 0
}
Results are ranked by effective_score = similarity * decay * importance. This ensures that relevant, recent, and important memories always appear first.
Timeline
GET /timeline
Retrieve chronological history for a subject.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
subject | string | (required) | Subject to query |
limit | integer | 20 | Maximum results |
offset | integer | 0 | Pagination offset |
Example:
curl "http://localhost:8765/timeline?subject=project+alpha&limit=10" \
-H "X-Agent-Id: my-agent"
Response (200):
{
"results": [
{
"id": 10,
"content": "Project alpha kickoff meeting scheduled",
"category": "task",
"importance": 3,
"decay_score": 0.85,
"created_at": "2025-01-10T09:00:00Z"
},
{
"id": 25,
"content": "Project alpha: decided on React + FastAPI stack",
"category": "decision",
"importance": 5,
"created_at": "2025-01-12T14:00:00Z"
}
],
"total": 2
}
Update Memory
PUT /memories/{id}
Update the content, category, or importance of an existing memory.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | integer | Memory ID |
Request Body (all fields optional):
| Field | Type | Description |
|---|---|---|
content | string | New content (3--4000 characters) |
category | string | New category |
importance | integer | New importance (1--5) |
Example:
curl -X PUT http://localhost:8765/memories/42 \
-H "Content-Type: application/json" \
-d '{"content": "User prefers dark mode (confirmed)", "importance": 5}'
Response (200):
{
"id": 42,
"content": "User prefers dark mode (confirmed)",
"importance": 5,
"updated_at": "2025-01-16T08:00:00Z"
}
Delete Memory
DELETE /memories/{id}
Permanently delete a memory.
Example:
curl -X DELETE http://localhost:8765/memories/42
Response (200):
{"deleted": true, "id": 42}
Tags Endpoints
Add Tags
POST /memories/{id}/tags
Request Body:
{"tags": ["react", "frontend", "v19"]}
Response (200):
{"id": 42, "tags": ["react", "frontend", "v19"]}
List Tags
GET /memories/{id}/tags
Response (200):
{"id": 42, "tags": ["react", "frontend", "v19"]}
Remove Tags
DELETE /memories/{id}/tags
Request Body:
{"tags": ["v19"]}
Response (200):
{"id": 42, "tags": ["react", "frontend"]}
Search by Tag
GET /tags/{tag}/memories
Example:
curl "http://localhost:8765/tags/react/memories" \
-H "X-Agent-Id: my-agent"
Response (200):
{
"tag": "react",
"results": [
{
"id": 42,
"content": "React 19 supports server components",
"category": "project",
"importance": 3,
"decay_score": 0.95
}
],
"total": 1
}
Relations Endpoints
Create Relation
POST /memories/{id}/relations
Create a bidirectional link between two memories.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
target_id | integer | Yes | ID of the target memory |
relation | string | Yes | Relation type (e.g., depends_on, related_to, contradicts, supersedes) |
Example:
curl -X POST http://localhost:8765/memories/42/relations \
-H "Content-Type: application/json" \
-d '{"target_id": 58, "relation": "depends_on"}'
Response (201):
{
"source_id": 42,
"target_id": 58,
"relation": "depends_on",
"created_at": "2025-01-16T09:00:00Z"
}
List Relations
GET /memories/{id}/relations
Returns all bidirectional relations for a memory.
Response (200):
{
"id": 42,
"relations": [
{"target_id": 58, "relation": "depends_on", "created_at": "2025-01-16T09:00:00Z"},
{"target_id": 12, "relation": "related_to", "created_at": "2025-01-15T11:00:00Z"}
]
}
Maintenance Endpoints
Run Decay Pass
POST /decay/run
Recalculate decay scores for all memories using the Ebbinghaus formula. Removes fully decayed memories.
Response (200):
{
"processed": 150,
"decayed": 12,
"removed": 3
}
Compress Memories
POST /compress
Merge memories with cosine similarity above the configured threshold (default: 0.88).
Response (200):
{
"compressed": 5,
"merged_pairs": [
{"kept": 42, "merged": 43},
{"kept": 55, "merged": 56}
]
}
Compression requires the semantic extra. It keeps the more important memory and merges the content of the less important one into it.
Cleanup Expired
POST /cleanup
Remove memories that have exceeded their TTL.
Response (200):
{"removed": 7}
Prometheus Metrics
GET /metrics
Returns Prometheus-formatted metrics for monitoring.
Response (200):
# HELP kore_memories_total Total number of active memories
# TYPE kore_memories_total gauge
kore_memories_total 150
# HELP kore_searches_total Total search requests
# TYPE kore_searches_total counter
kore_searches_total 1234
Archive and Backup Endpoints
Archive Memory
POST /memories/{id}/archive
Soft-delete a memory. It is hidden from search but can be restored.
Response (200):
{"id": 42, "archived": true}
Restore Memory
POST /memories/{id}/restore
Restore a previously archived memory.
Response (200):
{"id": 42, "restored": true}
List Archived
GET /archive
Response (200):
{
"results": [
{"id": 42, "content": "...", "archived_at": "2025-01-16T10:00:00Z"}
],
"total": 1
}
Export Memories
GET /export
Export all active memories as a JSON array.
Response (200):
{
"memories": [
{
"id": 42,
"content": "User prefers dark mode",
"category": "preference",
"importance": 4,
"decay_score": 0.92,
"tags": ["ui"],
"created_at": "2025-01-15T10:30:00Z"
}
],
"exported_at": "2025-01-16T12:00:00Z",
"total": 1
}
Import Memories
POST /import
Import memories from a previous export.
Request Body: The JSON object returned by /export.
Response (200):
{"imported": 42}
Utility Endpoints
Health Check
GET /health
Response (200):
{
"status": "healthy",
"version": "1.0.0",
"capabilities": {
"semantic_search": true,
"fts5": true,
"mcp": true
}
}
Web Dashboard
GET /dashboard
Returns the built-in web dashboard. No build step or npm required. Includes tabs for overview, memories, tags, relations, timeline, maintenance, and backup.
Interactive API Docs
GET /docs
Returns Swagger/OpenAPI interactive documentation.
Status Codes
| Code | Meaning |
|---|---|
| 200 | Success |
| 201 | Created (save, batch save, create relation) |
| 400 | Bad request (malformed JSON, missing required fields) |
| 401 | Unauthorized (missing API key) |
| 403 | Forbidden (invalid API key) |
| 404 | Not found (memory ID does not exist) |
| 422 | Validation error (content too short, invalid category, etc.) |
| 429 | Rate limited |
| 500 | Internal server error |
Rate Limits
Kore applies per-IP and per-path rate limiting. Default limits are generous for single-user deployments. When rate-limited, the response includes:
Retry-After: 5
X-RateLimit-Remaining: 0