MimirDocumentationSign in
Documentation

REST API

The REST surface mirrors the MCP tools one to one. Authentication is the same bearer token, the same limits apply, and every call writes one audit row. Use it when an agent or a script cannot speak MCP, or when you want to look at a response with curl before wiring it into an agent.

Authentication

bash
export MIMIR_URL=https://mimir.example.com
export MIMIR_TOKEN=mimir_... # Settings → API keys, shown once

Send the token as Authorization: Bearer $MIMIR_TOKEN on every request. A missing or revoked token answers:

json
{ "error": "unauthorized", "code": "unauthorized" }

Conventions

Projects are addressed by slug; memories by path, split into URL segments. Bodies are JSON, responses are JSON unless a digest is requested as text. Dates are ISO 8601 with a UTC offset. A failure always carries both a human message in error and a stable machine code in code.

Walk through it

1. Which projects can I reach? The answer already respects grants, so a caller only ever sees what it may read.

bash
curl -s "$MIMIR_URL/api/v1/projects" \
-H "Authorization: Bearer $MIMIR_TOKEN"
json
{
"projects": [
{
"id": "0f0c…",
"slug": "mimir",
"name": "mimir",
"role": "write",
"memoryCount": 42,
"archived": false
}
]
}

2. What does this project know? The tree is titles only — the cheap orientation read before a search.

bash
curl -s "$MIMIR_URL/api/v1/projects/mimir/tree?path=deploys&depth=2" \
-H "Authorization: Bearer $MIMIR_TOKEN"
json
{
"memories": [
{
"path": "deploys/rollback",
"title": "How to roll back a release",
"hasSummary": true,
"updatedAt": "2026-10-25T18:04:11.000Z"
}
]
}

3. Read one memory. The path is the URL; encode spaces and unusual characters as usual.

bash
curl -s "$MIMIR_URL/api/v1/projects/mimir/memory/deploys/rollback" \
-H "Authorization: Bearer $MIMIR_TOKEN"
json
{
"id": "5b1e…",
"path": "deploys/rollback",
"title": "How to roll back a release",
"summary": "Compose: down, check out the previous tag, up.",
"body": "Roll back with docker compose down, then up on the previous tag.",
"kind": "note",
"updatedAt": "2026-10-25T18:04:11.000Z"
}

4. Write one. Writing an existing path replaces the body and keeps the old one as a version. A provider that is down does not fail this call — the memory is stored and the summary and vector arrive later.

bash
curl -s -X PUT "$MIMIR_URL/api/v1/projects/mimir/memory/deploys/rollback" \
-H "Authorization: Bearer $MIMIR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"body": "Roll back with docker compose down, then up on the previous tag.",
"title": "How to roll back a release",
"kind": "runbook"
}'
json
{ "path": "deploys/rollback", "created": false }

5. Search. Keyword and meaning, fused; path_prefix keeps a deployment note out of an authentication answer.

bash
curl -s -X POST "$MIMIR_URL/api/v1/projects/mimir/search" \
-H "Authorization: Bearer $MIMIR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "query": "how do I roll back", "path_prefix": "deploys", "limit": 5 }'
json
{
"results": [
{
"path": "deploys/rollback",
"title": "How to roll back a release",
"summary": "Compose: down, check out the previous tag, up.",
"score": 0.0328
}
]
}

score is a fused rank score, not a probability: it is only comparable within one response, and a higher number is better.

6. Session start. The digest is what an agent should read first; format=text gives a shell hook something it can inject without JSON parsing.

bash
curl -s "$MIMIR_URL/api/v1/projects/mimir/digest?budget_tokens=400&format=text" \
-H "Authorization: Bearer $MIMIR_TOKEN"
text
deploys
- deploys/rollback — How to roll back a release
  Compose: down, check out the previous tag, up.

conventions
- conventions/state-management — Zustand, one store per feature
… 38 more memories, truncated to fit 400 tokens

7. History and restore. A version id comes from the versions list; a restore writes the old body back as a new version, so it can itself be undone.

bash
curl -s "$MIMIR_URL/api/v1/projects/mimir/versions?path=deploys/rollback" \
-H "Authorization: Bearer $MIMIR_TOKEN"
curl -s -X POST "$MIMIR_URL/api/v1/projects/mimir/versions/9ac2…/restore" \
-H "Authorization: Bearer $MIMIR_TOKEN"
json
{
"versions": [
{
"id": "9ac2…",
"path": "deploys/rollback",
"title": "How to roll back a release",
"kind": "note",
"source": "agent",
"updatedAt": "2026-10-25T17:40:02.000Z",
"createdAt": "2026-10-25T17:40:02.000Z",
"bytes": 61
}
]
}
{ "restored": true, "path": "deploys/rollback" }

8. Import a batch. Paths that are too large, empty or malformed are skipped and reported rather than failing the whole call.

bash
curl -s -X POST "$MIMIR_URL/api/v1/projects/mimir/ingest" \
-H "Authorization: Bearer $MIMIR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"prefix": "docs",
"files": [
{ "path": "architecture.md", "body": "# Architecture
One container…" },
{ "path": "empty.md", "body": "" }
]
}'
json
{
"written": 1,
"skipped": [{ "path": "docs/empty.md", "reason": "body must not be empty" }]
}

Routes

Method and pathBodyReturns
GET /api/v1/me—{ id, email, name, role, mfaEnabled }
GET /api/v1/projects—{ projects: [{ id, slug, name, role, memoryCount, archived }] }
GET /api/v1/projects/:slug/tree?path=&depth=—{ memories: [{ path, title, hasSummary, updatedAt }] }
GET /api/v1/projects/:slug/memory/:path—one memory
PUT /api/v1/projects/:slug/memory/:path{ body, title?, kind? }{ path, created }
DELETE /api/v1/projects/:slug/memory/:path—{ deleted: true }
POST /api/v1/projects/:slug/search{ query, path_prefix?, limit? }{ results: [{ path, title, summary, score }] }
GET /api/v1/projects/:slug/digest?budget_tokens=&format=text—{ text, memoryCount, truncated }
GET /api/v1/projects/:slug/versions?path=—{ versions: [{ id, path, title, kind, source, updatedAt, createdAt, bytes }] }
POST /api/v1/projects/:slug/versions/:id/restore—{ restored: true, path }
POST /api/v1/projects/:slug/ingest{ files: [{ path, body }], prefix? }{ written, skipped: [{ path, reason }] }

Errors

CodeStatusMeaning
unauthorized401No token, or a token that was revoked
forbidden403A valid user without the grant this call needs
not_found404No such project, memory or version, or one you cannot see
invalid_params400A field is missing or the wrong type
invalid_path400A memory path is malformed after normalisation
body_too_large413The memory body is over 256 KB
rate_limited429The per-user rate limit; read Retry-After
internal500{ "error": "internal error" } — the database message never leaves the server

Limits

256 KB per memory body, 1 MiB per request, 100 files and 2 MB per ingest, 60 calls per minute per user. A project over its limits is not throttled per project — the ceiling is the caller.

REST API