Skip to content

Latest commit

 

History

History
299 lines (218 loc) · 11.8 KB

File metadata and controls

299 lines (218 loc) · 11.8 KB

OpenMind Core API

The OpenMind Core API lets local client applications manage sources, control indexing, search local memory, and ask source-grounded questions without knowing about SQLite, LanceDB, extractors, embeddings, or model-provider internals.

The first API contract is available at:

http://127.0.0.1:8765/api/v1

Interactive OpenAPI documentation is available at http://127.0.0.1:8765/docs while the server is running.

Start the server

Complete openmind setup first, then run:

openmind serve

The server always binds to 127.0.0.1. A different port can be selected without exposing the API to the network:

openmind serve --port 9000

Authentication

OpenMind generates a cryptographically random API token at:

~/.openmind/api_token

The token file is restricted to the current operating-system user on platforms that support POSIX permissions. Show the token with:

openmind api token

Send it with every /api/v1 request:

Authorization: Bearer <openmind-api-token>

GET /health is the only unauthenticated endpoint. It returns only liveness and the OpenMind version.

Rotate a token if it may have been exposed:

openmind api token --rotate

Rotation immediately invalidates the previous token. The running API server picks up the new token automatically.

First request

TOKEN="$(openmind api token)"

curl http://127.0.0.1:8765/api/v1/status \
  -H "Authorization: Bearer $TOKEN"

Search local memory:

curl http://127.0.0.1:8765/api/v1/search \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query":"cabin packing list","limit":5}'

Endpoints

Method Path Purpose
GET /health Public liveness and version check
GET /api/v1/status OpenMind, model, memory, and indexing status
GET /api/v1/providers Available model providers
GET /api/v1/providers/status Current provider connectivity
GET /api/v1/models Available chat, embedding, and image models
POST /api/v1/models/load Load configured or explicitly selected models
PUT /api/v1/models/selection Save validated model choices and optionally load them
GET /api/v1/sources List user-approved source folders
POST /api/v1/sources Add a source folder
DELETE /api/v1/sources/{source_id} Remove a source and its indexed memory
GET /api/v1/ignore-rules List protected and user ignore rules
POST /api/v1/ignore-rules Create an ignore rule
PATCH /api/v1/ignore-rules/{rule_id} Update a user ignore rule
DELETE /api/v1/ignore-rules/{rule_id} Remove a user ignore rule
POST /api/v1/ignore-rules/test Explain whether a path is ignored
POST /api/v1/index/start Start or return the active background indexing job
GET /api/v1/index/status Read indexing progress
POST /api/v1/index/pause Request indexing pause
POST /api/v1/index/resume Resume paused indexing
POST /api/v1/index/stop Request indexing stop
POST /api/v1/watch/start Start source-folder synchronization
GET /api/v1/watch/status Read watcher state and recent activity
POST /api/v1/watch/stop Request watcher shutdown
POST /api/v1/search Search indexed local memory
POST /api/v1/ask Return an answer with structured sources
POST /api/v1/ask/stream Stream answer text as server-sent events
DELETE /api/v1/chat/sessions/{session_id} End an in-memory chat session
GET /api/v1/documents/{file_id} Inspect an indexed file and its text chunks
POST /api/v1/actions/open Open a validated indexed file in its default OS app

Watch mode

Start the local watcher after sources have been added:

curl -X POST http://127.0.0.1:8765/api/v1/watch/start \
  -H "Authorization: Bearer $TOKEN"

The API and CLI use the same watcher service and shared SQLite state. Starting through either interface creates one detached local worker that remains active after the launching client or terminal exits. Repeated start requests return the current active watcher instead of creating duplicates. Status includes watched source paths, queued jobs, the current file, latest event and indexing timestamps, and recent file errors. Stop requests are cooperative and take effect after the current file operation finishes.

The watcher only observes enabled sources already approved through OpenMind. It does not modify or delete user files; a deleted source file only causes its OpenMind metadata and searchable chunks to be removed.

Ignore rules

Client applications can manage the same indexing rules used by the CLI, scanner, and watcher. Create a global rule:

{
  "type": "extension",
  "value": ".mp4",
  "enabled": true,
  "scope": "global",
  "source_id": null,
  "reason": "Video files"
}

For a source-specific rule, set scope to source and provide an existing source_id. Supported types are path, folder_name, file_name, extension, pattern, source_type, max_file_size, and hidden_files.

Test a path without indexing it:

{
  "path": "/Users/example/Documents/private/receipt.pdf",
  "source_id": "src_0123456789ab"
}

The response is explainable:

{
  "ignored": true,
  "matched_rule": {
    "id": "ign_0123456789abcdef",
    "type": "path",
    "value": "/Users/example/Documents/private",
    "reason": "Private folder"
  }
}

System rules are visible but protected from updates and deletion. Adding or enabling a rule immediately removes matching content from LanceDB and marks its file record as skipped; original files are never changed. After disabling or deleting a user rule, start indexing to include newly eligible files.

Sources

Add a folder:

{
  "path": "/Users/example/Documents",
  "recursive": true
}

OpenMind resolves the path and rejects missing files, non-directory paths, and duplicate sources. Removing a source also removes its file records and searchable chunks from OpenMind, but never deletes the original folder or files. Source removal returns the number of file records and memory chunks removed and is refused while indexing or watch mode is active.

{
  "source_id": "src_0123456789ab",
  "source_path": "/Users/example/Documents",
  "files_removed": 42,
  "chunks_removed": 318,
  "user_files_deleted": false
}

Model selection

The running API automatically reloads model and provider settings when openmind models update changes the local configuration. Status, Ask, search, image indexing, model loading, and provider requests therefore use the newly selected chat, embedding, image, and provider settings without restarting openmind serve.

The model fields returned by /api/v1/status are the models currently selected for OpenMind to use. The loaded fields returned by /api/v1/models show whether each model is currently loaded in the model server.

GET /api/v1/models separates chat, embedding, and image-capable models. Save selections with:

{
  "chat_model": "qwen-model-key",
  "embedding_model": "nomic-embedding-key",
  "image_model": "smolvlm-model-key",
  "load": true
}

The API validates every key against models reported by the configured provider. Set chat_model to null for search-only mode or image_model to null to disable image indexing. An embedding model is required.

With load: true, OpenMind unloads previously selected models that are no longer needed before loading the new selection. It does not unload unrelated models that were loaded independently in LM Studio. The response includes separate unload_results and load_results arrays. With load: false, only the saved selection changes; loaded model instances are left untouched.

Search and Ask

Search request:

{
  "query": "OAuth error screenshot",
  "limit": 10
}

Search results contain a file_id, source_id, path, score, snippet, source type, chunk index, and safe metadata. They never contain raw vectors or raw image bytes.

Ask request:

{
  "question": "Do I have screenshots related to login errors?",
  "limit": 8,
  "include_sources": true,
  "reasoning": false,
  "session_id": null
}

The first request creates an in-memory chat session and returns its session_id. Send that ID with follow-up requests to continue the same provider conversation without resending the full message history. Every request still searches local memory using its current question and sends fresh retrieved evidence to the model, so changing topics within a session does not reuse the first turn's sources. Sessions expire after four hours of inactivity and end when the API process stops; clients can end one earlier with DELETE /api/v1/chat/sessions/{session_id}.

The synchronous response marks format as markdown, returns only the generated Markdown in answer, and keeps source details in the separate sources field. The answer does not contain an appended Sources section. reasoning defaults to false; set it to true to enable the selected model's reasoning capability and include its reasoning output. Unsupported models return a clear error. Search responses are unchanged.

Use /api/v1/ask/stream with the same request body for server-sent events. Concatenate the text values from every delta event, then render the result as Markdown:

event: meta
data: {"format":"markdown","session_id":"chat_...","reasoning":false}

event: delta
data: {"text":"partial Markdown answer"}

event: sources
data: {"sources":[{"file_id":"file_...","path":"/Users/example/Documents/notes.md"}]}

event: done
data: {"session_id":"chat_..."}

Open indexed files safely

The open action accepts an indexed file_id, not an arbitrary path:

{
  "file_id": "file_0123456789abcdef"
}

Before opening anything, OpenMind verifies that the database record is indexed, the file still exists, and its resolved path remains inside an enabled source folder. The API does not expose delete, move, edit, shell-command, or arbitrary-path actions.

Browser clients and CORS

Cross-origin browser access is disabled by default. Allow only the exact development or application origin that needs access:

openmind serve --allow-origin http://localhost:3000

Repeat --allow-origin for multiple origins. Wildcards, credentials embedded in origins, paths, query strings, and fragments are rejected. Native desktop, mobile, editor, and command-line clients do not need CORS configuration.

Error responses

OpenMind uses standard HTTP status codes:

  • 400 for an invalid product-level operation.
  • 401 for a missing or invalid bearer token.
  • 403 for a recognized but forbidden local action.
  • 404 when a source, job, document, or indexed file is unavailable.
  • 409 when a source folder is already registered.
  • 422 when a request does not match the documented schema.
  • 503 when the configured model provider cannot complete a request.

Error bodies use FastAPI's standard detail field. Client applications should not depend on internal exception text.

Security boundaries

  • The server binds only to 127.0.0.1; there is no public-host option.
  • Private endpoints require bearer authentication, including on localhost.
  • API tokens are generated locally, stored outside the project, omitted from logs, and compared in constant time.
  • CORS is disabled unless exact origins are explicitly supplied.
  • Request schemas reject unknown fields and bound text and result sizes.
  • Only user-approved source folders can be indexed or opened.
  • The API does not expose SQLite, LanceDB, embeddings, vectors, extractor calls, worker internals, raw file downloads, or raw image bytes.

These boundaries are intentional. Client applications consume OpenMind capabilities while storage and provider implementations remain replaceable.