API Reference
All endpoints require a valid JWT unless noted otherwise. The JWT is read from the x-auth-request-access-token header (oauth2_proxy) or Authorization: Bearer header. OpenAPI docs at http://localhost:8012/docs.
Chat
POST /chat
Stream a chat response via Server-Sent Events.
Request body:
{
"message": "string",
"conversation_id": "optional-uuid",
"attachment_ids": ["optional-list-of-uuids"],
"context": {"page": "dashboard"},
"top_k": 5,
"include_citations": false
}
Response: text/event-stream — SSE events with data: {"type": "<type>", "data": ...} format.
Behavior:
- Creates a new conversation if conversation_id is omitted.
- Loads authorized attachments and retrieves relevant document chunks from Qdrant.
- The LLM autonomously invokes registered skills (energy data, weather, flexibility, etc.) via tool calls.
- Persists the full assistant reply once streaming completes.
Uploads and Attachments
POST /upload
Upload a file for RAG ingestion (user scope).
Request: multipart/form-data with file field.
Response: 201 with attachment metadata including id, filename, content_type.
content_type is decided from the file's bytes; a type outside the allowed list (PDF,
PNG/JPEG/GIF/WebP, .docx/.xlsx/.pptx, .txt/.md/.csv) is 415
(REQ-0048). POST /admin/uploads applies the same list.
Images are captioned via the vision model before chunking. All files are parsed, chunked, embedded, and upserted into Qdrant.
GET /attachments
List all attachments belonging to the authenticated user.
GET /attachments/{id}/raw
Download the raw uploaded file. Images and PDFs are served inline, everything else as
attachment, always with X-Content-Type-Options: nosniff and a sandboxing
Content-Security-Policy (REQ-0049).
DELETE /attachments/{id}
Delete an attachment and remove its vectors from Qdrant.
Conversations
GET /conversations
List all conversations for the authenticated user.
GET /conversations/{id}/messages
Return all messages in a conversation.
DELETE /conversations/{id}
Delete a conversation and all its messages.
User
GET /user
Return the authenticated user's profile derived from the JWT: community_id (the REC
organization in the token, or null), roles (the caller's realm roles, from
realm_access.roles), is_platform_admin (holds the platform-admin realm role), and
is_admin — true for a platform administrator and for a manager of the caller's own
community. An identity from trusted headers has no roles.
Admin
These act on one community's knowledge base. The caller must be a platform administrator
(the platform-admin realm role in a verified token's realm_access.roles) or hold one of
REC_MANAGER_GROUPS inside that REC's organization. A realm group (top-level groups
claim) grants nothing. A manager acts on their own community; a platform administrator
names one with community_id (400 without). Anyone else gets 403.
POST /admin/uploads
Multipart: file, and optionally community_id (a platform administrator's). Shares a file
with the community as a system-scoped attachment, readable by its members.
POST /admin/kb/sync
Body: {"community_id": "…" | null, "full": false}. Syncs every source registered for
the community and returns one result per source; a failing source carries an error
and does not stop the others. Replaces POST /admin/training-materials/sync.
Health
GET /health
Returns {"status": "ok"}. No authentication required.
GET /ping
Returns {"ok": true}. Requires authentication — useful as a liveness check that validates the JWT.