⎿ # V2-Docker API Reference ## Authentication ### API Key Authentication All License Server API endpoints require authentication using an API key. The API key must be included in the request headers. **Header Format:** ``` X-API-Key: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ``` **API Key Management:** - API keys can be managed through the Admin Panel under "Lizenzserver Administration" → "System-API-Key generieren" - Keys follow the format: `AF-YYYY-[32 random characters]` - Only one system API key is active at a time - Regenerating the key will immediately invalidate the old key - The initial API key is automatically generated on first startup - To retrieve the initial API key from database: `SELECT api_key FROM system_api_key WHERE id = 1;` **Error Response (401 Unauthorized):** ```json { "error": "Invalid or missing API key", "code": "INVALID_API_KEY", "status": 401 } ``` ## License Server API **Base URL:** `https://api-software-undso.intelsight.de` ### 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: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Content-Type: application/json ``` **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: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Content-Type: application/json ``` **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: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ``` **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 } ] } ``` ### Session Management API Endpoints **Note:** Session endpoints require that the client application is configured in the `client_configs` table. The default client "Account Forger" is pre-configured. #### POST /api/license/session/start Start a new session for a license. **Headers:** ``` X-API-Key: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Content-Type: application/json ``` **Request:** ```json { "license_key": "XXXX-XXXX-XXXX-XXXX", "machine_id": "DESKTOP-ABC123", "hardware_hash": "unique-hardware-identifier", "version": "1.0.0" } ``` **Response:** - 200 OK: Returns session_token and optional update info - 409 Conflict: "Es ist nur eine Sitzung erlaubt..." (single session enforcement) #### POST /api/license/session/heartbeat Keep session alive with heartbeat. **Headers:** ``` X-API-Key: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Content-Type: application/json ``` **Request:** ```json { "session_token": "550e8400-e29b-41d4-a716-446655440000", "license_key": "XXXX-XXXX-XXXX-XXXX" } ``` **Response:** 200 OK with last_heartbeat timestamp #### POST /api/license/session/end End an active session. **Headers:** ``` X-API-Key: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Content-Type: application/json ``` **Request:** ```json { "session_token": "550e8400-e29b-41d4-a716-446655440000" } ``` **Response:** 200 OK with session duration and end reason ### Version API Endpoints #### POST /api/version/check Check for available updates. **Headers:** ``` X-API-Key: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ``` **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" } ``` #### GET /api/version/latest Get latest version information. **Headers:** ``` X-API-Key: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ``` **Response:** ```json { "version": "1.1.0", "release_date": "2025-06-20", "download_url": "https://example.com/download/v1.1.0", "release_notes": "Bug fixes and performance improvements" } ``` ## Admin Panel API **Base URL:** `https://admin-panel-undso.intelsight.de` ### 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 } } ``` ### License Management API - `POST /api/license/{id}/toggle` - Toggle active status - `POST /api/licenses/bulk-activate` - Activate multiple (license_ids array) - `POST /api/licenses/bulk-deactivate` - Deactivate multiple - `POST /api/licenses/bulk-delete` - Delete multiple - `POST /api/license/{id}/quick-edit` - Update validity/limits - `GET /api/license/{id}/devices` - List registered devices #### 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" } ] } ``` ### 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 } ``` ### Lead Management API #### GET /leads/api/institutions Get all institutions with pagination. **Query Parameters:** - `page`: Page number (default: 1) - `per_page`: Items per page (default: 20) - `search`: Search query **Response:** ```json { "institutions": [ { "id": 1, "name": "Tech University", "contact_count": 5, "created_at": "2025-06-19T10:00:00Z" } ], "total": 100, "page": 1, "per_page": 20 } ``` #### POST /leads/api/institutions Create a new institution. **Request:** ```json { "name": "New University" } ``` **Response:** ```json { "id": 101, "name": "New University", "created_at": "2025-06-19T15:00:00Z" } ``` #### GET /leads/api/contacts/{contact_id} Get contact details. **Response:** ```json { "id": 1, "first_name": "John", "last_name": "Doe", "position": "IT Manager", "institution_id": 1, "details": [ { "id": 1, "type": "email", "value": "john.doe@example.com", "label": "Work" }, { "id": 2, "type": "phone", "value": "+49 123 456789", "label": "Mobile" } ], "notes": [ { "id": 1, "content": "Initial contact", "version": 1, "created_at": "2025-06-19T10:00:00Z", "created_by": "admin" } ] } ``` #### POST /leads/api/contacts/{contact_id}/details Add contact detail (phone/email). **Request:** ```json { "type": "email", "value": "secondary@example.com", "label": "Secondary" } ``` **Response:** ```json { "id": 3, "type": "email", "value": "secondary@example.com", "label": "Secondary" } ``` ### Resource Management API #### POST /api/resources/allocate Allocate resources to a license. **Request:** ```json { "license_id": 123, "resource_type": "domain", "resource_ids": [45, 46, 47] } ``` **Response:** ```json { "success": true, "allocated": 3, "message": "3 resources allocated successfully" } ``` ## 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 - API endpoints: 100 requests/minute - Login attempts: 5 per minute - Configurable via Admin Panel ## Error Response Format All errors return JSON with `error`, `code`, and `status` fields. ## Client Integration Example request with required headers: ```bash curl -X POST https://api-software-undso.intelsight.de/api/license/activate \ -H "X-API-Key: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ -H "Content-Type: application/json" \ -d '{ "license_key": "XXXX-XXXX-XXXX-XXXX", "hardware_hash": "unique-hardware-id", "machine_name": "DESKTOP-123", "app_version": "1.0.0" }' ``` ## Testing ### Test Credentials - Admin Users: - Username: `rac00n` / Password: `1248163264` - Username: `w@rh@mm3r` / Password: `Warhammer123!` - API Key: Generated in Admin Panel under "Lizenzserver Administration" ### Getting the Initial API Key If you need to retrieve the API key directly from the database: ```bash docker exec -it v2_postgres psql -U postgres -d v2_db -c "SELECT api_key FROM system_api_key WHERE id = 1;" ``` ### Test Endpoints - Admin Panel: `https://admin-panel-undso.intelsight.de/` - License Server API: `https://api-software-undso.intelsight.de/`