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
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) don't require authentication.
/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.
Complete list of available API endpoints.
/api/auth/loginLogin and get JWT token
/api/auth/registerRegister a new admin (first-use 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
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 |