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"

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"}'
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

© 2026 Steve Hansen. Eidet is MIT licensed.

This site uses Just the Docs, a documentation theme for Jekyll.