Base URL

http://localhost:47293/api

Authentication

JWT Bearer Token

Rate Limiting

100 req/min (API), 10 req/min (validation)

Encryption

AES-256-GCM + RSA-4096

Authentication

All protected endpoints require a JWT token in the Authorization header.

Authorization: Bearer <your_jwt_token>
Get your token by calling POST /api/auth/login with your credentials.

Quick Start

1. Register
curl -X POST http://localhost:47293/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"secret123","display_name":"John"}'
2. Login
curl -X POST http://localhost:47293/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"secret123"}'
3. Create Product
curl -X POST http://localhost:47293/api/products \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"My App","description":"My application"}'
4. Create License
curl -X POST http://localhost:47293/api/licenses \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"product_id":"PRODUCT_ID","type":"subscription","max_uses":1,"hwid_locked":true}'

Auth

User authentication and profile management.

POST /auth/register Register new user
Request Body
{
  "email": "[email protected]",
  "password": "securepassword123",
  "display_name": "John Doe"
}
Response
{
  "success": true,
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIs...",
    "user": {
      "id": "uuid",
      "email": "[email protected]",
      "display_name": "John Doe",
      "role": "user"
    }
  }
}
POST /auth/login Login and get JWT token
Request Body
{
  "email": "[email protected]",
  "password": "securepassword123"
}
Response
{
  "success": true,
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIs...",
    "user": { ... }
  }
}
POST /auth/refresh Refresh JWT token Auth
Response
{
  "success": true,
  "data": {
    "token": "new_jwt_token..."
  }
}
GET /auth/me Get current user profile Auth
Response
{
  "success": true,
  "data": {
    "id": "uuid",
    "email": "[email protected]",
    "display_name": "John Doe",
    "role": "user",
    "created_at": "2025-01-01T00:00:00Z"
  }
}

Products

Manage your software products.

GET /products List all products Auth
Response
{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "name": "My Application",
      "description": "...",
      "secret_key": "sk_live_...",
      "is_active": true,
      "created_at": "2025-01-01T00:00:00Z"
    }
  ]
}
POST /products Create a new product Auth
Request Body
{
  "name": "My Application",
  "description": "Professional software application"
}
Response
{
  "success": true,
  "data": {
    "id": "uuid",
    "name": "My Application",
    "secret_key": "sk_live_abc123...",
    ...
  }
}
GET /products/:id Get product by ID Auth
ParameterTypeDescription
iduuidProduct ID
PUT /products/:id Update product Auth
Request Body
{
  "name": "Updated Name",
  "description": "Updated description",
  "is_active": true
}
DELETE /products/:id Delete product Auth
This will also delete all associated licenses.
POST /products/:id/regenerate-key Regenerate secret key Auth
This will invalidate all existing SDK integrations!
Response
{
  "success": true,
  "data": {
    "secret_key": "sk_live_new_key..."
  }
}

Licenses

Create and manage software licenses.

GET /licenses List licenses with filters Auth
Query ParamTypeDescription
product_iduuidFilter by product
statusstringactive, expired, suspended
typestringtrial, subscription, lifetime
pageintegerPage number (default: 1)
limitintegerItems per page (default: 20)
POST /licenses Create a single license Auth
Request Body
{
  "product_id": "uuid",
  "type": "subscription",  // trial, subscription, lifetime
  "max_uses": 1,
  "hwid_locked": true,
  "expires_at": "2025-12-31T23:59:59Z",
  "metadata": {
    "plan": "pro",
    "features": ["feature1", "feature2"]
  }
}
Response
{
  "success": true,
  "data": {
    "id": "uuid",
    "license_key": "XXXX-XXXX-XXXX-XXXX",
    "type": "subscription",
    "status": "active",
    ...
  }
}
POST /licenses/bulk Bulk create licenses Auth
Request Body
{
  "product_id": "uuid",
  "count": 10,  // max 100
  "type": "subscription",
  "max_uses": 1,
  "hwid_locked": true,
  "expires_at": "2025-12-31T23:59:59Z"
}
Response
{
  "success": true,
  "data": {
    "created": 10,
    "licenses": [ ... ]
  }
}
GET /licenses/:id Get license by ID Auth
Response
{
  "success": true,
  "data": {
    "id": "uuid",
    "license_key": "XXXX-XXXX-XXXX-XXXX",
    "product_id": "uuid",
    "type": "subscription",
    "status": "active",
    "hwid": "abc123...",
    "hwid_locked": true,
    "max_uses": 1,
    "current_uses": 1,
    "expires_at": "2025-12-31T23:59:59Z",
    "metadata": {},
    "created_at": "2025-01-01T00:00:00Z"
  }
}
PUT /licenses/:id Update license Auth
Request Body
{
  "status": "suspended",
  "max_uses": 2,
  "hwid_locked": false,
  "expires_at": "2026-12-31T23:59:59Z",
  "metadata": { "note": "Updated" }
}
DELETE /licenses/:id Delete license Auth
POST /licenses/:id/reset-hwid Reset HWID lock Auth

Clears the hardware ID, allowing the license to be activated on a new device.

GET /licenses/:id/logs Get license activity logs Auth
Query ParamTypeDescription
pageintegerPage number
limitintegerItems per page
Response
{
  "success": true,
  "data": {
    "logs": [
      {
        "id": "uuid",
        "action": "activation",
        "ip_address": "192.168.1.1",
        "hwid": "abc123...",
        "user_agent": "...",
        "created_at": "2025-01-01T00:00:00Z"
      }
    ],
    "pagination": { ... }
  }
}

Client API

Endpoints used by your software to validate licenses. No authentication required.

POST /client/validate Validate license without activating
Request Body
{
  "license_key": "XXXX-XXXX-XXXX-XXXX",
  "hwid": "hardware_id_hash",
  "product_id": "uuid"
}
Response
{
  "success": true,
  "data": {
    "valid": true,
    "license": {
      "type": "subscription",
      "expires_at": "2025-12-31T23:59:59Z",
      "metadata": {}
    },
    "signature": "base64_rsa_signature",
    "watermark": "unique_watermark"
  }
}
POST /client/activate Activate license and create session
Request Body
{
  "license_key": "XXXX-XXXX-XXXX-XXXX",
  "hwid": "hardware_id_hash",
  "product_id": "uuid",
  "client_data": {
    "platform": "win32",
    "os_version": "10.0.19041",
    "vm_indicators": [],
    "debug_indicators": []
  }
}
Response
{
  "success": true,
  "data": {
    "activated": true,
    "session": {
      "token": "session_token",
      "expires_at": "2025-01-02T00:00:00Z"
    },
    "license": {
      "type": "subscription",
      "expires_at": "2025-12-31T23:59:59Z",
      "metadata": {}
    },
    "signature": "base64_rsa_signature"
  }
}
POST /client/deactivate Deactivate license and end session
Request Body
{
  "license_key": "XXXX-XXXX-XXXX-XXXX",
  "hwid": "hardware_id_hash",
  "product_id": "uuid"
}
POST /client/heartbeat Session heartbeat (call every 5 min)
Request Body
{
  "license_key": "XXXX-XXXX-XXXX-XXXX",
  "hwid": "hardware_id_hash",
  "product_id": "uuid",
  "session_token": "current_session_token"
}
Response
{
  "success": true,
  "data": {
    "valid": true,
    "new_token": "rotated_token_if_applicable"
  }
}
POST /client/verify-challenge Verify challenge-response
Request Body
{
  "license_key": "XXXX-XXXX-XXXX-XXXX",
  "hwid": "hardware_id_hash",
  "challenge": "random_challenge_string",
  "response": "hmac_sha256_response"
}
GET /client/public-key Get RSA public key for signature verification
Response
{
  "success": true,
  "data": {
    "public_key": "-----BEGIN PUBLIC KEY-----\nMIICIj...\n-----END PUBLIC KEY-----"
  }
}

Security

Security management endpoints. Admin access required.

Blacklist Management

GET /security/blacklist List blacklist entries Admin
Query ParamTypeDescription
typestringip, hwid, license, fingerprint
severitystringlow, medium, high, critical
is_activebooleanFilter active/inactive
page, limitintegerPagination
POST /security/blacklist Add to blacklist Admin
Request Body
{
  "type": "ip",  // ip, hwid, license, fingerprint
  "value": "192.168.1.100",
  "reason": "Brute force attack detected",
  "severity": "high",  // low, medium, high, critical
  "expires_at": "2025-02-01T00:00:00Z"  // optional
}
PUT /security/blacklist/:id/disable Disable blacklist entry Admin
DELETE /security/blacklist/:id Delete blacklist entry Admin

Security Events

GET /security/events List security events Admin
Query ParamTypeDescription
event_typestringFilter by event type
severitystringinfo, low, medium, high, critical
license_iduuidFilter by license
ip_addressstringFilter by IP
hwidstringFilter by HWID
is_blockedbooleanFilter blocked attempts
start_datedatetimeFilter start
end_datedatetimeFilter end
Event Types
license_validation, license_activation, license_deactivation,
hwid_mismatch, hwid_spoof_attempt, ip_mismatch, geo_anomaly,
debug_detected, vm_detected, tamper_detected, replay_attack,
brute_force, blacklist_hit, session_hijack, rate_limit_exceeded
GET /security/stats Security statistics overview Admin
Response
{
  "success": true,
  "data": {
    "overview": {
      "today_events": 45,
      "critical_events": 2,
      "blocked_attempts": 15,
      "active_blacklist": 8,
      "active_sessions": 120
    },
    "events_by_type": [...],
    "events_by_severity": [...],
    "daily_trend": [...]
  }
}

Sessions

GET /security/sessions List active sessions Admin
Query ParamTypeDescription
license_iduuidFilter by license
is_activebooleanFilter active/inactive
page, limitintegerPagination
POST /security/sessions/:id/revoke Revoke a session Admin
Request Body
{
  "reason": "Suspicious activity detected"
}
POST /security/sessions/license/:license_id/revoke-all Revoke all sessions for a license Admin
Request Body
{
  "reason": "License compromised"
}

Quick Actions

POST /security/block-ip Quick block IP address Admin
Request Body
{
  "ip": "192.168.1.100",
  "reason": "Malicious activity",
  "duration_hours": 24  // optional, default 24
}
POST /security/block-hwid Quick block HWID Admin
Request Body
{
  "hwid": "abc123def456...",
  "reason": "License sharing detected",
  "duration_hours": 720  // optional, default 720 (30 days)
}

Webhooks

Configure webhooks to receive real-time notifications.

GET /webhooks List all webhooks Auth
POST /webhooks Create a webhook Auth
Request Body
{
  "url": "https://your-server.com/webhook",
  "events": [
    "license.created",
    "license.activated",
    "license.expired",
    "license.suspended",
    "security.alert"
  ],
  "secret": "your_webhook_secret"
}
Available Events
license.created, license.activated, license.deactivated,
license.expired, license.suspended, license.deleted,
security.alert, security.blocked
PUT /webhooks/:id Update webhook Auth
Request Body
{
  "url": "https://new-url.com/webhook",
  "events": ["license.created"],
  "secret": "new_secret",
  "is_active": true
}
DELETE /webhooks/:id Delete webhook Auth
POST /webhooks/:id/test Send test event Auth
Response
{
  "success": true,
  "data": {
    "status_code": 200,
    "response_time_ms": 150
  }
}

Statistics

Analytics and statistics endpoints.

GET /stats/dashboard Dashboard overview statistics Auth
Response
{
  "success": true,
  "data": {
    "total_products": 5,
    "total_licenses": 150,
    "active_licenses": 120,
    "total_activations": 500,
    "recent_activity": [...]
  }
}
GET /stats/products/:id Product-specific statistics Auth
Response
{
  "success": true,
  "data": {
    "total_licenses": 50,
    "active_licenses": 45,
    "expired_licenses": 3,
    "suspended_licenses": 2,
    "activations_today": 5,
    "activations_this_week": 25,
    "activations_this_month": 100
  }
}

Notifications

User notification management.

GET /notifications List notifications Auth
Response
{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "type": "license_expired",
      "title": "License Expired",
      "message": "License XXXX-XXXX expired",
      "is_read": false,
      "created_at": "2025-01-01T00:00:00Z"
    }
  ]
}
GET /notifications/unread-count Get unread notification count Auth
Response
{
  "success": true,
  "data": { "count": 5 }
}
PUT /notifications/:id/read Mark notification as read Auth
PUT /notifications/read-all Mark all as read Auth

Admin

Admin-only endpoints for system management.

GET /admin/users List all users Admin
PUT /admin/users/:id Update user Admin
Request Body
{
  "role": "admin",  // user, admin
  "is_active": true
}
DELETE /admin/users/:id Delete user Admin
GET /admin/settings Get system settings Admin
PUT /admin/settings Update system settings Admin

Error Codes

Standard error response format and codes.

Error Response Format
{
  "success": false,
  "message": "Error description",
  "error_code": "ERROR_CODE"
}
Security Block Response
{
  "success": false,
  "message": "Access denied",
  "security_blocked": true,
  "security_details": {
    "reason": "blacklist_hit",
    "type": "ip"
  }
}
CodeDescription
400Bad Request - Invalid input
401Unauthorized - Authentication required
403Forbidden - Insufficient permissions
404Not Found - Resource doesn't exist
409Conflict - Resource already exists
429Too Many Requests - Rate limited
500Internal Server Error
License Error Codes
Error CodeDescription
LICENSE_NOT_FOUNDLicense key doesn't exist
LICENSE_EXPIREDLicense has expired
LICENSE_SUSPENDEDLicense is suspended
HWID_MISMATCHHardware ID doesn't match
MAX_USES_EXCEEDEDMaximum activations reached
PRODUCT_NOT_FOUNDProduct doesn't exist
BLACKLISTEDIP/HWID is blacklisted
SESSION_EXPIREDSession token expired
SECURITY_VIOLATIONSecurity check failed

Encryption

Client requests can be encrypted using AES-256-GCM for enhanced security.

Encrypted Request Format
{
  "encrypted": true,
  "iv": "hex_encoded_iv_16_bytes",
  "data": "hex_encoded_ciphertext",
  "tag": "hex_encoded_auth_tag_16_bytes",
  "signature": "hmac_sha256_signature",
  "product_id": "uuid",
  "timestamp": 1704067200000
}
Signature Calculation
signature = HMAC-SHA256(
  secret_key,
  iv + ":" + data + ":" + tag + ":" + timestamp
)
The timestamp must be within 30 seconds of server time to prevent replay attacks.

SDK Guide

13 farklı dil için SDK desteği. Tüm SDK'lar HWID, şifreleme, heartbeat ve güvenlik özelliklerini destekler.

Desteklenen Diller

Node.js, Python, C#, Go, Java, PHP, Rust, Ruby, Lua, C++, Kotlin, Swift, Delphi

Özellikler

AES-256-GCM, HMAC-SHA256, HWID, Auto Heartbeat, VM Detection

Installation
npm install ./sdk/nodejs
Usage
const LicenseCM = require('licensecm');

const client = new LicenseCM({
  baseUrl: 'https://verify.licensekit.cloud',
  productId: 'YOUR_PRODUCT_ID',
  secretKey: 'YOUR_SECRET_KEY',
  useEncryption: true,
  autoHeartbeat: true,
  heartbeatInterval: 5 * 60 * 1000,

  onSessionExpired: () => {
    console.log('Session expired!');
    process.exit(1);
  },
  onSecurityViolation: (details) => {
    console.error('Security violation:', details);
    process.exit(1);
  }
});

async function main() {
  await client.initialize();
  const result = await client.activate('XXXX-XXXX-XXXX-XXXX');
  console.log('License active!', result);
}

main();
Installation
pip install pycryptodome
# Copy sdk/python/licensecm.py to your project
Usage
from licensecm import LicenseCM

client = LicenseCM(
    base_url="https://verify.licensekit.cloud",
    product_id="YOUR_PRODUCT_ID",
    secret_key="YOUR_SECRET_KEY",
    use_encryption=True,
    auto_heartbeat=True,
    heartbeat_interval=300,
    on_session_expired=lambda: exit(1),
    on_security_violation=lambda d: print(f"Violation: {d}")
)

client.initialize()
result = client.activate("XXXX-XXXX-XXXX-XXXX")
print("License active!", result)
Installation
// Add sdk/csharp/LicenseCM.cs to your project
Usage
using LicenseCM;

using var client = new LicenseCMClient(
    baseUrl: "https://verify.licensekit.cloud",
    productId: "YOUR_PRODUCT_ID",
    secretKey: "YOUR_SECRET_KEY",
    useEncryption: true,
    autoHeartbeat: true
);

client.SessionExpired += (s, e) => Environment.Exit(1);
client.SecurityViolation += (s, e) => Console.WriteLine($"Violation: {e.Reason}");

await client.InitializeAsync();
var result = await client.ActivateAsync("XXXX-XXXX-XXXX-XXXX");
Console.WriteLine("License active!");
Installation
go get github.com/licensecm/sdk-go
Usage
package main

import (
    "fmt"
    licensecm "github.com/licensecm/sdk-go"
)

func main() {
    client := licensecm.NewClient(
        "https://verify.licensekit.cloud",
        "YOUR_PRODUCT_ID",
        "YOUR_SECRET_KEY",
    )
    client.UseEncryption = true
    client.AutoHeartbeat = true

    client.OnSessionExpired = func() { os.Exit(1) }
    client.OnSecurityViolation = func(d map[string]interface{}) {
        fmt.Println("Violation:", d)
    }

    client.Initialize()
    result, _ := client.Activate("XXXX-XXXX-XXXX-XXXX", "")
    fmt.Println("License active!", result)
}
Maven Dependency
<dependency>
    <groupId>com.licensecm</groupId>
    <artifactId>licensecm-sdk</artifactId>
    <version>1.0.0</version>
</dependency>
Usage
import com.licensecm.LicenseCM;

LicenseCM client = new LicenseCM(
    "https://verify.licensekit.cloud",
    "YOUR_PRODUCT_ID",
    "YOUR_SECRET_KEY"
);

client.setUseEncryption(true)
      .setAutoHeartbeat(true)
      .setOnSessionExpired(() -> System.exit(1))
      .setOnSecurityViolation(d -> System.out.println("Violation: " + d));

client.initialize();
JSONObject result = client.activate("XXXX-XXXX-XXXX-XXXX", null);
System.out.println("License active! " + result);
Installation
composer require licensecm/sdk
Usage
<?php
use LicenseCM\LicenseCMClient;

$client = new LicenseCMClient(
    'https://verify.licensekit.cloud',
    'YOUR_PRODUCT_ID',
    'YOUR_SECRET_KEY'
);

$client->setUseEncryption(true)
       ->setAutoHeartbeat(true)
       ->setOnSessionExpired(fn() => exit(1))
       ->setOnSecurityViolation(fn($d) => print_r($d));

$client->initialize();
$result = $client->activate('XXXX-XXXX-XXXX-XXXX');
echo "License active!";
Cargo.toml
[dependencies]
licensecm = "1.0"
Usage
use licensecm::LicenseCMClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = LicenseCMClient::new(
        "https://verify.licensekit.cloud",
        "YOUR_PRODUCT_ID",
        "YOUR_SECRET_KEY",
    );

    client.set_use_encryption(true)
          .set_auto_heartbeat(true);

    client.initialize().await?;
    let result = client.activate("XXXX-XXXX-XXXX-XXXX", None).await?;
    println!("License active! {:?}", result);
    Ok(())
}
Installation
gem install licensecm
Usage
require 'licensecm'

client = LicenseCM::Client.new(
  base_url: 'https://verify.licensekit.cloud',
  product_id: 'YOUR_PRODUCT_ID',
  secret_key: 'YOUR_SECRET_KEY'
)

client.use_encryption = true
client.auto_heartbeat = true
client.on_session_expired = -> { exit(1) }
client.on_security_violation = ->(d) { puts "Violation: #{d}" }

client.initialize_client
result = client.activate('XXXX-XXXX-XXXX-XXXX')
puts "License active! #{result}"
Gradle
implementation("com.licensecm:sdk:1.0.0")
Usage
import com.licensecm.LicenseCMClient

val client = LicenseCMClient(
    "https://verify.licensekit.cloud",
    "YOUR_PRODUCT_ID",
    "YOUR_SECRET_KEY"
).apply {
    useEncryption = true
    autoHeartbeat = true
    onSessionExpired = { System.exit(1) }
    onSecurityViolation = { println("Violation: $it") }
}

client.initialize()
val result = client.activate("XXXX-XXXX-XXXX-XXXX")
println("License active! $result")
Swift Package Manager
.package(url: "https://github.com/licensecm/sdk-swift", from: "1.0.0")
Usage
import LicenseCM

let client = LicenseCMClient(
    baseUrl: "https://verify.licensekit.cloud",
    productId: "YOUR_PRODUCT_ID",
    secretKey: "YOUR_SECRET_KEY"
)

client.useEncryption = true
client.autoHeartbeat = true
client.onSessionExpired = { exit(1) }
client.onSecurityViolation = { print("Violation: \($0)") }

client.initialize { _ in
    client.activate(licenseKey: "XXXX-XXXX-XXXX-XXXX") { result in
        print("License active!")
    }
}
Requirements
// libcurl, OpenSSL, nlohmann/json
// Compile: g++ -std=c++17 -o app main.cpp -lcurl -lssl -lcrypto
Usage
#include "licensecm.hpp"

int main() {
    LicenseCM::Client client(
        "https://verify.licensekit.cloud",
        "YOUR_PRODUCT_ID",
        "YOUR_SECRET_KEY"
    );

    client.setUseEncryption(true)
          .setAutoHeartbeat(true)
          .setOnSessionExpired([]() { exit(1); })
          .setOnSecurityViolation([](auto d) { /* handle */ });

    client.initialize();
    auto result = client.activate("XXXX-XXXX-XXXX-XXXX");
    std::cout << "License active!" << std::endl;
    return 0;
}
Requirements
-- luarocks install luasocket lua-cjson
Usage
local LicenseCM = require("licensecm")

local client = LicenseCM.new({
    base_url = "https://verify.licensekit.cloud",
    product_id = "YOUR_PRODUCT_ID",
    secret_key = "YOUR_SECRET_KEY",
    use_encryption = false,
    auto_heartbeat = true,
    on_session_expired = function() os.exit(1) end,
    on_security_violation = function(d) print("Violation:", d) end
})

client:initialize()
local result = client:activate("XXXX-XXXX-XXXX-XXXX")
print("License active!")
Installation
// Add LicenseCM.pas to your project uses clause
Usage
uses LicenseCM;

var
  Client: TLicenseCMClient;
begin
  Client := TLicenseCMClient.Create(nil);
  try
    Client.BaseUrl := 'https://verify.licensekit.cloud';
    Client.ProductId := 'YOUR_PRODUCT_ID';
    Client.SecretKey := 'YOUR_SECRET_KEY';
    Client.UseEncryption := True;
    Client.AutoHeartbeat := True;

    Client.OnSessionExpired := procedure(Sender: TObject) begin Halt(1); end;

    Client.Initialize;
    Client.Activate('XXXX-XXXX-XXXX-XXXX');
    WriteLn('License active!');
  finally
    Client.Free;
  end;
end.
RSA Keys: Public key is automatically fetched from /api/client/public-key. Keys are generated on first server start in backend/keys/.
SDK Dosyaları: Tüm SDK'lar /sdk klasöründe bulunur. Her dil için örnek kullanım dosyası mevcuttur.