REST API Reference
Base URL: http://localhost:19380
All endpoints return JSON. Requests with a body expect Content-Type: application/json.
Authentication
When API key auth is enabled, include the key as a Bearer token:
Authorization: Bearer eidet_abc123...
Health, status, and Web UI endpoints are always public.
Query Parameter Convention
All repo-scoped endpoints accept the filesystem path (or normalized id) via the repo query parameter (not repoId). The service normalizes via RepoIdNormalizer internally. Search uses q (not query). Always URL-encode values.
GET /api/eidet/context?repo=P%3A%5CMyProject
GET /api/eidet/recall?repo=P%3A%5CMyProject&q=authentication
Health & Status
GET /api/health
Quick health check.
curl http://localhost:19380/api/health
{
"status": "ok",
"version": "0.11.0",
"latestVersion": "0.11.1",
"updateAvailable": true
}
latestVersion is whatever the nightly update check last saw — this endpoint reads that cached answer and never calls NuGet itself. It is null until the first check runs, or when update.check is off.
GET /api/status
Detailed service status.
curl http://localhost:19380/api/status
{
"version": "1.0.0",
"status": "running",
"uptime": "2d 5h 30m",
"api": "http://127.0.0.1:19380"
}
Core Operations
POST /api/eidet — Store a Memory
curl -X POST http://localhost:19380/api/eidet \
-H "Content-Type: application/json" \
-d '{
"repo": "P:\\MyProject",
"content": "The auth module uses JWT with RS256 signing",
"type": "observation",
"tags": ["auth", "jwt"],
"importance": 0.7,
"source": "user",
"sessionId": "session-abc",
"supersedes": null
}'
Response (stored):
{ "id": "memories/P--MyProject/observation/a1b2c3d4e5f6", "success": true }
Response (duplicate):
{ "duplicateId": "memories/P--MyProject/observation/existing123", "success": false }
Response (rejected):
{ "reason": "Content blocked by secret scanner: AWS access key detected", "success": false }
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
repo | string | yes | — | Repository/project identifier |
content | string | yes | — | The memory text |
type | string | yes | — | observation, insight, procedure, or heuristic |
tags | string[] | no | [] | Searchable tags |
importance | float | no | 0.5 | 0.0–1.0 importance score |
source | string | no | "claude-session" | Origin identifier |
sessionId | string | no | null | Session tracking |
supersedes | string | no | null | ID of memory this replaces |
GET /api/eidet/recall — Recall Memories
Legacy alias: GET /api/eidet/search (same response).
curl "http://localhost:19380/api/eidet/recall?repo=P%3A%5CMyProject&q=authentication&limit=5&type=insight"
{
"results": [
{
"id": "memories/P--MyProject/insight/abc123",
"repoId": "P--MyProject",
"type": "Insight",
"content": "The auth module uses JWT with RS256...",
"oneLiner": "JWT RS256 auth in auth module",
"tags": ["auth", "jwt"],
"importance": 0.7,
"score": 0.95,
"createdAt": "2026-03-15T10:30:00Z",
"ageDays": 26,
"stalenessWarning": null
}
]
}
| Parameter | Type | Default | Description |
|---|---|---|---|
repo | string | required | Repository identifier |
q | string | required | Search query |
limit | int | 10 | Max results |
type | string | — | Filter by memory type |
GET /api/eidet/context — Get Session Context
Returns the compact L0+L1 context (under 600 tokens) that agents load at session start.
curl "http://localhost:19380/api/eidet/context?repo=P%3A%5CMyProject"
{
"context": "[Memory: 42 entries, 15 observations, 18 insights, 5 procedures, 4 heuristics]\n[I] JWT RS256 auth in auth module\n[P] Deploy: push main → CI → tag → verify\n[H] Always use forward slashes in CI paths\n..."
}
GET /api/eidet/{id} — Get a Memory
curl "http://localhost:19380/api/eidet/memories%2FP--MyProject%2Finsight%2Fabc123"
Returns the full MemoryEntry object with all fields.
PUT /api/eidet/{id} — Update a Memory
Content edits create a new version that supersedes the old one (the new ID is returned); metadata-only edits (tags, importance, etc.) update in place.
curl -X PUT "http://localhost:19380/api/eidet/memories%2FP--MyProject%2Finsight%2Fabc123" \
-H "Content-Type: application/json" \
-d '{"content": "Updated text", "tags": ["auth", "jwt", "verified"], "importance": 0.85}'
{ "id": "memories/P--MyProject/insight/new789", "superseded": "memories/P--MyProject/insight/abc123", "success": true }
DELETE /api/eidet/{id} — Forget a Memory
curl -X DELETE "http://localhost:19380/api/eidet/memories%2FP--MyProject%2Finsight%2Fabc123?reason=outdated"
{ "forgotten": true }
POST /api/eidet/feedback — Echo/Fizzle
Report whether a recalled memory was useful.
curl -X POST http://localhost:19380/api/eidet/feedback \
-H "Content-Type: application/json" \
-d '{"memoryId": "memories/P--MyProject/insight/abc123", "wasUsed": true}'
{ "applied": true }
GET /api/eidet/history/{id} — Version Chain
curl "http://localhost:19380/api/eidet/history/memories%2FP--MyProject%2Finsight%2Fabc123"
{
"chain": [
{ "id": "memories/P--MyProject/insight/abc123", "content": "...", "createdAt": "2026-04-01T..." },
{ "id": "memories/P--MyProject/observation/def456", "content": "...", "createdAt": "2026-03-15T..." }
]
}
GET /api/eidet/stats — Repo Summary + Counts
Compact stats for status bars and UI badges: a one-paragraph text summary plus structured counts by memory type. Counts come from a precomputed map-reduce index — cheap to call frequently.
curl "http://localhost:19380/api/eidet/stats?repo=P%3A%5CMyProject"
{
"repo": "P:\\MyProject",
"summary": "[Memory: 42 entries, 15 observations, 18 insights, 5 procedures, 4 heuristics]\n[I] JWT RS256 auth in auth module",
"counts": { "observation": 15, "insight": 18, "procedure": 5, "heuristic": 4 },
"total": 42
}
Keys in counts are lowercase type names. Missing keys mean zero entries of that type.
Browse & Graph
GET /api/eidet/browse — Paginated Browse
Browse memories without a search query.
curl "http://localhost:19380/api/eidet/browse?repo=P%3A%5CMyProject&skip=0&take=20&type=insight"
{
"repo": "P--MyProject",
"skip": 0,
"take": 20,
"count": 15,
"entries": [ ... ]
}
| Parameter | Type | Default | Description |
|---|---|---|---|
repo | string | required | Repository identifier |
skip | int | 0 | Pagination offset |
take | int | 50 | Page size |
type | string | — | Filter by memory type |
GET /api/eidet/repos — List Repositories
curl http://localhost:19380/api/eidet/repos
{
"repos": [
{ "repoId": "P--MyProject" },
{ "repoId": "P--OtherProject" }
]
}
GET /api/eidet/graph — Knowledge Graph
Returns nodes and edges for visualization.
curl "http://localhost:19380/api/eidet/graph?repo=P%3A%5CMyProject&limit=200"
{
"nodes": [
{ "id": "memories/...", "type": "Insight", "label": "JWT RS256 auth", "importance": 0.8, "tags": ["auth"] }
],
"edges": [
{ "from": "memories/...", "to": "memories/...", "relation": "derived" }
]
}
Operations
POST /api/eidet/intake — Ingest Project Files
Scans CLAUDE.md, README.md, .editorconfig, package.json, etc. and creates seed memories.
curl -X POST "http://localhost:19380/api/eidet/intake?repo=P%3A%5CMyProject"
{ "newCount": 12, "skippedCount": 3 }
POST /api/eidet/consolidate — Run Consolidation
Groups related observations into insights.
| Parameter | Type | Default | Description |
|---|---|---|---|
repo | string | (required) | Repo path |
dry_run | bool | false | Return the candidate clusters without writing anything |
curl -X POST "http://localhost:19380/api/eidet/consolidate?repo=P%3A%5CMyProject&dry_run=true"
{ "candidates": 45, "insightsCreated": 3, "insightsBoosted": 2 }
candidates counts the clusters considered, not the memories written — a cluster whose merge would only restate one of its own observations is reported and then skipped, so insightsCreated is legitimately lower. A converged corpus consolidates to all zeros.
POST /api/maintenance — Run Maintenance
Runs the full maintenance pipeline (TTL expiry, retention, dedup, decay, cleanup, enrichment, consolidation).
curl -X POST "http://localhost:19380/api/maintenance?repo=P%3A%5CMyProject"
A run that finishes within 30 seconds answers 200 with the report. One that does not answers 202 and keeps going — a large repo with drift review enabled runs for well over ten minutes, and blocking for that long made a successful run indistinguishable from a dead service:
{
"runId": "9f1c...",
"repo": "P--MyProject",
"status": "running",
"startedAt": "2026-08-13T09:12:04.7Z",
"poll": "/api/maintenance/runs/9f1c..."
}
Only one pass per repo runs at a time. A caller that gives up and retries starts no second pass — it gets a new run id reporting the same one — and a hand-triggered run cannot collide with the scheduler’s.
GET /api/maintenance/runs/{id} — Poll a Run
curl "http://localhost:19380/api/maintenance/runs/9f1c..."
status is running, completed, or failed; report carries the same body a 200 from the POST would have returned, and error replaces it on failure. Results stay pollable for an hour after the run finishes, then the id 404s. Admin scope, like the POST — the report is an operator surface.
{
"runId": "9f1c...",
"repo": "P--MyProject",
"status": "completed",
"startedAt": "2026-08-13T09:12:04.7Z",
"completedAt": "2026-08-13T09:26:41.2Z",
"report": { "repoId": "P--MyProject", "stages": [] }
}
GET /api/eidet/export — Export as Markdown
curl "http://localhost:19380/api/eidet/export?repo=P%3A%5CMyProject"
Returns plain markdown text with all memories organized by type.
Layers
GET /api/eidet/layers — List Mounted Layers
curl "http://localhost:19380/api/eidet/layers?repo=P%3A%5CMyProject"
POST /api/eidet/layers/mount — Mount a Layer
curl -X POST http://localhost:19380/api/eidet/layers/mount \
-H "Content-Type: application/json" \
-d '{"repo": "P:\\MyProject", "layerId": "shared-knowledge", "type": "shared"}'
POST /api/eidet/layers/sync — Pull/Push Layer Changes
Syncs a mounted shared/base layer with its remote source (if configured).
curl -X POST http://localhost:19380/api/eidet/layers/sync \
-H "Content-Type: application/json" \
-d '{"repo": "P:\\MyProject", "layerId": "shared-knowledge"}'
DELETE /api/eidet/layers/{layerId} — Unmount a Layer
curl -X DELETE "http://localhost:19380/api/eidet/layers/shared-knowledge?repo=P%3A%5CMyProject"
Links
GET /api/eidet/links — List Cross-Repo Links
Returns memories tagged with cross-repo-link for this repo.
curl "http://localhost:19380/api/eidet/links?repo=P%3A%5CMyProject"
POST /api/eidet/links — Create a Top-Level Link
curl -X POST http://localhost:19380/api/eidet/links \
-H "Content-Type: application/json" \
-d '{"repo": "P:\\MyProject", "targetRepo": "P:\\OtherProject", "note": "shares auth module"}'
POST /api/eidet/{id}/links — Attach a Link to a Memory
curl -X POST "http://localhost:19380/api/eidet/memories%2FP--MyProject%2Finsight%2Fabc123/links" \
-H "Content-Type: application/json" \
-d '{"targetId": "memories/P--OtherProject/insight/xyz789", "relation": "derived"}'
DELETE /api/eidet/{id}/links — Remove a Link from a Memory
curl -X DELETE "http://localhost:19380/api/eidet/memories%2FP--MyProject%2Finsight%2Fabc123/links" \
-H "Content-Type: application/json" \
-d '{"targetId": "memories/P--OtherProject/insight/xyz789"}'
Quality, Usage & Monitoring
GET /api/eidet/quality — Quality Report
Recall-quality metrics: echo/fizzle ratios, stale memory counts, dead memories, etc.
curl "http://localhost:19380/api/eidet/quality?repo=P%3A%5CMyProject"
GET /api/eidet/context/preview — Debug View of Context Assembly
Returns the same text as /api/eidet/context plus layer scope and estimated tokens.
curl "http://localhost:19380/api/eidet/context/preview?repo=P%3A%5CMyProject&tokens=600"
{
"repo": "P:\\MyProject",
"maxTokens": 600,
"context": "[Memory: ...] ...",
"estimatedTokens": 540,
"layers": [{ "id": "shared-knowledge", "name": "Shared", "type": "Shared" }],
"crossRepoScope": ["P--MyProject", "shared-knowledge"]
}
GET /api/eidet/usage — Usage Stats
curl "http://localhost:19380/api/eidet/usage?repo=P%3A%5CMyProject&days=30"
GET /api/eidet/usage/timeseries — Daily Buckets
curl "http://localhost:19380/api/eidet/usage/timeseries?repo=P%3A%5CMyProject&days=30"
GET /api/eidet/usage/hourly — Hourly Buckets
curl "http://localhost:19380/api/eidet/usage/hourly?repo=P%3A%5CMyProject"
GET /api/eidet/scheduled-tasks — Scheduler State
Lists tasks queued in the RavenDB-backed scheduler (maintenance, enrichment, etc.).
curl http://localhost:19380/api/eidet/scheduled-tasks
GET /api/eidet/portal — Web Portal Payload
Aggregated dashboard data used by the embedded Web UI.
curl "http://localhost:19380/api/eidet/portal?repo=P%3A%5CMyProject"
Enrichment
POST /api/eidet/enrich — On-Demand Ollama Enrichment
Generates one-liner, summary, foresight hint, and entity supplements for a specific memory.
curl -X POST http://localhost:19380/api/eidet/enrich \
-H "Content-Type: application/json" \
-d '{"id": "memories/P--MyProject/insight/abc123"}'
{ "id": "memories/P--MyProject/insight/abc123", "enriched": true, "oneLiner": "...", "summary": "..." }
Packs (Import/Export)
POST /api/eidet/packs/export — Export as .eidet Pack
curl -X POST "http://localhost:19380/api/eidet/packs/export?repo=P%3A%5CMyProject" -o project.eidet
POST /api/eidet/packs/import — Import a .eidet Pack
curl -X POST http://localhost:19380/api/eidet/packs/import \
-H "Content-Type: application/json" \
-d '{"repo": "P:\\MyProject", "data": "..."}'
MCP over HTTP
POST /mcp — JSON-RPC over HTTP
For MCP clients that use HTTP transport instead of stdio.
curl -X POST http://localhost:19380/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "method": "tools/list", "id": 1}'
Web UI
Open http://localhost:19380/ui in your browser. The Web UI provides:
- Dashboard — repo selector, memory counts, recent memories
- Browser — search and browse with type filters and pagination
- Knowledge Graph — interactive force-directed graph visualization
- Timeline — chronological view grouped by date
- Settings — service status and action buttons