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.
Complete openmind setup first, then run:
openmind serveThe server always binds to 127.0.0.1. A different port can be selected without exposing the API to the network:
openmind serve --port 9000OpenMind 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 tokenSend 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 --rotateRotation immediately invalidates the previous token. The running API server picks up the new token automatically.
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}'| 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 |
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.
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.
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
}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 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_..."}
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.
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:3000Repeat --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.
OpenMind uses standard HTTP status codes:
400for an invalid product-level operation.401for a missing or invalid bearer token.403for a recognized but forbidden local action.404when a source, job, document, or indexed file is unavailable.409when a source folder is already registered.422when a request does not match the documented schema.503when 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.
- 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.