# V2-Docker API Reference ## License Server API ### Public Endpoints #### GET / Root endpoint - Service status. **Response:** ```json { "status": "ok", "service": "V2 License Server", "timestamp": "2025-06-19T10:30:00Z" } ``` #### GET /health Health check endpoint. **Response:** ```json { "status": "healthy", "timestamp": "2025-06-19T10:30:00Z" } ``` #### GET /metrics Prometheus metrics endpoint. **Response:** Prometheus metrics in CONTENT_TYPE_LATEST format. ### License API Endpoints All license endpoints require API key authentication via `X-API-Key` header. #### POST /api/license/activate Activate a license on a new system. **Headers:** ``` X-API-Key: your-api-key ``` **Request:** ```json { "license_key": "XXXX-XXXX-XXXX-XXXX", "hardware_hash": "unique-hardware-identifier", "machine_name": "DESKTOP-ABC123", "app_version": "1.0.0" } ``` **Response:** ```json { "message": "License activated successfully", "activation": { "id": 123, "license_key": "XXXX-XXXX-XXXX-XXXX", "hardware_hash": "unique-hardware-identifier", "machine_name": "DESKTOP-ABC123", "activated_at": "2025-06-19T10:30:00Z", "last_heartbeat": "2025-06-19T10:30:00Z", "is_active": true } } ``` #### POST /api/license/verify Verify an active license. **Headers:** ``` X-API-Key: your-api-key ``` **Request:** ```json { "license_key": "XXXX-XXXX-XXXX-XXXX", "hardware_hash": "unique-hardware-identifier", "app_version": "1.0.0" } ``` **Response:** ```json { "valid": true, "message": "License is valid", "license": { "key": "XXXX-XXXX-XXXX-XXXX", "valid_until": "2026-01-01", "max_users": 10 }, "update_available": false, "latest_version": "1.0.0" } ``` #### GET /api/license/info/{license_key} Get license information. **Headers:** ``` X-API-Key: your-api-key ``` **Response:** ```json { "license": { "id": 123, "key": "XXXX-XXXX-XXXX-XXXX", "customer_name": "ACME Corp", "type": "perpetual", "valid_from": "2025-01-01", "valid_until": "2026-01-01", "max_activations": 5, "max_users": 10, "is_active": true }, "activations": [ { "id": 456, "hardware_hash": "unique-hardware-identifier", "machine_name": "DESKTOP-ABC123", "activated_at": "2025-06-19T10:00:00Z", "last_heartbeat": "2025-06-19T14:30:00Z", "is_active": true } ] } ``` ### Version API Endpoints #### POST /api/version/check Check for available updates. **Headers:** ``` X-API-Key: your-api-key ``` **Request:** ```json { "current_version": "1.0.0", "license_key": "XXXX-XXXX-XXXX-XXXX" } ``` **Response:** ```json { "update_available": true, "latest_version": "1.1.0", "download_url": "https://example.com/download/v1.1.0", "release_notes": "Bug fixes and performance improvements", "is_mandatory": false } ``` #### GET /api/version/latest Get latest version information. **Headers:** ``` X-API-Key: your-api-key ``` **Response:** ```json { "version": "1.1.0", "release_date": "2025-06-15", "download_url": "https://example.com/download/v1.1.0", "release_notes": "Bug fixes and performance improvements", "is_mandatory": false } ``` ## Admin Panel API ### Customer API Endpoints #### GET /api/customers Search customers for Select2 dropdown. **Query Parameters:** - `q`: Search query - `page`: Page number (default: 1) **Response:** ```json { "results": [ { "id": 123, "text": "ACME Corp - admin@acme.com" } ], "pagination": { "more": false } } ``` #### GET /api/customer/{customer_id}/licenses Get licenses for a specific customer. **Response:** ```json { "licenses": [ { "id": 456, "license_key": "XXXX-XXXX-XXXX-XXXX", "type": "perpetual", "status": "active", "valid_until": "2026-01-01", "max_activations": 5, "current_activations": 3 } ] } ``` #### GET /api/customer/{customer_id}/quick-stats Get quick statistics for a customer. **Response:** ```json { "total_licenses": 10, "active_licenses": 8, "total_activations": 25, "total_users": 150 } ``` ### License Management API #### POST /api/license/{license_id}/toggle Toggle license active status. **Response:** ```json { "success": true, "is_active": true, "message": "License activated successfully" } ``` #### POST /api/licenses/bulk-activate Activate multiple licenses. **Request:** ```json { "license_ids": [1, 2, 3] } ``` **Response:** ```json { "success": true, "count": 3, "message": "3 licenses activated successfully" } ``` #### POST /api/licenses/bulk-deactivate Deactivate multiple licenses. **Request:** ```json { "license_ids": [1, 2, 3] } ``` **Response:** ```json { "success": true, "count": 3, "message": "3 licenses deactivated successfully" } ``` #### POST /api/licenses/bulk-delete Delete multiple licenses. **Request:** ```json { "license_ids": [1, 2, 3] } ``` **Response:** ```json { "success": true, "deleted": 3, "message": "3 licenses deleted successfully" } ``` #### POST /api/license/{license_id}/quick-edit Quick edit license properties. **Request:** ```json { "valid_until": "2027-01-01", "max_activations": 10, "max_users": 50 } ``` **Response:** ```json { "success": true, "message": "License updated successfully" } ``` #### POST /api/generate-license-key Generate a new license key. **Response:** ```json { "license_key": "NEW1-NEW2-NEW3-NEW4" } ``` ### Device Management API #### GET /api/license/{license_id}/devices Get devices for a license. **Response:** ```json { "devices": [ { "id": 123, "hardware_hash": "unique-hardware-identifier", "machine_name": "DESKTOP-ABC123", "activated_at": "2025-01-01T10:00:00Z", "last_heartbeat": "2025-06-19T14:30:00Z", "is_active": true, "app_version": "1.0.0" } ] } ``` #### POST /api/license/{license_id}/register-device Register a new device. **Request:** ```json { "hardware_hash": "unique-hardware-identifier", "machine_name": "DESKTOP-XYZ789", "app_version": "1.0.0" } ``` **Response:** ```json { "success": true, "device_id": 456, "message": "Device registered successfully" } ``` #### POST /api/license/{license_id}/deactivate-device/{device_id} Deactivate a device. **Response:** ```json { "success": true, "message": "Device deactivated successfully" } ``` ### Resource Management API #### GET /api/license/{license_id}/resources Get resources for a license. **Response:** ```json { "resources": [ { "id": 789, "type": "server", "identifier": "SRV-001", "status": "allocated", "allocated_at": "2025-06-01T10:00:00Z" } ] } ``` #### POST /api/resources/allocate Allocate resources to a license. **Request:** ```json { "license_id": 123, "resource_ids": [789, 790] } ``` **Response:** ```json { "success": true, "allocated": 2, "message": "2 resources allocated successfully" } ``` #### GET /api/resources/check-availability Check resource availability. **Query Parameters:** - `type`: Resource type - `count`: Number of resources needed **Response:** ```json { "available": true, "count": 5, "resources": [ { "id": 791, "type": "server", "identifier": "SRV-002" } ] } ``` #### GET /api/resources/stats Get resource statistics. **Response:** ```json { "total": 100, "allocated": 75, "available": 25, "by_type": { "server": { "total": 50, "allocated": 40, "available": 10 }, "workstation": { "total": 50, "allocated": 35, "available": 15 } } } ``` ### Search API #### GET /api/global-search Global search across all entities. **Query Parameters:** - `q`: Search query - `type`: Entity type filter (customer, license, device) - `limit`: Maximum results (default: 20) **Response:** ```json { "results": [ { "type": "customer", "id": 123, "title": "ACME Corp", "subtitle": "admin@acme.com", "url": "/customer/edit/123" }, { "type": "license", "id": 456, "title": "XXXX-XXXX-XXXX-XXXX", "subtitle": "ACME Corp - Active", "url": "/license/edit/456" } ], "total": 15 } ``` ### Session Management API #### GET /api/sessions/active-count Get count of active sessions. **Response:** ```json { "count": 42 } ``` ### Monitoring API #### GET /api/monitoring/live-stats Get live statistics for monitoring. **Response:** ```json { "timestamp": "2025-06-19T14:30:00Z", "metrics": { "active_licenses": 850, "total_activations": 2500, "active_sessions": 1200, "heartbeats_per_minute": 450 }, "alerts": [ { "type": "warning", "message": "High CPU usage detected", "timestamp": "2025-06-19T14:25:00Z" } ] } ``` #### GET /api/monitoring/anomaly-stats Get anomaly statistics. **Response:** ```json { "total_anomalies": 15, "unresolved": 3, "by_type": { "unusual_activation_pattern": 5, "excessive_heartbeats": 3, "license_hopping": 7 } } ``` #### GET /api/admin/license/auth-token Get JWT token for analytics access. **Response:** ```json { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "expires_at": "2025-06-19T15:30:00Z" } ``` ## Lead Management API ### GET /leads/api/stats Get lead statistics. **Response:** ```json { "total_institutions": 150, "total_contacts": 450, "recent_activities": 25, "conversion_rate": 12.5, "by_type": { "university": 50, "company": 75, "government": 25 } } ``` ### Lead Routes (HTML Pages) - `GET /leads/` - Lead overview page - `GET /leads/create` - Create lead form - `POST /leads/create` - Save new lead - `GET /leads/edit/{lead_id}` - Edit lead form - `POST /leads/update/{lead_id}` - Update lead - `POST /leads/delete/{lead_id}` - Delete lead - `GET /leads/export` - Export leads - `POST /leads/import` - Import leads ## Common Response Codes - `200 OK`: Successful request - `201 Created`: Resource created - `400 Bad Request`: Invalid request data - `401 Unauthorized`: Missing or invalid authentication - `403 Forbidden`: Insufficient permissions - `404 Not Found`: Resource not found - `409 Conflict`: Resource conflict (e.g., duplicate) - `429 Too Many Requests`: Rate limit exceeded - `500 Internal Server Error`: Server error ## Rate Limiting - Public API: 100 requests per minute per IP - Admin API: 1000 requests per minute per token - Heartbeat endpoint: 1 request per minute per activation ## Error Response Format ```json { "error": { "code": "INVALID_LICENSE", "message": "The provided license key is invalid", "details": { "field": "license_key", "reason": "format_invalid" } } } ``` ## Client Integration Examples ### Python ```python import requests import json class LicenseClient: def __init__(self, base_url): self.base_url = base_url def activate(self, license_key, hardware_id): response = requests.post( f"{self.base_url}/api/v1/activate", json={ "license_key": license_key, "hardware_id": hardware_id, "machine_name": socket.gethostname(), "app_version": "1.0.0" } ) return response.json() def validate(self, license_key, activation_id, hardware_id): response = requests.post( f"{self.base_url}/api/v1/validate", json={ "license_key": license_key, "activation_id": activation_id, "hardware_id": hardware_id, "app_version": "1.0.0" } ) return response.json() ``` ### C# Example ```csharp public class LicenseClient { private readonly HttpClient _httpClient; private readonly string _baseUrl; public LicenseClient(string baseUrl) { _baseUrl = baseUrl; _httpClient = new HttpClient(); } public async Task ActivateAsync( string licenseKey, HardwareInfo hardwareId) { var request = new { license_key = licenseKey, hardware_id = hardwareId, machine_name = Environment.MachineName, app_version = "1.0.0" }; var response = await _httpClient.PostAsJsonAsync( $"{_baseUrl}/api/v1/activate", request ); return await response.Content.ReadFromJsonAsync(); } } ``` ## Webhooks ### Configuration Configure webhooks in the admin panel to receive notifications for: - License activation - License expiration - Suspicious activity - Usage threshold alerts ### Webhook Payload ```json { "event": "license.activated", "timestamp": "2025-06-19T10:30:00Z", "data": { "license_id": 123, "activation_id": "act_456", "customer_id": 789 } } ``` ## Testing ### Test Credentials - License Key: `TEST-TEST-TEST-TEST` - API Key: `test_api_key_123` - JWT Secret: `test_jwt_secret` ### Test Endpoints - Development: `http://localhost:8080` - Staging: `https://staging-api.example.com` - Production: `https://api.example.com`