KeyVault is a high-security license management system with hardware ID locking, encrypted validation, and full audit logging. It provides a RESTful API for managing and validating license keys.
Project Isolation
Separate keys by project with unique API secrets
HWID Locking
Bind keys to PC hardware IDs
AES-256-GCM
End-to-end encryption for all payloads
Anti-Replay
Server-side nonce rotation per validation
Rate Limiting
Per-IP and per-key request throttling
Audit Logs
Every action is logged with IP and HWID
Telegram Bot
Native API for Telegram bot integration
User Portal
Per-project user dashboards with customizable blocks
Portal Editor
Drag-and-drop dashboard builder for each project
No-Key Flow
Users can register without a key, add one later
HWID Gating
Restrict features until HWID is bound in loader
Admin Panel
Full admin view of all users, projects, and keys
Admin endpoints require a Bearer token obtained via the login endpoint. Public endpoints (validate, telegram, portal) don't require admin authentication. Self-registration is disabled — only the first user (setup) and admin-created users are allowed.
/api/auth/loginAuthenticate and receive a JWT token stored as an HTTP-only cookie.
{
"email": "admin@keyvault.io",
"password": "your-password"
}{
"success": true,
"data": {
"user": { "id": "...", "email": "admin@keyvault.io", "role": "ADMIN" },
"token": "eyJhbGciOiJIUzI1NiIs..."
}
}💡 For programmatic access, use the Authorization: Bearer <token> header.
Projects let you organize license keys into separate namespaces. Each project gets a unique API secret (kv_...) that clients use during validation to scope keys to a specific project.
kv_ secret is generated automaticallysecret field in validate/heartbeat/telegram requests💡 The secret field is optional. If omitted, validation searches across all keys regardless of project.
Each project gets a public-facing user portal at /p/[slug]. End-users can register, activate license keys, download the loader, and view their account status — all configurable via the Portal Dashboard Editor.
/p/your-project-slugIn project settings, use the Portal Dashboard Editor to customize which blocks appear on the user portal. Available blocks:
key_infoLicense status, plan, expiry, sessions
copy_keyButton to copy the license key mask
download_loaderLoader download with HWID gating
hwid_statusHWID binding status indicator
custom_buttonExternal link (Discord, website, etc.)
custom_textCustom paragraph of text
/api/portal/registerRegister a portal user (no key required)
{
"username": "player123",
"password": "securepass",
"projectId": "clxxx..."
}{
"success": true,
"data": {
"token": "eyJ...",
"user": { "id": "...", "username": "player123", "projectId": "...", "keyId": null }
}
}/api/portal/loginLogin as a portal user
{
"username": "player123",
"password": "securepass",
"projectId": "clxxx..."
}/api/portal/meGet portal user info, key data, access level, and project dashboard config. Requires portal_token cookie or Bearer token.
{
"success": true,
"data": {
"user": { "id": "...", "username": "player123" },
"key": { "mask": "A1B2-****-****-G7H8", "plan": "MONTHLY", "status": "ACTIVE", "hwidLocked": true },
"access": {
"hasKey": true,
"keyActive": true,
"hwidBound": true,
"fullAccess": true,
"canDownloadLoader": true,
"loaderUrl": "https://..."
}
}
}/api/portal/activateActivate a license key on portal user account. Requires portal auth.
{
"key": "A1B2-C3D4-E5F6-G7H8"
}{
"success": true,
"data": {
"message": "Key activated successfully!",
"key": { "mask": "A1B2-****-****-G7H8", "plan": "WEEKLY", "status": "ACTIVE" },
"needsHwidBinding": true
}
}/api/portal/info?slug=my-projectGet public project info for portal page (no auth required)
/api/portal/logoutClear portal auth cookie
Complete list of available API endpoints.
/api/auth/loginLogin and get JWT token
/api/auth/registerRegister a new admin (first-use setup or admin-only)
/api/auth/logoutClear auth cookie
/api/auth/meGet current user info
/api/keys?projectId=xxxList all license keys (paginated, optional project filter)
/api/keysGenerate new license keys
{
"plan": "WEEKLY", // DAILY | WEEKLY | MONTHLY | LIFETIME | CUSTOM
"count": 5, // 1-50 keys at once
"maxSessions": 1, // Max concurrent sessions
"customDays": 90, // Required if plan is CUSTOM (1-3650)
"note": "VIP client", // Optional admin note
"projectId": "clxxx..." // Optional project ID
}/api/keys/:idGet key details with recent logs
/api/keys/:idUpdate key status, reset HWID, change sessions
{
"status": "BANNED", // ACTIVE | EXPIRED | BANNED | REVOKED
"resetHwid": true, // Reset hardware ID lock
"maxSessions": 3 // Update max sessions
}/api/keys/:idRevoke a license key
/api/logsView audit logs (paginated)
/api/statsDashboard statistics
/api/projectsList user's projects
/api/projectsCreate a new project (auto-generates API secret)
{
"name": "My Game",
"description": "Game license management"
}/api/projects/:idGet project details with key count
/api/projects/:idUpdate project or regenerate secret
{
"name": "New Name",
"description": "Updated description",
"regenerateSecret": true // optional: generates new kv_ secret
}/api/projects/:idDelete project and all its keys
/api/heartbeatHealth check endpoint
/api/adminAdmin only: list all users, projects, and keys
/api/portal/info?slug=xxxPublic project info for portal page
/api/portal/registerRegister a portal user (no key required)
/api/portal/loginLogin as a portal user
/api/portal/meGet portal user info, key status, and access level
/api/portal/activateActivate a license key on portal user account
/api/portal/logoutClear portal auth cookie
The core endpoint for validating license keys from your application. No auth required — just send the key and hardware ID.
/api/validateValidate a license key and receive server-side variables. HWID is locked on first use.
{
"key": "A1B2-C3D4-E5F6-G7H8",
"hwid": "sha256-hash-of-hardware-id",
"secret": "kv_abc123..." // Project secret (optional, scopes to project)
}{
"success": true,
"data": {
"valid": true,
"plan": "WEEKLY",
"expiresAt": "2026-03-07T12:00:00.000Z",
"note": "VIP client",
"serverVar": "encrypted-server-variable",
"nonce": "one-time-nonce-rotated-per-call",
"sessionId": "uuid-v4"
}
}Generate a hardware fingerprint by combining stable system identifiers. Recommended: SHA256(MotherboardUUID + ":" + DiskSerial). For Telegram bots, use the user's Telegram ID via the /api/telegram endpoint instead.
A dedicated API endpoint for Telegram bots. The PC HWID is passed from the client — the bot simply forwards the key + HWID to the API and returns the result.
/api/telegramTelegram bot actions: validate, info, reset_hwid
{
"action": "validate", // validate | info | reset_hwid
"key": "A1B2-C3D4-E5F6-G7H8",
"hwid": "ABC123-PC-HARDWARE-ID", // Real PC HWID from client
"secret": "kv_abc123...", // Project secret (scopes to project)
"telegram_id": "123456789", // Optional, for audit logs
"telegram_username": "johndoe" // Optional, for audit logs
}{
"success": true,
"data": {
"valid": true,
"plan": "MONTHLY",
"customDays": null,
"expires_at": "2026-03-30T12:00:00.000Z",
"nonce": "rotated-nonce",
"note": null
}
}validateCheck key + PC HWID. Binds HWID on first use, returns nonce.
infoGet full key info (read-only). HWID optional for match check.
reset_hwidRemove HWID binding so the key can be activated on a new machine.
Copy-paste ready examples for integrating KeyVault into your application.
import requests
import hashlib
import subprocess
API_URL = "https://your-domain.vercel.app/api/validate"
def get_hwid():
"""Get a hardware fingerprint (motherboard UUID + disk serial)."""
try:
uuid = subprocess.check_output(
"wmic csproduct get uuid", shell=True
).decode().split("\n")[1].strip()
disk = subprocess.check_output(
"wmic diskdrive get serialnumber", shell=True
).decode().split("\n")[1].strip()
raw = f"{uuid}:{disk}"
return hashlib.sha256(raw.encode()).hexdigest()
except Exception:
return hashlib.sha256(b"fallback-hwid").hexdigest()
PROJECT_SECRET = "kv_your_project_secret" # from dashboard
def validate_license(key: str) -> dict:
"""Validate a license key against the KeyVault API."""
response = requests.post(API_URL, json={
"key": key,
"hwid": get_hwid(),
"secret": PROJECT_SECRET, # scopes to your project
}, timeout=10)
data = response.json()
if data.get("success"):
print(f"✅ License valid! Plan: {data['data']['plan']}")
print(f" Expires: {data['data']['expiresAt'] or 'Never'}")
print(f" Note: {data['data'].get('note', 'N/A')}")
print(f" Server Nonce: {data['data']['nonce']}")
return data["data"]
else:
print(f"❌ Validation failed: {data.get('error')}")
return None
# Usage
result = validate_license("XXXX-XXXX-XXXX-XXXX")
if result:
# Continue application execution with server variable
server_var = result.get("serverVar")
note = result.get("note")KeyVault supports flexible licensing with 5 built-in plan types.
| Plan | Duration | Description |
|---|---|---|
DAILY | 24 hours | Short-term trial or daily access |
WEEKLY | 7 days | Weekly subscription period |
MONTHLY | 30 days | Standard monthly license |
LIFETIME | ∞ Never expires | Permanent access, one-time purchase |
CUSTOM | 1–3650 days | Set any duration via customDays field |
All API responses follow a consistent format. Errors include an HTTP status code and a message.
// Error response format
{
"success": false,
"error": "Human-readable error message"
}| Code | Meaning | Common Causes |
|---|---|---|
400 | Bad Request | Missing fields, invalid plan, bad payload |
401 | Unauthorized | Invalid or missing auth token, invalid key |
403 | Forbidden | Key expired, HWID mismatch, max sessions, banned |
404 | Not Found | Key doesn't exist |
415 | Unsupported Media | Wrong Content-Type header |
429 | Rate Limited | Too many requests from IP or key |
500 | Server Error | Internal error, contact admin |