The REST API provides endpoints for graph data management, content operations, and system status.
http://localhost:4000/api
Default is http://localhost:4000/api when running locally via Docker with Nginx. The actual backend runs on port 3001 (or as configured in settings.yaml/env) and is proxied by Nginx. For production, it's typically https://www.visionflow.info/api (or your configured domain).
All API requests primarily use Nostr authentication.
POST /api/auth/nostrRequest Body:
{
"id": "event_id_hex_string",
"pubkey": "user_hex_pubkey",
"created_at": 1678886400, // Unix timestamp (seconds)
"kind": 22242,
"tags": [
["relay", "wss://some.relay.com"],
["challenge", "a_random_challenge_string"]
],
"content": "LogseqXR Authentication",
"sig": "event_signature_hex_string"
}Refers to src/services/nostr_service.rs::AuthEvent.
Response:
{
"user": {
"pubkey": "user_hex_pubkey",
"npub": "user_npub_string", // Optional
"isPowerUser": true // boolean
},
"token": "session_token_string",
"expiresAt": 1234567890, // Unix timestamp (seconds)
"features": ["feature1", "feature2"] // List of enabled features for the user
}Matches AuthResponse from src/handlers/nostr_handler.rs.
POST /api/auth/nostr/verifyRequest Body:
{
"pubkey": "user_hex_pubkey",
"token": "session_token_string"
}Matches ValidateRequest from src/handlers/nostr_handler.rs.
Response Body:
{
"valid": true, // boolean
"user": { // Optional
"pubkey": "user_hex_pubkey",
"npub": "user_npub_string",
"isPowerUser": false
},
"features": ["feature1"] // List of enabled features if valid
}Matches VerifyResponse from src/handlers/nostr_handler.rs.
DELETE /api/auth/nostrRequest Body:
{
"pubkey": "user_hex_pubkey",
"token": "session_token_string"
}Matches ValidateRequest from src/handlers/nostr_handler.rs.
GET /api/graph/dataReturns GraphResponse from src/handlers/api_handler/graph/mod.rs:
{
"nodes": [
// Array of crate::models::node::Node
],
"edges": [
// Array of crate::models::edge::Edge
],
"metadata": {
// HashMap<String, crate::models::metadata::Metadata>
}
}Note: The Node model used in this response is defined in src/models/node.rs and uses a u32 for the id field.
GET /api/graph/data/paginatedQuery Parameters:
page: Page number (integer, default: 1)pageSize: Items per page (integer, default: 100, camelCase)sort: Sort field (string, optional)filter: Filter expression (string, optional)
Response:
{
"nodes": [...],
"edges": [...],
"metadata": {},
"totalPages": 0,
"currentPage": 1,
"total_nodes": 0,
"page_size": 100
}
### Update Graph
```http
POST /api/graph/updateThis endpoint triggers a full re-fetch of files from the source (e.g., GitHub) by FileService, updates the MetadataStore, and then rebuilds the entire graph structure in GraphService. It does not accept client-side graph data for partial updates.
POST /api/graph/refreshThis endpoint rebuilds the graph structure in GraphService using the currently existing MetadataStore on the server. It does not re-fetch files.
POST /api/files/processTriggers fetching and processing of Markdown files.
Response:
{
"status": "success",
"processed_files": ["file1.md", "file2.md"]
}GET /api/files/get_content/{filename}POST /api/files/uploadThe endpoint /api/files/upload is not defined in src/handlers/api_handler/files/mod.rs. This section should be removed or marked as "Not Implemented / Deprecated".
(Marking as Not Implemented for now)
This endpoint is not implemented.
GET /api/user-settingsReturns UISettings (camelCase) as defined in src/models/ui_settings.rs, derived from the server's AppFullSettings. This endpoint does not require authentication.
GET /api/user-settings/syncRequires authentication.
GET Response: Returns UISettings. For power users, these are global settings. For regular users, these are their persisted settings.
POST Request Body: ClientSettingsPayload from src/models/client_settings_payload.rs (camelCase).
POST Response: The updated UISettings.
GET /api/visualisation/settings/{category}The handler get_visualisation_settings (mapped to /api/visualisation/get_settings/{category} in src/handlers/api_handler/visualisation/mod.rs) actually returns the entire AppFullSettings struct, not just a category. The path parameter {category} is not used by this specific handler.
The handler get_category_settings (mapped to /api/visualisation/settings/{category}) does return a specific category.
The documentation path /api/visualisation/settings/{category} matches get_category_settings. This endpoint returns a specific category as a JSON object.
POST /api/auth/nostr/api-keysRequest Body:
{
"perplexity": "optional_api_key_string",
"openai": "optional_api_key_string",
"ragflow": "optional_api_key_string"
}Matches ApiKeysRequest from src/handlers/nostr_handler.rs.
Response:
{
"pubkey": "user_hex_pubkey",
"npub": "user_npub_string", // Optional
"isPowerUser": true // boolean
}Returns UserResponseDTO.
POST /api/ragflow/chatRequest Body:
{
"question": "Your question here",
"sessionId": "optional-previous-session-id-string",
"stream": false // Optional boolean
}Matches RagflowChatRequest from src/models/ragflow_chat.rs.
Response:
{
"answer": "The response from RAGFlow AI",
"sessionId": "session-id-string"
}Matches RagflowChatResponse from src/models/ragflow_chat.rs.
GET /api/healthResponse:
{
"status": "healthy",
"metadata_count": 123,
"nodes_count": 456,
"edges_count": 789
}GET /api/health/physicsResponse:
{
"status": "string (e.g., 'running', 'idle', 'error')",
"details": "string (e.g., 'Simulation is active with X nodes' or error message)",
"timestamp": 1234567890 // Unix timestamp
}Returns PhysicsSimulationStatus from src/handlers/health_handler.rs.
Error responses are often simple JSON like {"error": "message string"} or {"status": "error", "message": "message string"}.
The structured format {"error": {"code": ..., "message": ..., "details": ...}} is not consistently used across all handlers.
400 Bad Request: Invalid parameters or request payload.401 Unauthorized: Invalid or missing authentication token.403 Forbidden: Valid token but insufficient permissions for the requested operation.404 Not Found: The requested resource or endpoint does not exist.422 Unprocessable Entity: The request was well-formed but could not be processed (e.g., semantic errors in Nostr event).500 Internal Server Error: A generic error occurred on the server.503 Service Unavailable: The server is temporarily unable to handle the request (e.g., during maintenance or if a dependent service is down).