Alkiviades — API Reference¶
Base URL: https://api.alkiviades.cc
Authentication¶
All protected endpoints require Authorization: Bearer <jwt_access_token> header.
POST /auth/login¶
Authenticate and receive JWT + refresh cookie.
Body: {"email": "user@example.com", "password": "secret"}
Response (200):
refresh_token cookie (path: /auth/refresh, 7 days).
Errors: 401 Invalid credentials, 422 Validation error.
POST /auth/refresh¶
Exchange refresh cookie for new access token.
Requires: refresh_token cookie.
Response (200): {"access_token": "eyJ...", "token_type": "bearer"}
Rotates refresh token (old revoked, new issued).
Errors: 401 Invalid/expired/revoked refresh token.
POST /auth/logout¶
Revoke refresh token and clear cookie.
Requires: refresh_token cookie (optional, idempotent).
Response (200): {"status": "ok"}
POST /auth/guest¶
Create temporary guest account with 5 queries.
Response (200):
{
"access_token": "eyJ...",
"token_type": "bearer",
"is_admin": false,
"role": "guest",
"queries_remaining": 5
}
GET /auth/me¶
Get current user profile. Auth required.
Response (200):
{
"id": "uuid",
"email": "user@example.com",
"role": "user",
"is_admin": false,
"queries_remaining": null
}
Health¶
GET /health¶
Public health check.
Response: {"status": "ok"}
GET /health/debug¶
Admin-only system diagnostics. Admin auth required.
Response:
{
"python_version": "3.12.x",
"has_deepseek_key": true,
"has_tavily_key": true,
"kb_exists": true,
"kb_size_mb": 75.2,
"embed_dtype": "float16",
"max_vocab_size": 15000,
"vectors_mmap": true,
"env": { "RENDER": "true", ... }
}
Chat¶
POST /chat¶
Non-streaming chat. Auth required.
Body:
{
"message": "What are the key positions on healthcare reform?",
"session_id": "optional-session-uuid",
"axes": { "ethical": -0.33, "alignment": 0.67, "social": 1.0 }
}
Response (200):
{
"reply": "Based on the analysis...",
"session_id": "session-uuid",
"sources": ["file1.md", "file2.md"],
"queries_remaining": null
}
Errors: 429 Guest query limit reached. 401 Unauthorized.
POST /chat/stream¶
SSE streaming chat. Auth required.
Body: Same as /chat.
Response: text/event-stream with events:
| Event | Data | Description |
|---|---|---|
| source | {"file": "doc.md", "score": 0.89} | RAG source chunk |
| token | {"text": "word"} | LLM text token |
| tool_call | {"tool": "search_news", "args": {...}} | Tool invocation |
| tool_result | {"tool": "search_news", "result": "..."} | Tool result |
| error | {"message": "..."} | Server error |
| done | {"session_id": "uuid"} | Stream complete |
| heartbeat | {"t": 1234567890} | Keepalive (every 15s) |
Sessions¶
All session endpoints require auth.
GET /sessions¶
List sessions for authenticated user.
Response: [{ "id": "uuid", "title": "Chat about...", "created": "...", "updated": "...", "turns": 5, "axes": "..." }]
GET /sessions/{id}¶
Get full session with all turns.
Response: { "id": "uuid", "title": "...", "messages": [...] }
Query ?preview=true for first 3 turns only.
DELETE /sessions/{id}¶
Delete a session. 404 if not found or not owned.
Axes¶
GET /api/axes¶
Get current axis values.
Response: {"ethical": -1.0, "alignment": 1.0, "social": 1.0}
PUT /api/axes¶
Update axis values (clamped -1 to 1).
Body: {"ethical": 0.0, "social": -0.5}
Response: Updated axes dict.
Admin¶
GET /api/admin/logs?limit=100¶
Get last N lines of application log. Admin auth required.
Response: {"lines": "log content..."}
GET /api/admin/logs/stream¶
SSE stream of new log entries. Admin auth required.
Events: {"event": "log", "data": "log line"} (polled every 2s).
POST /rebuild¶
Rebuild knowledge base from source files. Admin auth required.
Response: {"chunks": 2461, "diff": {"summary": {...}, "added": {...}, "removed": {...}, "changed": {...}}}