Developer API Documentation
Integrate licensing, hardware device binding, and subscription validation into Flutter, Windows, macOS, Linux, and web applications.
https://keyauth.workss.in/api/v1
LicenseEngine provides a self-hosted licensing architecture comparable to modern software authorization platforms. All requests and responses communicate strictly via standard JSON over HTTPS.
Authentication Flow
Authentication follows a two-stage session handshake:
- Initialization (Handshake): The client calls
POST /api/v1/initwith its publicapp_idand client version. The server verifies app status, maintenance mode, and minimum semantic version, then issues a temporary high-entropysession_token. - Authentication: The client presents the
session_tokenalongside the user's license key and machinehwidtoPOST /api/v1/license. The server validates expiration, subscription, blacklists, binds machine HWID atomically, and elevates the session to authenticated. - Heartbeat & Verification: While running, applications periodically ping
POST /api/v1/heartbeatto confirm the session, license, and bans remain valid.
Client-Secret Security Model
Core Security Principle
Desktop and mobile client software (Flutter, C#, C++, Python binaries) can be decompiled and reverse engineered. Never embed server-side administrative credentials or master database secrets inside compiled client software!
Client apps only ever embed their public app_id. Session tokens are generated cryptographically using high-entropy random bytes, stored server-side as SHA-256 hashes, and slid automatically upon authenticated activity.
Initialize Application Session
Establishes a temporary API session token and verifies client version compatibility.
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
app_id | string | Yes | Public Application ID (e.g. app_xxxxxxxx). |
version | string | No | Semantic version of the client software (e.g. 1.0.0). |
Example Request (cURL)
curl -X POST "https://keyauth.workss.in/api/v1/init" \
-H "Content-Type: application/json" \
-d '{
"app_id": "YOUR_APP_PUBLIC_ID",
"version": "1.0.0"
}'
Success Response (200 OK)
{
"success": true,
"message": "Application initialized successfully.",
"data": {
"session_token": "7a3f892b1049281c7e90...",
"expires_in": 900,
"application": {
"name": "My App",
"version": "1.0.0",
"maintenance": false
}
}
}
Authenticate License Key
Validates license key status, calculates first activation expiry, and binds machine HWID.
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
session_token | string | Yes | Token obtained from /init. |
license | string | Yes | User license key string. |
hwid | string | Yes | Machine hardware fingerprint. |
device_name | string | No | Device / computer hostname. |
platform | string | No | Operating system (e.g. Windows, Android). |
Success Response (200 OK)
{
"success": true,
"message": "Authentication successful.",
"data": {
"expires_at": "2027-10-05T18:30:00Z",
"is_lifetime": false,
"subscriptions": [
{
"name": "Premium Tier",
"slug": "premium",
"level": 2
}
],
"device_limit": 1,
"registered_devices": 1
}
}
Lightweight Session Heartbeat
Keep-alive ping to ensure authenticated sessions, licenses, and bans remain valid.
curl -X POST "https://keyauth.workss.in/api/v1/heartbeat" \
-H "Content-Type: application/json" \
-d '{
"session_token": "YOUR_SESSION_TOKEN"
}'
Error Codes Reference
| Error Code | HTTP Status | Description |
|---|---|---|
INVALID_REQUEST | 422 | Form validation failure or missing required fields. |
INVALID_APP | 404 | Public Application ID does not exist. |
APP_DISABLED | 403 | Application has been paused or disabled by administrator. |
APP_MAINTENANCE | 403 | Application is in maintenance mode. |
VERSION_OUTDATED | 426 | Client software version is below minimum supported version. |
INVALID_SESSION | 401 | Session token does not exist or has expired. |
SESSION_EXPIRED | 401 | Session timed out due to inactivity. |
INVALID_LICENSE | 404 | License key does not exist. |
LICENSE_EXPIRED | 403 | License validity duration has lapsed. |
LICENSE_DISABLED | 403 | License has been temporarily disabled. |
LICENSE_BANNED | 403 | License was banned by admin. |
HWID_MISMATCH | 403 | Hardware device limit reached for this license. |
HWID_BANNED | 403 | Specific machine HWID is blacklisted. |
IP_BANNED | 403 | Client IP address is blacklisted. |
INVALID_CREDENTIALS | 401 | Username or password incorrect. |
USER_BANNED | 403 | User account is banned. |
RATE_LIMITED | 429 | Too many requests sent within rate limit window. |
Flutter / Dart Client SDK
Complete production-ready client class using the standard Dart http package.
import 'dart:convert';
import 'package:http/http.dart' as http;
class LicenseAuthClient {
final String baseUrl;
final String appId;
String? sessionToken;
LicenseAuthClient({required this.baseUrl, required this.appId});
/// Initialize application session
Future<Map<String, dynamic>> init({String version = '1.0.0'}) async {
final response = await http.post(
Uri.parse('$baseUrl/api/v1/init'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'app_id': appId, 'version': version}),
);
final data = jsonDecode(response.body);
if (data['success'] == true) {
sessionToken = data['data']['session_token'];
}
return data;
}
/// Authenticate license key with machine HWID
Future<Map<String, dynamic>> authenticateLicense({
required String license,
required String hwid,
String? deviceName,
String? platform,
}) async {
if (sessionToken == null) {
throw Exception('Session not initialized. Call init() first.');
}
final response = await http.post(
Uri.parse('$baseUrl/api/v1/license'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'session_token': sessionToken,
'license': license,
'hwid': hwid,
'device_name': deviceName,
'platform': platform,
}),
);
return jsonDecode(response.body);
}
/// Lightweight heartbeat verification
Future<bool> heartbeat({String? hwid}) async {
if (sessionToken == null) return false;
try {
final res = await http.post(
Uri.parse('$baseUrl/api/v1/heartbeat'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'session_token': sessionToken, 'hwid': hwid}),
);
final json = jsonDecode(res.body);
return json['success'] == true;
} catch (_) {
return false;
}
}
/// Terminate session on app close
Future<void> logout() async {
if (sessionToken == null) return;
await http.post(
Uri.parse('$baseUrl/api/v1/logout'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'session_token': sessionToken}),
);
sessionToken = null;
}
}
// ==========================================
// Usage Example in Flutter:
// ==========================================
void main() async {
final auth = LicenseAuthClient(
baseUrl: 'https://keyauth.workss.in',
appId: 'YOUR_APP_ID',
);
// 1. Initialize
final initRes = await auth.init(version: '1.0.0');
if (initRes['success'] != true) {
print('Init failed: ${initRes['error']['message']}');
return;
}
// 2. Authenticate
final authRes = await auth.authenticateLicense(
license: 'VB-XXXX-XXXX-XXXX',
hwid: 'DEVICE-UNIQUE-ID',
deviceName: 'MyPhone',
platform: 'Android',
);
if (authRes['success'] == true) {
print('Access granted! Expires: ${authRes['data']['expires_at']}');
} else {
print('Denied: ${authRes['error']['message']}');
}
}
Python Client SDK
Reusable class using Python requests with automatic session persistence.
import requests
import platform
class LicenseAuth:
def __init__(self, base_url: str, app_id: str):
self.base_url = base_url.rstrip('/')
self.app_id = app_id
self.session_token = None
def init(self, version: str = "1.0.0") -> dict:
url = f"{self.base_url}/api/v1/init"
res = requests.post(url, json={"app_id": self.app_id, "version": version}, timeout=10)
data = res.json()
if data.get("success"):
self.session_token = data["data"]["session_token"]
return data
def authenticate_license(self, license_key: str, hwid: str, device_name: str = None) -> dict:
if not self.session_token:
raise RuntimeError("Must call init() before authenticating.")
url = f"{self.base_url}/api/v1/license"
payload = {
"session_token": self.session_token,
"license": license_key,
"hwid": hwid,
"device_name": device_name or platform.node(),
"platform": platform.system()
}
res = requests.post(url, json=payload, timeout=10)
return res.json()
def heartbeat(self) -> bool:
if not self.session_token:
return False
url = f"{self.base_url}/api/v1/heartbeat"
res = requests.post(url, json={"session_token": self.session_token}, timeout=5)
return res.json().get("success", False)
# Example Usage:
if __name__ == "__main__":
auth = LicenseAuth("https://keyauth.workss.in", "YOUR_APP_ID")
auth.init("1.0.0")
result = auth.authenticate_license("VB-XXXX-XXXX-XXXX", "MY-HWID-STRING")
if result.get("success"):
print("Success! Expiry:", result["data"]["expires_at"])
else:
print("Error:", result["error"]["message"])
C# (.NET) Client SDK
Native asynchronous integration with HttpClient and System.Text.Json.
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
public class LicenseAuthClient
{
private readonly HttpClient _http = new HttpClient();
private readonly string _baseUrl;
private readonly string _appId;
public string SessionToken { get; private set; }
public LicenseAuthClient(string baseUrl, string appId)
{
_baseUrl = baseUrl.TrimEnd('/');
_appId = appId;
}
public async Task<JsonDocument> InitAsync(string version = "1.0.0")
{
var payload = JsonSerializer.Serialize(new { app_id = _appId, version });
var content = new StringContent(payload, Encoding.UTF8, "application/json");
var response = await _http.PostAsync($"{_baseUrl}/api/v1/init", content);
var json = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
if (json.RootElement.GetProperty("success").GetBoolean())
{
SessionToken = json.RootElement.GetProperty("data").GetProperty("session_token").GetString();
}
return json;
}
public async Task<JsonDocument> AuthenticateLicenseAsync(string license, string hwid)
{
var payload = JsonSerializer.Serialize(new {
session_token = SessionToken,
license = license,
hwid = hwid,
device_name = Environment.MachineName,
platform = "Windows"
});
var content = new StringContent(payload, Encoding.UTF8, "application/json");
var response = await _http.PostAsync($"{_baseUrl}/api/v1/license", content);
return JsonDocument.Parse(await response.Content.ReadAsStringAsync());
}
}
C++ Client (libcurl)
Standard C++ implementation using libcurl for high-performance Windows / Linux binaries.
#include <iostream>
#include <string>
#include <curl/curl.h>
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
std::string SendPost(const std::string& url, const std::string& jsonPayload) {
CURL* curl = curl_easy_init();
std::string response;
if (curl) {
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, jsonPayload.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl_slist_free_all(headers);
}
return response;
}