Bravura Admin Pro - API Reference

Back to Documentation Hub

Bravura Admin Pro - API Reference

Version 1.1.0

Last Updated: October 21, 2025

Complete API documentation for Bravura Admin Pro licensing infrastructure.

---

Table of Contents

---

Overview

Bravura Admin Pro provides a RESTful API for license validation, activation, and management.

Base URL


Production: https://yourdomain.com/api
Development: http://localhost:8000/api

Response Format

All API responses follow this format:


{
    "success": true,
    "message": "Operation completed successfully",
    "timestamp": "2025-01-15T12:00:00Z",
    "data": { /* endpoint-specific data */ }
}

Error responses:


{
    "success": false,
    "message": "Error description",
    "error_code": "ERROR_CODE",
    "timestamp": "2025-01-15T12:00:00Z",
    "details": { /* additional error information */ }
}

Content Type

All requests and responses use application/json unless otherwise specified.

---

Authentication

Admin Authentication

Admin endpoints require JWT bearer token authentication.

Obtain Token:


POST /api/admin/login
Content-Type: application/x-www-form-urlencoded

username=admin&password=your_password

Response:


{
    "success": true,
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "token_type": "bearer",
    "expires_in": 28800
}

Using Token:


GET /api/admin/licenses
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Customer Authentication

Customer portal uses password or license key authentication.

Password Login:


POST /api/customer/login
Content-Type: application/json

{
    "email": "customer@example.com",
    "password": "customer_password"
}

License Key Login:


POST /api/customer/login-license
Content-Type: application/json

{
    "license_key": "XXXX-XXXX-XXXX-XXXX"
}

---

License Validation

Validate License

Verify a license key and optionally bind to a machine ID.

Endpoint: POST /api/licenses/validate

Request:


{
    "license_key": "XXXX-XXXX-XXXX-XXXX",
    "machine_id": "optional-machine-identifier",
    "app_version": "1.0.0"
}

Success Response:


{
    "success": true,
    "valid": true,
    "tier": "PROFESSIONAL",
    "expires": "2026-01-15",
    "license_type": "PERPETUAL",
    "subscription_active": null,
    "offline_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "features": [
        "complete_admin_panel",
        "subscription_billing",
        "white_label",
        "priority_support"
    ],
    "remaining_activations": 4,
    "has_update_access": true,
    "update_expiry_date": "2026-01-15",
    "update_access_status": "Active",
    "can_access_source": false,
    "signed_license_data": {
        "license_key": "XXXX-XXXX-XXXX-XXXX",
        "tier": "PROFESSIONAL",
        "expires": "2026-01-15",
        "signature": "cryptographic_signature_here"
    }
}

Invalid License Response:


{
    "success": true,
    "valid": false,
    "message": "License has been revoked"
}

Validation Rules:

---

License Activation

Activate License

Bind a license to a specific machine ID.

Endpoint: POST /api/licenses/activate

Request:


{
    "license_key": "XXXX-XXXX-XXXX-XXXX",
    "machine_id": "MACHINE-UUID-HERE",
    "machine_name": "John's MacBook Pro",
    "app_version": "1.0.0"
}

Success Response:


{
    "success": true,
    "activated": true,
    "activation_count": 1,
    "max_activations": 5,
    "license_data": {
        "license_key": "XXXX-XXXX-XXXX-XXXX",
        "tier": "PROFESSIONAL",
        "expires": "2026-01-15",
        "activated_at": "2025-01-15T12:00:00Z"
    }
}

Activation Limit Exceeded:


{
    "success": false,
    "activated": false,
    "message": "Activation limit exceeded. You have used 5 of 5 activations.",
    "activation_count": 5,
    "max_activations": 5
}

Activation Rules:

---

Revocation List

Get Revocation List

Retrieve SHA256 hashes of revoked license keys for offline validation.

Endpoint: GET /api/licenses/revocation-list

Response:


{
    "success": true,
    "revoked_hashes": [
        "a1b2c3d4e5f6...",
        "f6e5d4c3b2a1..."
    ],
    "count": 2,
    "last_updated": "2025-01-15T12:00:00Z",
    "cache_ttl": 86400
}

Usage:

  1. Download list periodically (recommended: daily)
  2. Cache locally
  3. Hash license key with SHA256
  4. Check if hash exists in revoked list
  5. Reject if found in list

Example Validation:


import hashlib

# Hash the license key
license_hash = hashlib.sha256(license_key.encode()).hexdigest()

# Check against revocation list
if license_hash in revoked_hashes:
    print("License has been revoked")
else:
    print("License is valid")

---

Admin Endpoints

List Licenses

Endpoint: GET /api/admin/licenses

Query Parameters:

Response:


{
    "success": true,
    "licenses": [
        {
            "id": 1,
            "license_key": "XXXX-XXXX-XXXX-XXXX",
            "tier": "PROFESSIONAL",
            "status": "ACTIVE",
            "license_type": "PERPETUAL",
            "expiration_date": "2026-01-15",
            "activation_count": 1,
            "max_activations": 5,
            "customer_email": "customer@example.com",
            "created_at": "2025-01-15T12:00:00Z",
            "amount_paid": 3999.99,
            "currency": "USD"
        }
    ],
    "total": 150,
    "page": 1,
    "per_page": 25
}

Create License

Endpoint: POST /api/admin/licenses

Request:


{
    "customer_email": "customer@example.com",
    "tier": "PROFESSIONAL",
    "expiration_date": "2026-01-15",
    "max_activations": 5,
    "stripe_payment_intent": "pi_xxx",
    "amount_paid": 3999.99,
    "currency": "USD"
}

Response:


{
    "success": true,
    "message": "License created successfully",
    "license": {
        "id": 1,
        "license_key": "XXXX-XXXX-XXXX-XXXX",
        "tier": "PROFESSIONAL",
        "status": "ACTIVE",
        "customer_email": "customer@example.com"
    }
}

Update License

Endpoint: PUT /api/admin/licenses/{license_id}

Request:


{
    "status": "SUSPENDED",
    "tier": "ENTERPRISE",
    "expiration_date": "2027-01-15",
    "max_activations": 25,
    "update_expiry_date": "2027-01-15"
}

Response:


{
    "success": true,
    "message": "License updated successfully",
    "license": {
        "id": 1,
        "status": "SUSPENDED",
        "tier": "ENTERPRISE"
    }
}

Revoke License

Endpoint: POST /api/admin/licenses/{license_id}/revoke

Request:


{
    "reason": "Customer requested refund"
}

Response:


{
    "success": true,
    "message": "License revoked successfully",
    "license_id": 1
}

Dashboard Statistics

Endpoint: GET /api/admin/stats

Response:


{
    "licenses": {
        "total_licenses": 150,
        "active_licenses": 130,
        "expired_licenses": 10,
        "revoked_licenses": 10,
        "by_tier": {
            "STANDARD": 50,
            "PROFESSIONAL": 75,
            "ENTERPRISE": 25
        },
        "total_revenue": 549850.00,
        "refunded_licenses": 5,
        "refund_rate": 3.3
    },
    "customers": {
        "total_customers": 140
    },
    "subscriptions": {
        "active_subscriptions": 50,
        "mrr": 4999.50
    }
}

---

Stripe Webhooks

Webhook Endpoint

Endpoint: POST /api/webhooks/stripe

Headers:


Stripe-Signature: t=timestamp,v1=signature

Supported Events:

Event Processing:

  1. Verify webhook signature
  2. Check for duplicate events (idempotency)
  3. Process event based on type
  4. Send customer notifications
  5. Log event

Webhook Testing:

Use Stripe CLI to test webhooks locally:


stripe listen --forward-to localhost:8000/api/webhooks/stripe
stripe trigger payment_intent.succeeded

---

Customer Portal

Get Customer Licenses

Endpoint: GET /api/customer/licenses

Headers:


Authorization: Bearer {customer_token}

Response:


{
    "success": true,
    "licenses": [
        {
            "license_key": "XXXX-XXXX-XXXX-XXXX",
            "tier": "PROFESSIONAL",
            "status": "ACTIVE",
            "license_type": "PERPETUAL",
            "expires": "2026-01-15",
            "created_at": "2025-01-15T12:00:00Z",
            "product_name": "Your Software"
        }
    ]
}

Get Download Links

Endpoint: GET /api/customer/downloads

Headers:


Authorization: Bearer {customer_token}

Response:


{
    "success": true,
    "downloads": [
        {
            "version": "1.0.0",
            "tier": "PROFESSIONAL",
            "release_date": "2025-01-15",
            "download_url": "https://yourdomain.com/downloads/...",
            "file_size": 52428800,
            "release_notes": "Initial release"
        }
    ]
}

---

Error Codes

Code Description
`INVALID_LICENSE` License key not found or invalid format
`LICENSE_EXPIRED` License has passed expiration date
`LICENSE_REVOKED` License has been revoked
`LICENSE_SUSPENDED` License is temporarily suspended
`ACTIVATION_LIMIT_EXCEEDED` Too many activations
`SUBSCRIPTION_INACTIVE` Subscription has expired or canceled
`INVALID_CREDENTIALS` Login failed
`UNAUTHORIZED` Authentication required
`FORBIDDEN` Insufficient permissions
`NOT_FOUND` Resource not found
`VALIDATION_ERROR` Request validation failed
`RATE_LIMIT_EXCEEDED` Too many requests
`WEBHOOK_SIGNATURE_INVALID` Stripe signature verification failed
`DATABASE_ERROR` Database operation failed
`INTERNAL_ERROR` Unexpected server error

---

Rate Limiting

Limits

Rate Limit Headers


X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1642262400

Rate Limit Exceeded Response


{
    "success": false,
    "error_code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Please retry after 60 seconds.",
    "retry_after": 60
}

---

Code Examples

Python - License Validation


import requests

def validate_license(license_key, machine_id=None):
    url = "https://yourdomain.com/api/licenses/validate"
    data = {
        "license_key": license_key,
        "machine_id": machine_id,
        "app_version": "1.0.0"
    }

    response = requests.post(url, json=data)
    result = response.json()

    if result["success"] and result["valid"]:
        print(f"License valid! Tier: {result['tier']}")
        return True
    else:
        print(f"License invalid: {result.get('message')}")
        return False

# Usage
validate_license("XXXX-XXXX-XXXX-XXXX", "MACHINE-UUID")

JavaScript - Admin Login


async function adminLogin(username, password) {
    const formData = new URLSearchParams();
    formData.append('username', username);
    formData.append('password', password);

    const response = await fetch('https://yourdomain.com/api/admin/login', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: formData
    });

    const result = await response.json();

    if (result.success) {
        localStorage.setItem('admin_token', result.access_token);
        console.log('Login successful');
        return result.access_token;
    } else {
        console.error('Login failed:', result.message);
        return null;
    }
}

// Usage
adminLogin('admin', 'your_password');

C# - License Activation


using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

public class LicenseActivator
{
    private readonly HttpClient _httpClient;

    public LicenseActivator()
    {
        _httpClient = new HttpClient();
    }

    public async Task<bool> ActivateLicense(string licenseKey, string machineId)
    {
        var url = "https://yourdomain.com/api/licenses/activate";
        var data = new
        {
            license_key = licenseKey,
            machine_id = machineId,
            machine_name = Environment.MachineName,
            app_version = "1.0.0"
        };

        var json = JsonSerializer.Serialize(data);
        var content = new StringContent(json, Encoding.UTF8, "application/json");

        var response = await _httpClient.PostAsync(url, content);
        var responseJson = await response.Content.ReadAsStringAsync();
        var result = JsonSerializer.Deserialize<ActivationResponse>(responseJson);

        if (result.success && result.activated)
        {
            Console.WriteLine({{RenderedMarkdown}}quot;License activated! {result.activation_count}/{result.max_activations} activations used");
            return true;
        }
        else
        {
            Console.WriteLine({{RenderedMarkdown}}quot;Activation failed: {result.message}");
            return false;
        }
    }
}

public class ActivationResponse
{
    public bool success { get; set; }
    public bool activated { get; set; }
    public string message { get; set; }
    public int activation_count { get; set; }
    public int max_activations { get; set; }
}

---

Security Best Practices

API Keys

Webhook Security

License Validation

---

Support

For API questions or issues:

---

Bravura Admin Pro API Reference v1.0.0

Copyright © 2025 Wigley Studios LLC. All rights reserved.