14 KiB
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 Administration → API Keys
- 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
Error Response (401 Unauthorized):
{
"error": "Invalid or missing API key",
"code": "INVALID_API_KEY",
"status": 401
}
License Server API
Public Endpoints
GET /
Root endpoint - Service status.
Response:
{
"status": "ok",
"service": "V2 License Server",
"timestamp": "2025-06-19T10:30:00Z"
}
GET /health
Health check endpoint.
Response:
{
"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:
{
"license_key": "XXXX-XXXX-XXXX-XXXX",
"hardware_hash": "unique-hardware-identifier",
"machine_name": "DESKTOP-ABC123",
"app_version": "1.0.0"
}
Response:
{
"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:
{
"license_key": "XXXX-XXXX-XXXX-XXXX",
"hardware_hash": "unique-hardware-identifier",
"app_version": "1.0.0"
}
Response:
{
"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:
{
"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:
{
"current_version": "1.0.0",
"license_key": "XXXX-XXXX-XXXX-XXXX"
}
Response:
{
"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:
{
"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 querypage: Page number (default: 1)
Response:
{
"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:
{
"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:
{
"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:
{
"success": true,
"is_active": true,
"message": "License activated successfully"
}
POST /api/licenses/bulk-activate
Activate multiple licenses.
Request:
{
"license_ids": [1, 2, 3]
}
Response:
{
"success": true,
"count": 3,
"message": "3 licenses activated successfully"
}
POST /api/licenses/bulk-deactivate
Deactivate multiple licenses.
Request:
{
"license_ids": [1, 2, 3]
}
Response:
{
"success": true,
"count": 3,
"message": "3 licenses deactivated successfully"
}
POST /api/licenses/bulk-delete
Delete multiple licenses.
Request:
{
"license_ids": [1, 2, 3]
}
Response:
{
"success": true,
"deleted": 3,
"message": "3 licenses deleted successfully"
}
POST /api/license/{license_id}/quick-edit
Quick edit license properties.
Request:
{
"valid_until": "2027-01-01",
"max_activations": 10,
"max_users": 50
}
Response:
{
"success": true,
"message": "License updated successfully"
}
POST /api/generate-license-key
Generate a new license key.
Response:
{
"license_key": "NEW1-NEW2-NEW3-NEW4"
}
Device Management API
GET /api/license/{license_id}/devices
Get devices for a license.
Response:
{
"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:
{
"hardware_hash": "unique-hardware-identifier",
"machine_name": "DESKTOP-XYZ789",
"app_version": "1.0.0"
}
Response:
{
"success": true,
"device_id": 456,
"message": "Device registered successfully"
}
POST /api/license/{license_id}/deactivate-device/{device_id}
Deactivate a device.
Response:
{
"success": true,
"message": "Device deactivated successfully"
}
Resource Management API
GET /api/license/{license_id}/resources
Get resources for a license.
Response:
{
"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:
{
"license_id": 123,
"resource_ids": [789, 790]
}
Response:
{
"success": true,
"allocated": 2,
"message": "2 resources allocated successfully"
}
GET /api/resources/check-availability
Check resource availability.
Query Parameters:
type: Resource typecount: Number of resources needed
Response:
{
"available": true,
"count": 5,
"resources": [
{
"id": 791,
"type": "server",
"identifier": "SRV-002"
}
]
}
GET /api/resources/stats
Get resource statistics.
Response:
{
"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 querytype: Entity type filter (customer, license, device)limit: Maximum results (default: 20)
Response:
{
"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:
{
"count": 42
}
Monitoring API
GET /api/monitoring/live-stats
Get live statistics for monitoring.
Response:
{
"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:
{
"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:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_at": "2025-06-19T15:30:00Z"
}
Lead Management API
GET /leads/api/stats
Get lead statistics.
Response:
{
"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 pageGET /leads/create- Create lead formPOST /leads/create- Save new leadGET /leads/edit/{lead_id}- Edit lead formPOST /leads/update/{lead_id}- Update leadPOST /leads/delete/{lead_id}- Delete leadGET /leads/export- Export leadsPOST /leads/import- Import leads
Common Response Codes
200 OK: Successful request201 Created: Resource created400 Bad Request: Invalid request data401 Unauthorized: Missing or invalid authentication403 Forbidden: Insufficient permissions404 Not Found: Resource not found409 Conflict: Resource conflict (e.g., duplicate)429 Too Many Requests: Rate limit exceeded500 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
{
"error": {
"code": "INVALID_LICENSE",
"message": "The provided license key is invalid",
"details": {
"field": "license_key",
"reason": "format_invalid"
}
}
}
Client Integration Examples
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
public class LicenseClient
{
private readonly HttpClient _httpClient;
private readonly string _baseUrl;
public LicenseClient(string baseUrl)
{
_baseUrl = baseUrl;
_httpClient = new HttpClient();
}
public async Task<ActivationResponse> 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<ActivationResponse>();
}
}
Webhooks
Configuration
Configure webhooks in the admin panel to receive notifications for:
- License activation
- License expiration
- Suspicious activity
- Usage threshold alerts
Webhook Payload
{
"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