Dateien
Hetzner-Backup/API_REFERENCE.md
2025-06-19 17:52:21 +02:00

9.5 KiB

V2-Docker API Reference

License Server API

Public Endpoints

POST /api/v1/activate

Activate a license on a new system.

Request:

{
  "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:

{
  "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:

{
  "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:

{
  "valid": true,
  "features": ["feature1", "feature2"],
  "max_users": 10,
  "message": "License valid"
}

POST /api/v1/heartbeat

Send usage heartbeat.

Request:

{
  "license_key": "XXXX-XXXX-XXXX-XXXX",
  "activation_id": "act_123456",
  "current_users": 5,
  "feature_usage": {
    "feature1": 150,
    "feature2": 75
  }
}

Response:

{
  "success": true,
  "next_heartbeat": "2025-01-01T12:30:00Z"
}

POST /api/v1/deactivate

Deactivate a license.

Request:

{
  "license_key": "XXXX-XXXX-XXXX-XXXX",
  "activation_id": "act_123456",
  "reason": "System upgrade"
}

Response:

{
  "success": true,
  "message": "License deactivated successfully"
}

Admin API Endpoints

Authentication

All admin endpoints require JWT authentication:

Authorization: Bearer <jwt_token>

GET /api/v1/admin/licenses

List all licenses.

Query Parameters:

  • page (default: 1)
  • per_page (default: 50)
  • status (active, inactive, expired)
  • customer_id

Response:

{
  "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:

{
  "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:

{
  "id": 456,
  "license_key": "NEW1-NEW2-NEW3-NEW4",
  "message": "License created successfully"
}

GET /api/v1/admin/licenses/{id}

Get license details.

Response:

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "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

{
  "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