# V2-Docker API Reference ## License Server API ### Public Endpoints #### POST /api/v1/activate Activate a license on a new system. **Request:** ```json { "license_key": "XXXX-XXXX-XXXX-XXXX", "hardware_id": { "mac_address": "00:1B:44:11:3A:B7", "cpu_id": "BFEBFBFF000906EA", "system_uuid": "4C4C4544-0052-3410-8036-B8C04F303832" }, "machine_name": "DESKTOP-ABC123", "app_version": "1.0.0" } ``` **Response:** ```json { "success": true, "activation_id": "act_123456", "features": ["feature1", "feature2"], "max_users": 10, "valid_until": "2026-01-01T00:00:00Z" } ``` #### POST /api/v1/validate Validate an active license. **Request:** ```json { "license_key": "XXXX-XXXX-XXXX-XXXX", "activation_id": "act_123456", "hardware_id": { "mac_address": "00:1B:44:11:3A:B7", "cpu_id": "BFEBFBFF000906EA", "system_uuid": "4C4C4544-0052-3410-8036-B8C04F303832" }, "current_users": 5, "app_version": "1.0.0" } ``` **Response:** ```json { "valid": true, "features": ["feature1", "feature2"], "max_users": 10, "message": "License valid" } ``` #### POST /api/v1/heartbeat Send usage heartbeat. **Request:** ```json { "license_key": "XXXX-XXXX-XXXX-XXXX", "activation_id": "act_123456", "current_users": 5, "feature_usage": { "feature1": 150, "feature2": 75 } } ``` **Response:** ```json { "success": true, "next_heartbeat": "2025-01-01T12:30:00Z" } ``` #### POST /api/v1/deactivate Deactivate a license. **Request:** ```json { "license_key": "XXXX-XXXX-XXXX-XXXX", "activation_id": "act_123456", "reason": "System upgrade" } ``` **Response:** ```json { "success": true, "message": "License deactivated successfully" } ``` ### Admin API Endpoints #### Authentication All admin endpoints require JWT authentication: ``` Authorization: Bearer ``` #### GET /api/v1/admin/licenses List all licenses. **Query Parameters:** - `page` (default: 1) - `per_page` (default: 50) - `status` (active, inactive, expired) - `customer_id` **Response:** ```json { "licenses": [ { "id": 1, "license_key": "XXXX-XXXX-XXXX-XXXX", "customer_name": "ACME Corp", "type": "subscription", "status": "active", "valid_from": "2025-01-01", "valid_until": "2026-01-01", "max_activations": 5, "current_activations": 3 } ], "total": 100, "page": 1, "per_page": 50 } ``` #### POST /api/v1/admin/licenses Create a new license. **Request:** ```json { "customer_id": 123, "type": "subscription", "valid_from": "2025-01-01", "valid_until": "2026-01-01", "max_activations": 5, "max_users": 10, "features": ["feature1", "feature2"] } ``` **Response:** ```json { "id": 456, "license_key": "NEW1-NEW2-NEW3-NEW4", "message": "License created successfully" } ``` #### GET /api/v1/admin/licenses/{id} Get license details. **Response:** ```json { "id": 1, "license_key": "XXXX-XXXX-XXXX-XXXX", "customer": { "id": 123, "name": "ACME Corp", "email": "admin@acme.com" }, "activations": [ { "id": "act_123456", "machine_name": "DESKTOP-ABC123", "activated_at": "2025-01-01T10:00:00Z", "last_heartbeat": "2025-06-19T14:30:00Z", "status": "active" } ], "usage_stats": { "total_users": 150, "peak_users": 10, "feature_usage": { "feature1": 5000, "feature2": 2500 } } } ``` #### PUT /api/v1/admin/licenses/{id} Update license. **Request:** ```json { "valid_until": "2027-01-01", "max_activations": 10, "features": ["feature1", "feature2", "feature3"] } ``` #### DELETE /api/v1/admin/licenses/{id} Revoke a license. #### GET /api/v1/admin/activations List all activations. **Query Parameters:** - `license_id` - `status` (active, inactive) - `from_date` - `to_date` #### GET /api/v1/admin/statistics Get usage statistics. **Query Parameters:** - `from_date` - `to_date` - `customer_id` - `license_id` **Response:** ```json { "summary": { "total_licenses": 100, "active_licenses": 85, "total_activations": 250, "active_users": 1500 }, "usage_trends": [ { "date": "2025-06-01", "active_users": 1200, "new_activations": 5 } ], "feature_usage": { "feature1": 50000, "feature2": 25000 } } ``` ## Lead Management API ### Institutions #### GET /api/institutions List all institutions. **Query Parameters:** - `search`: Search term - `tags`: Comma-separated tags - `page`: Page number - `per_page`: Items per page #### POST /api/institutions Create new institution. **Request:** ```json { "name": "Example University", "type": "university", "address": "123 Main St", "tags": ["education", "research"], "metadata": { "student_count": 5000 } } ``` #### GET /api/institutions/{id} Get institution details. #### PUT /api/institutions/{id} Update institution. #### DELETE /api/institutions/{id} Delete institution. ### Contact Persons #### GET /api/institutions/{id}/contacts List contacts for institution. #### POST /api/institutions/{id}/contacts Add contact to institution. **Request:** ```json { "name": "John Doe", "email": "john@example.com", "phone": "+1234567890", "position": "IT Manager", "is_primary": true } ``` ### Notes #### GET /api/institutions/{id}/notes Get notes for institution. #### POST /api/institutions/{id}/notes Add note to institution. **Request:** ```json { "content": "Discussed pricing options", "type": "meeting", "tags": ["sales", "followup"] } ``` ## Analytics API ### GET /api/v1/analytics/usage Get detailed usage analytics. **Query Parameters:** - `from_date`: Start date (ISO 8601) - `to_date`: End date (ISO 8601) - `license_id`: Filter by license - `granularity`: hour, day, week, month **Response:** ```json { "period": { "from": "2025-06-01T00:00:00Z", "to": "2025-06-19T23:59:59Z" }, "metrics": { "total_heartbeats": 50000, "unique_activations": 150, "average_users_per_activation": 8.5, "peak_concurrent_users": 1200 }, "time_series": [ { "timestamp": "2025-06-01T00:00:00Z", "active_users": 800, "heartbeat_count": 2500 } ] } ``` ### GET /api/v1/analytics/features Get feature usage statistics. **Response:** ```json { "features": [ { "name": "feature1", "total_usage": 150000, "unique_users": 500, "usage_trend": "increasing" } ] } ``` ## 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`