Skip to main content

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

HeaderRequiredDescription
Content-TypeYes (POST/PUT)Must be application/json
X-Agent-IdOptionalAgent namespace identifier. Defaults to "default".
X-Kore-KeyConditionalAPI 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:

FieldTypeRequiredDescription
contentstringYesMemory text, 3--4000 characters
categorystringNoOne of: general, project, trading, finance, person, preference, task, decision. Default: general
importanceintegerNo1 = auto-score, 2--5 = explicit. Default: 1
ttl_hoursinteger or nullNoAuto-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:

FieldTypeRequiredDescription
memoriesarrayYesArray 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:

ParameterTypeDefaultDescription
qstring(required)Search query
limitinteger10Maximum results (1--100)
offsetinteger0Pagination offset
categorystring(all)Filter by category
semanticbooleanfalseUse 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
}
info

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:

ParameterTypeDefaultDescription
subjectstring(required)Subject to query
limitinteger20Maximum results
offsetinteger0Pagination 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:

ParameterTypeDescription
idintegerMemory ID

Request Body (all fields optional):

FieldTypeDescription
contentstringNew content (3--4000 characters)
categorystringNew category
importanceintegerNew 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:

FieldTypeRequiredDescription
target_idintegerYesID of the target memory
relationstringYesRelation 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}
]
}
info

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

CodeMeaning
200Success
201Created (save, batch save, create relation)
400Bad request (malformed JSON, missing required fields)
401Unauthorized (missing API key)
403Forbidden (invalid API key)
404Not found (memory ID does not exist)
422Validation error (content too short, invalid category, etc.)
429Rate limited
500Internal 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