# HTTP Server API Reference ## Overview The CHORUS HTTP Server provides REST API endpoints for accessing the distributed Hypercore log, monitoring system health, and querying system status. All endpoints return JSON responses. **Base URL**: `http://localhost:8080/api` (default) ## Server Configuration ### Initialization ```go server := api.NewHTTPServer(port, hypercoreLog, pubsub) err := server.Start() ``` ### Parameters - `port` (int) - HTTP port to listen on - `hypercoreLog` (*logging.HypercoreLog) - Distributed log instance - `pubsub` (*pubsub.PubSub) - Event broadcasting system ### Server Lifecycle ```go // Start server (blocking) err := server.Start() // Stop server gracefully err := server.Stop() ``` ## CORS Configuration All endpoints support CORS with the following headers: ``` Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: Content-Type, Authorization ``` OPTIONS preflight requests return `200 OK` immediately. ## Endpoints ### 1. Health Check Check if the API server is running and responding. **Endpoint**: `GET /api/health` **Parameters**: None **Response**: ```json { "status": "healthy", "timestamp": 1727712345, "log_entries": 1024 } ``` **Response Fields**: - `status` (string) - Always "healthy" if server is responding - `timestamp` (int64) - Current Unix timestamp in seconds - `log_entries` (uint64) - Total number of log entries in the Hypercore log **Example**: ```bash curl -X GET http://localhost:8080/api/health ``` **Status Codes**: - `200 OK` - Server is healthy and responding --- ### 2. System Status Get detailed system status including Hypercore statistics and API version. **Endpoint**: `GET /api/status` **Parameters**: None **Response**: ```json { "status": "running", "timestamp": 1727712345, "hypercore": { "total_entries": 1024, "head_hash": "abc123...", "peer_id": "12D3KooW...", "replicators": 3 }, "api_version": "1.0.0" } ``` **Response Fields**: - `status` (string) - System operational status ("running") - `timestamp` (int64) - Current Unix timestamp - `hypercore` (object) - Hypercore log statistics - `api_version` (string) - API version string **Example**: ```bash curl -X GET http://localhost:8080/api/status ``` **Status Codes**: - `200 OK` - Status retrieved successfully --- ### 3. Get Log Entries Query log entries with flexible filtering by range or limit. **Endpoint**: `GET /api/hypercore/logs` **Query Parameters**: - `start` (uint64, optional) - Starting index (inclusive) - `end` (uint64, optional) - Ending index (exclusive, defaults to current length) - `limit` (int, optional) - Maximum number of entries to return (default: 100, max: 1000) **Parameter Behavior**: - If neither `start` nor `end` are provided, returns most recent `limit` entries - If only `start` is provided, returns from `start` to current end, up to `limit` - If both `start` and `end` are provided, returns range [start, end), up to `limit` **Response**: ```json { "entries": [ { "index": 1023, "timestamp": "2025-09-30T14:25:45Z", "author": "12D3KooWAbC123...", "type": "task_completed", "data": { "task_id": "TASK-456", "result": "success", "duration_ms": 2340 }, "hash": "sha256:abc123...", "prev_hash": "sha256:def456...", "signature": "sig:789..." } ], "count": 1, "timestamp": 1727712345, "total": 1024 } ``` **Response Fields**: - `entries` (array) - Array of log entry objects - `count` (int) - Number of entries in this response - `timestamp` (int64) - Response generation timestamp - `total` (uint64) - Total number of entries in the log **Log Entry Fields**: - `index` (uint64) - Sequential entry index - `timestamp` (string) - ISO 8601 timestamp - `author` (string) - Peer ID that created the entry - `type` (string) - Log entry type (see Log Types section) - `data` (object) - Entry-specific data payload - `hash` (string) - SHA-256 hash of this entry - `prev_hash` (string) - Hash of the previous entry (blockchain-style) - `signature` (string) - Digital signature **Examples**: ```bash # Get most recent 50 entries (default limit: 100) curl -X GET "http://localhost:8080/api/hypercore/logs?limit=50" # Get entries from index 100 to 200 curl -X GET "http://localhost:8080/api/hypercore/logs?start=100&end=200" # Get entries starting at index 500 (up to current end) curl -X GET "http://localhost:8080/api/hypercore/logs?start=500" # Get last 10 entries curl -X GET "http://localhost:8080/api/hypercore/logs?limit=10" ``` **Status Codes**: - `200 OK` - Entries retrieved successfully - `400 Bad Request` - Invalid parameter format - `500 Internal Server Error` - Failed to retrieve log entries **Error Examples**: ```bash # Invalid start parameter curl -X GET "http://localhost:8080/api/hypercore/logs?start=invalid" # Response: 400 Bad Request - "Invalid start parameter" # System error # Response: 500 Internal Server Error - "Failed to get log entries: database error" ``` --- ### 4. Get Recent Log Entries Retrieve the most recent log entries (convenience endpoint). **Endpoint**: `GET /api/hypercore/logs/recent` **Query Parameters**: - `limit` (int, optional) - Maximum number of entries to return (default: 50, max: 1000) **Response**: ```json { "entries": [ { "index": 1023, "timestamp": "2025-09-30T14:25:45Z", "author": "12D3KooWAbC123...", "type": "task_completed", "data": {...} } ], "count": 50, "timestamp": 1727712345, "total": 1024 } ``` **Response Fields**: Same as "Get Log Entries" endpoint **Examples**: ```bash # Get last 10 entries curl -X GET "http://localhost:8080/api/hypercore/logs/recent?limit=10" # Get last 50 entries (default) curl -X GET "http://localhost:8080/api/hypercore/logs/recent" # Get last 100 entries curl -X GET "http://localhost:8080/api/hypercore/logs/recent?limit=100" ``` **Status Codes**: - `200 OK` - Entries retrieved successfully - `500 Internal Server Error` - Failed to retrieve entries --- ### 5. Get Logs Since Index Retrieve all log entries created after a specific index (useful for incremental synchronization). **Endpoint**: `GET /api/hypercore/logs/since/{index}` **Path Parameters**: - `index` (uint64, required) - Starting index (exclusive - returns entries after this index) **Response**: ```json { "entries": [ { "index": 1001, "timestamp": "2025-09-30T14:20:00Z", "type": "task_claimed", "data": {...} }, { "index": 1002, "timestamp": "2025-09-30T14:21:00Z", "type": "task_progress", "data": {...} } ], "count": 2, "since_index": 1000, "timestamp": 1727712345, "total": 1024 } ``` **Response Fields**: - `entries` (array) - Array of log entries after the specified index - `count` (int) - Number of entries returned - `since_index` (uint64) - The index parameter provided in the request - `timestamp` (int64) - Response generation timestamp - `total` (uint64) - Current total number of entries in the log **Examples**: ```bash # Get all entries after index 1000 curl -X GET "http://localhost:8080/api/hypercore/logs/since/1000" # Get all new entries (poll from last known index) LAST_INDEX=950 curl -X GET "http://localhost:8080/api/hypercore/logs/since/${LAST_INDEX}" ``` **Use Cases**: - **Incremental Sync**: Clients can poll this endpoint periodically to get new entries - **Change Detection**: Detect new log entries since last check - **Event Streaming**: Simple polling-based event stream **Status Codes**: - `200 OK` - Entries retrieved successfully - `400 Bad Request` - Invalid index parameter - `500 Internal Server Error` - Failed to retrieve entries --- ### 6. Get Log Statistics Get comprehensive statistics about the Hypercore log. **Endpoint**: `GET /api/hypercore/logs/stats` **Parameters**: None **Response**: ```json { "total_entries": 1024, "head_hash": "sha256:abc123...", "peer_id": "12D3KooWAbC123...", "replicators": 3, "entry_types": { "task_announced": 234, "task_claimed": 230, "task_completed": 215, "task_failed": 15, "task_progress": 320, "peer_joined": 5, "peer_left": 3, "consensus_reached": 2 }, "authors": { "12D3KooWAbC123...": 567, "12D3KooWDef456...": 457 }, "first_entry_time": "2025-09-25T08:00:00Z", "last_entry_time": "2025-09-30T14:25:45Z" } ``` **Response Fields**: - `total_entries` (uint64) - Total number of log entries - `head_hash` (string) - Current head hash of the log chain - `peer_id` (string) - Local peer ID - `replicators` (int) - Number of active replication connections - `entry_types` (object) - Count of entries by type - `authors` (object) - Count of entries by author peer ID - `first_entry_time` (string) - Timestamp of first entry - `last_entry_time` (string) - Timestamp of most recent entry **Example**: ```bash curl -X GET "http://localhost:8080/api/hypercore/logs/stats" ``` **Status Codes**: - `200 OK` - Statistics retrieved successfully --- ## Log Entry Types The Hypercore log supports multiple entry types for different system events: ### Task Coordination (BZZZ) - `task_announced` - New task announced to the swarm - `task_claimed` - Agent claims a task - `task_progress` - Progress update on a task - `task_completed` - Task successfully completed - `task_failed` - Task execution failed ### Meta-Discussion (HMMM) - `plan_proposed` - Agent proposes a plan - `objection_raised` - Another agent raises an objection - `collaboration` - Collaborative work event - `consensus_reached` - Group consensus achieved - `escalation` - Issue escalated for human review - `task_help_requested` - Agent requests help with a task - `task_help_offered` - Agent offers help with a task - `task_help_received` - Help received and acknowledged ### System Events - `peer_joined` - New peer joined the network - `peer_left` - Peer disconnected from the network - `capability_broadcast` - Agent broadcasts its capabilities - `network_event` - General network-level event ## Data Payload Examples ### Task Announced ```json { "type": "task_announced", "data": { "task_id": "TASK-123", "description": "Implement user authentication", "capabilities_required": ["go", "security", "api"], "priority": "high", "estimated_duration_minutes": 180 } } ``` ### Task Completed ```json { "type": "task_completed", "data": { "task_id": "TASK-123", "result": "success", "duration_ms": 172340, "commits": ["abc123", "def456"], "tests_passed": true, "coverage_percent": 87.5 } } ``` ### Consensus Reached ```json { "type": "consensus_reached", "data": { "discussion_id": "DISC-456", "proposal": "Refactor authentication module", "participants": ["agent-1", "agent-2", "agent-3"], "votes": {"yes": 3, "no": 0, "abstain": 0}, "next_steps": ["create_subtasks", "assign_agents"] } } ``` ## Error Responses ### 400 Bad Request Invalid query parameters or path parameters: ``` HTTP/1.1 400 Bad Request Content-Type: text/plain Invalid start parameter ``` ### 500 Internal Server Error Server-side processing error: ``` HTTP/1.1 500 Internal Server Error Content-Type: text/plain Failed to get log entries: database connection failed ``` ## Performance Recommendations ### Pagination Always use appropriate `limit` values to avoid retrieving large result sets: ```bash # Good: Limited result set curl "http://localhost:8080/api/hypercore/logs/recent?limit=50" # Bad: Could return thousands of entries curl "http://localhost:8080/api/hypercore/logs" ``` ### Polling Strategy For incremental updates, use the "logs since" endpoint: ```bash # Initial fetch LAST_INDEX=$(curl -s "http://localhost:8080/api/hypercore/logs/recent?limit=1" | jq '.entries[0].index') # Poll for updates (every 5 seconds) while true; do NEW_ENTRIES=$(curl -s "http://localhost:8080/api/hypercore/logs/since/${LAST_INDEX}") if [ $(echo "$NEW_ENTRIES" | jq '.count') -gt 0 ]; then echo "$NEW_ENTRIES" | jq '.entries' LAST_INDEX=$(echo "$NEW_ENTRIES" | jq '.entries[-1].index') fi sleep 5 done ``` ### Caching Consider caching statistics and status responses that change infrequently: ```bash # Cache stats for 30 seconds curl -H "Cache-Control: max-age=30" "http://localhost:8080/api/hypercore/logs/stats" ``` ## WebSocket Support (Future) WebSocket support is planned for real-time log streaming: ```javascript // Future WebSocket API const ws = new WebSocket('ws://localhost:8080/api/ws/logs'); ws.onmessage = (event) => { const logEntry = JSON.parse(event.data); console.log('New log entry:', logEntry); }; ``` ## Testing ### Using curl ```bash # Health check curl -v http://localhost:8080/api/health # Get recent logs with pretty-printing curl -s http://localhost:8080/api/hypercore/logs/recent?limit=5 | jq '.' # Monitor for new entries watch -n 2 'curl -s http://localhost:8080/api/hypercore/logs/recent?limit=1 | jq ".entries[0]"' ``` ### Using httpie ```bash # Install httpie pip install httpie # Make requests http GET localhost:8080/api/health http GET localhost:8080/api/hypercore/logs/recent limit==10 http GET localhost:8080/api/status ``` ### Integration Testing ```go package api_test import ( "testing" "net/http" "net/http/httptest" ) func TestHealthEndpoint(t *testing.T) { // Create test server server := api.NewHTTPServer(0, mockHypercoreLog, mockPubSub) // Create test request req := httptest.NewRequest("GET", "/api/health", nil) rec := httptest.NewRecorder() // Execute request server.ServeHTTP(rec, req) // Assert response if rec.Code != http.StatusOK { t.Errorf("Expected 200, got %d", rec.Code) } } ``` ## Related Documentation - [API Overview](./README.md) - API architecture and integration points - [Hypercore Log System](../internal/logging.md) - Distributed log internals - [Setup Manager](./setup-manager.md) - Configuration API (future document) - [Authentication](./authentication.md) - Authentication guide (future document)