Integrate license checking into your tool
Every key is validated live, server-side, HWID-locked to one device, and every response is cryptographically signed. Pick your language below and drop in the client — no build step required.
Your server
Base URL: loading…
Signing public key (embed this in your SDK config — it is not secret):
How it works
- In the admin dashboard, create a product for each tool you sell, then generate license keys for it (optionally with an expiry and a customer email).
- Give the key to your customer. Your tool calls the SDK's
check(key)on startup — it activates the key to the current device the first time, and verifies it on every subsequent run. - Manage keys any time from the dashboard: revoke a leaked key, extend an expiry, or reset a key's bound device so a customer can move to a new machine.
SDKs
Each SDK is dependency-light reference code meant to be copied into your own project and adapted, not a published package.
Python cryptography
license_client.py + example.py
Node.js zero deps
licenseClient.js + example.js
Go zero deps
licenseclient package + example
Rust ed25519-dalek
license_client crate + example
Quick start
Python
pip install cryptography
from license_client import LicenseClient
client = LicenseClient(
base_url="...",
product="your-product-slug",
public_key_b64="...",
)
result = client.check(license_key)
if not result.valid:
print("License invalid:", result.reason)
sys.exit(1)
Node.js
const { LicenseClient } = require('./licenseClient');
const client = new LicenseClient({
baseUrl: '...',
product: 'your-product-slug',
publicKeyB64: '...',
});
const result = await client.check(licenseKey);
if (!result.valid) {
console.error('License invalid:', result.reason);
process.exit(1);
}
Go
client, _ := licenseclient.New(
"...",
"your-product-slug",
"...",
)
result := client.Check(licenseKey)
if !result.Valid {
log.Fatal("License invalid: ", result.Reason)
}
Rust
let client = LicenseClient::new(
"...",
"your-product-slug",
"...",
)?;
let result = client.check(license_key);
if !result.valid {
eprintln!("License invalid: {:?}", result.reason);
std::process::exit(1);
}
What this system protects against — and what it doesn't
Read this before you rely on it
Every activate/verify decision is made server-side, and every response is signed with Ed25519 so it can't be forged even by someone who has extracted your SDK's public key from a compiled binary. Combined with one-key-one-device locking, instant revocation, and a full audit trail, this stops casual piracy and key-sharing effectively.
It cannot stop a determined attacker who has full control of the machine running your tool — they can patch out the license check entirely, run it under a debugger, or intercept and replace the SDK's own code. No client-side license check, from any vendor, can fully prevent that; it's a structural limit of running your logic on hardware you don't control. If that threat model matters to you, pair this with code obfuscation/anti-tamper tooling and treat this system as raising the cost of piracy, not eliminating it.
See the Security Model page for the full HWID and signature spec, and the API Reference for the raw HTTP contract if you're integrating from a language without a ready-made SDK.