Shax Documentation & SDKs
Shax is an enterprise-grade software licensing platform engineered for desktop software, developer tools, and internal utilities. It binds cryptographic license keys to machine hardware IDs (HWID) to eliminate unauthorized distribution and software piracy.
Security & Architecture
The platform strictly operates under the core tenet: "Client is Untrusted, Server is Authority".
Cryptographic Key Storage
License keys are hashed with SHA-256 upon generation. Plaintext keys are never stored in the database, preventing leaks even in the event of database dumps.
HWID Machine Fingerprinting
Hardware IDs are generated on the client by hashing motherboard serials, CPU identifiers, and MAC addresses. The server locks the license to a maximum allowable number of device hashes.
Encrypted Application Secrets
Application secrets are encrypted with AES-256-GCM using a server-side 256-bit encryption key.
IP & Geolocation Telemetry
Every activation and validation request logs client IP address, User-Agent, and geolocation metadata for fraud detection and auditing.
REST API Endpoints
Activates a new or unused license key and binds it to the requesting machine's HWID.
{
"license_key": "SHAX_SAMPLE_KEY_XXXX_YYYY",
"application_id": "app_xxxxxxxxxxxxxxxx",
"api_key": "sk_live_xxxxxxxxxxxxxxxx",
"hwid": "client_hardware_uuid_or_hash",
"device_info": {
"os": "Windows 11 Pro",
"architecture": "x86_64",
"hostname": "DEV-WORKSTATION"
}
}{
"success": true,
"message": "License activated successfully.",
"license": {
"status": "ACTIVE",
"expires_at": "2026-10-11T00:00:00.000Z",
"max_devices": 1,
"current_devices": 1
}
}Validates an existing license key against the machine's HWID. Fails if the license has expired, is revoked, or is accessed from an unbound machine.
{
"license_key": "SHAX_SAMPLE_KEY_XXXX_YYYY",
"application_id": "app_xxxxxxxxxxxxxxxx",
"api_key": "sk_live_xxxxxxxxxxxxxxxx",
"hwid": "client_hardware_uuid_or_hash"
}{
"success": true,
"license": {
"valid": true,
"status": "ACTIVE",
"expires_at": "2026-10-11T00:00:00.000Z"
}
}Official SDK Libraries
Node.js, Next.js & Nuxt.js (shax-license)
npm i shax-licenseOfficial TypeScript library with automatic hardware fingerprinting, offline caching, and Next.js / Nuxt 3 route guards. Defaults to https://license.webda.in.
import { ShaxClient } from "shax-license";
// For Next.js: import { createNextLicenseGuard } from "shax-license/next";
// For Nuxt.js: import { createNuxtLicenseGuard } from "shax-license/nuxt";
const client = new ShaxClient({
applicationId: "app_clxxxxxxxxxxxx",
apiKey: "sk_live_xxxxxxxxxxxx",
// baseUrl defaults to https://license.webda.in
});
// 1. Activate on first launch (starts 7-day or custom validity countdown)
const activation = await client.activate("SHAX-YOUR-LICENSE-KEY");
console.log("Activated! Status:", activation.license.status);
// 2. Validate on subsequent runs (fast in-memory cache)
const validation = await client.validate("SHAX-YOUR-LICENSE-KEY");
if (validation.valid) {
console.log("License is valid! Expires at:", validation.expiresAt);
}Python Integration (shax.py)
Lightweight client using standard library urllib and hashlib with automatic HWID generation on Windows, Linux, and macOS.
from sdk.python.shax import ShaxClient, ShaxError
client = ShaxClient(
app_id="app_your_application_id",
api_key="sk_live_your_api_key",
base_url="http://localhost:3000"
)
try:
# Activate or validate license
result = client.activate("SHAX-YOUR-KEY")
print("License valid! Expires:", result.get("expires_at"))
except ShaxError as e:
print(f"Validation failed: [{e.code}] {e.message}")C++ Header (shax.hpp)
Single-header drop-in client for game engines, desktop software, and system tools.
#include "sdk/cpp/shax.hpp"
shax::Client client("app_your_id", "sk_live_your_key", "http://localhost:3000");
try {
if (client.validate("SHAX-YOUR-KEY")) {
std::cout << "License active and bound to HWID!" << std::endl;
}
} catch (const shax::ShaxError& err) {
std::cerr << "License error: " << err.what() << std::endl;
}C# / .NET (Shax.cs)
Native async C# class utilizing HttpClient and System.Text.Json.
using Shax;
var client = new ShaxClient("app_your_id", "sk_live_your_key", "http://localhost:3000");
var response = await client.ValidateAsync("SHAX-YOUR-KEY");
if (response.Success) {
Console.WriteLine("License authorized for this workstation.");
}Auto-Login & Persistent License Session (One-Time Key Activation)
Eliminate friction for your customers by implementing a "Remember My License" flow. Customers enter their 24-character license key only once on first installation. The software caches the key locally and validates it silently against the server and local HWID on subsequent launches.
First Launch (Activation)
If no local key file is found, prompt user for their license key. Call /api/v1/license/activate with the machine's HWID. On success, save the key to %APPDATA%/YourApp/license.key.
Subsequent Launches (Silent Auto-Login)
Read the cached key from the local file. In the background, send /api/v1/license/validate with local HWID. If valid, immediately open the main application window without prompting!
Hardware & Expiry Security
If the server returns invalid (expired, revoked, or key file copied to another PC with a different HWID), delete the local key file and show the activation dialog again.
Python Auto-Login Implementation
import os
import json
from sdk.python.shax import ShaxClient, ShaxError
CONFIG_PATH = os.path.expanduser("~/.config/myapp/license.json")
client = ShaxClient(app_id="app_your_id", api_key="sk_live_your_key", base_url="http://localhost:3000")
def load_saved_key():
if os.path.exists(CONFIG_PATH):
try:
with open(CONFIG_PATH, "r") as f:
return json.load(f).get("license_key")
except:
return None
return None
def save_key(key):
os.makedirs(os.path.dirname(CONFIG_PATH), exist_ok=True)
with open(CONFIG_PATH, "w") as f:
json.dump({"license_key": key}, f)
def start_application():
saved_key = load_saved_key()
if saved_key:
print("[Auto-Login] Found saved license. Validating silently...")
try:
res = client.validate(saved_key)
if res.get("valid"):
print("[Auto-Login] SUCCESS! Launching application...")
return True
except ShaxError as e:
print(f"[Auto-Login] Validation failed ({e.message}). Re-prompting user...")
if os.path.exists(CONFIG_PATH):
os.remove(CONFIG_PATH)
# First-time launch or expired: Prompt customer
key = input("Enter your Shax License Key: ").strip()
try:
res = client.activate(key)
save_key(key)
print("[Activation] Activated and saved for auto-login!")
return True
except ShaxError as e:
print(f"Activation failed: [{e.code}] {e.message}")
return False
if __name__ == "__main__":
if start_application():
print("Welcome to MyApp!")C++ Auto-Login Implementation
#include <iostream>
#include <fstream>
#include "sdk/cpp/shax.hpp"
const std::string LICENSE_FILE = "license.key";
shax::Client client("app_your_id", "sk_live_your_key", "http://localhost:3000");
bool auto_login_or_prompt() {
std::ifstream infile(LICENSE_FILE);
std::string saved_key;
// Check if key is already saved from previous login
if (infile >> saved_key && !saved_key.empty()) {
std::cout << "[Auto-Login] Validating saved key against hardware..." << std::endl;
try {
if (client.validate(saved_key)) {
std::cout << "[Auto-Login] Authorized! Launching software..." << std::endl;
return true;
}
} catch (...) {
std::cout << "[Auto-Login] Key expired or hardware changed. Removing..." << std::endl;
std::remove(LICENSE_FILE.c_str());
}
}
// First time user: Prompt for key
std::cout << "Please enter your license key: ";
std::string user_key;
std::cin >> user_key;
try {
if (client.activate(user_key)) {
std::ofstream outfile(LICENSE_FILE);
outfile << user_key;
std::cout << "Activated successfully! Saved for next launch." << std::endl;
return true;
}
} catch (const shax::ShaxError& err) {
std::cerr << "Activation failed: " << err.what() << std::endl;
}
return false;
}C# / .NET Auto-Login Implementation
using System;
using System.IO;
using System.Threading.Tasks;
using Shax;
class Program {
static readonly string KeyPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"MySoftware",
"license.key"
);
static async Task<bool> InitializeSoftwareAsync() {
var client = new ShaxClient("app_your_id", "sk_live_your_key", "http://localhost:3000");
// 1. Check for saved key (Auto-Login)
if (File.Exists(KeyPath)) {
string savedKey = (await File.ReadAllTextAsync(KeyPath)).Trim();
var valResult = await client.ValidateAsync(savedKey);
if (valResult.Success) {
Console.WriteLine("[Auto-Login] Session verified! Launching...");
return true;
}
File.Delete(KeyPath); // Invalidate bad key
}
// 2. Prompt user once
Console.Write("Enter License Key: ");
string inputKey = Console.ReadLine()?.Trim() ?? "";
var actResult = await client.ActivateAsync(inputKey);
if (actResult.Success) {
Directory.CreateDirectory(Path.GetDirectoryName(KeyPath)!);
await File.WriteAllTextAsync(KeyPath, inputKey);
Console.WriteLine("[Activation] License activated and saved!");
return true;
}
Console.WriteLine($"Error: {actResult.ErrorMessage}");
return false;
}
}AI & MCP Protocol
Shax includes native integration with the Model Context Protocol. You can instruct your AI assistant to manage your licensing infrastructure directly.
Interactive MCP Setup
View configuration snippets for Claude Desktop and Cursor in the dashboard.