File Palaces iconFilePalaces

API Reference

The File Palaces Python sidecar exposes a local HTTP API on localhost only. In dev mode the port is hardcoded to 52731. Interactive API docs (Swagger UI) are available at http://127.0.0.1:<port>/docs when the sidecar is running.

Base URL

http://127.0.0.1:52731

Endpoints

GET /status

Health check. Returns immediately.

Response

{ "status": "ok", "ready": true }

ready is false while the sidecar is still initialising (embedding model loading).


GET /folders

List all Wings with their current mining status.

Response

[
  {
    "path": "C:\\Users\\you\\Documents\\Work",
    "wing": "work",
    "related_to": [],
    "status": "ready"
  }
]

status values: pending, indexing, ready, error


POST /folders

Add a new folder as a Wing and start mining it.

Request body

{ "path": "/absolute/path/to/folder" }

Response

{ "wing": "folder_slug", "status": "pending" }

Mining starts asynchronously in the background. Subscribe to GET /events to track progress.


DELETE /folders/{wing}

Remove a Wing and delete all its indexed data from the palace.

Path params

ParamTypeDescription
wingstringThe Wing slug (from GET /folders)

POST /chat/stream

Streaming chat endpoint using Server-Sent Events. Optionally scoped to one Wing.

Request body

{
  "messages": [
    { "role": "user", "content": "Summarise the Q3 report" }
  ],
  "wing_filter": "work",
  "session_id": "abc123"
}

wing_filter and session_id are optional.

Response — SSE stream (Content-Type: text/event-stream)

Events arrive in this order:

data: {"sources": [{"text": "...", "wing": "work", "room": "reports", "source_file": "q3.pdf", "similarity": 0.87}]}

data: {"content": "The Q3 report shows "}

data: {"content": "strong revenue growth..."}

data: {"done": true}

On error:

data: {"error": "Model not found: llama3.2"}

GET /search

Semantic and keyword search across the palace without invoking an LLM.

Query params

ParamTypeDefaultDescription
qstringrequiredThe search query
wingstringRestrict to a Wing
top_kinteger8Number of results
thresholdfloat0.3Minimum similarity

Response

[
  {
    "text": "Revenue for Q3 was $4.2M...",
    "wing": "work",
    "room": "reports",
    "source_file": "C:\\...\\q3.pdf",
    "similarity": 0.87
  }
]

GET /palace

Palace statistics.

Response

{
  "wings": 3,
  "rooms": 27,
  "drawers": 14203,
  "palace_path": "C:\\Users\\you\\AppData\\Roaming\\FilePalaces\\palace"
}

GET /settings

Get the current LLM and search configuration.

Response

{
  "provider": "ollama",
  "model": "llama3.2",
  "base_url": null,
  "api_key": null,
  "top_k": 8,
  "threshold": 0.3,
  "system_prompt": "You are a helpful assistant..."
}

PUT /settings

Update LLM configuration. Send only the fields you want to change.

Request body

{
  "provider": "openai",
  "model": "gpt-4o-mini",
  "api_key": "sk-..."
}

Response — the full updated settings object.


GET /events

SSE stream of mining progress events. Connect once and keep the connection open to receive all future mining events.

Response — SSE stream

data: {"wing": "work", "status": "indexing", "files_done": 42, "files_total": 150}

data: {"wing": "work", "status": "ready", "files_done": 150, "files_total": 150}

data: {"wing": "notes", "status": "error", "error": "Permission denied: private.pdf"}

Error responses

All errors return a JSON body with a detail field:

{ "detail": "Wing 'foo' not found" }

HTTP status codes follow standard REST conventions: 400 bad request, 404 not found, 422 validation error, 500 internal server error.