Complete guide for integrating JanusAI License Server into your applications
Log into the admin panel and navigate to Products. Create a new product with:
JANUS-CHAT
(unique identifier)Navigate to Licenses and create a new license:
// Basic validation request
const response = await fetch('https://your-domain.com/api/v1/validate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
licenseKey: 'your-license-key',
productCode: 'JANUS-CHAT',
machineId: getMachineId(),
requireActivation: true
})
});
const result = await response.json();
if (result.status === 'valid') {
// License is valid, enable features
enableFeatures(result.features);
}
// Example: Generate unique machine ID
function getMachineId() {
// Combine multiple hardware identifiers
const cpuId = os.cpus()[0].model;
const hostname = os.hostname();
const networkInterfaces = os.networkInterfaces();
const macAddress = Object.values(networkInterfaces)
.flat()
.find(i => !i.internal && i.mac !== '00:00:00:00:00:00')?.mac;
// Create a hash of the combined values
return crypto.createHash('sha256')
.update(cpuId + hostname + macAddress)
.digest('hex');
}
class LicenseManager {
constructor(apiUrl, productCode) {
this.apiUrl = apiUrl;
this.productCode = productCode;
this.machineId = getMachineId();
}
async validateLicense(licenseKey) {
try {
const response = await fetch(`${this.apiUrl}/api/v1/validate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
licenseKey,
productCode: this.productCode,
machineId: this.machineId,
requireActivation: true
})
});
const result = await response.json();
if (result.status === 'valid') {
// Store validation result locally
this.storeValidation(result);
return { success: true, features: result.features };
} else {
return { success: false, error: result.message };
}
} catch (error) {
// Fallback to offline validation if stored
return this.offlineValidation(licenseKey);
}
}
storeValidation(result) {
// Encrypt and store for offline use
const encrypted = encrypt(JSON.stringify({
...result,
validatedAt: new Date().toISOString(),
machineId: this.machineId
}));
localStorage.setItem('license_cache', encrypted);
}
offlineValidation(licenseKey) {
// Check cached validation
const cached = localStorage.getItem('license_cache');
if (!cached) return { success: false, error: 'No cached license' };
const decrypted = JSON.parse(decrypt(cached));
const hoursSinceValidation =
(new Date() - new Date(decrypted.validatedAt)) / 1000 / 60 / 60;
// Allow 72 hours offline grace period
if (hoursSinceValidation < 72 && decrypted.licenseKey === licenseKey) {
return { success: true, features: decrypted.features };
}
return { success: false, error: 'Offline validation expired' };
}
}
Set up periodic validation checks:
// Validate on startup
await licenseManager.validateLicense(userLicenseKey);
// Revalidate every 24 hours
setInterval(async () => {
const result = await licenseManager.validateLicense(userLicenseKey);
if (!result.success) {
// Handle license expiration or invalidation
showLicenseError(result.error);
}
}, 24 * 60 * 60 * 1000);
{
"status": "valid",
"message": "License is valid",
"expiresAt": "2024-12-31T23:59:59Z",
"features": ["basic", "advanced"],
"customer": {
"name": "Acme Corp",
"email": "[email protected]"
},
"activations": {
"used": 2,
"limit": 5
}
}
// Expired license
{
"status": "expired",
"message": "License expired on 2024-01-01",
"expiresAt": "2024-01-01T00:00:00Z"
}
// Machine limit exceeded
{
"status": "machine_limit_exceeded",
"message": "Maximum activations reached",
"activations": {
"used": 5,
"limit": 5
}
}
Status | HTTP Code | Description |
---|---|---|
valid | 200 | License is valid and active |
expired | 403 | License has expired |
blocked | 403 | License is suspended or blocked |
invalid_product | 404 | Product code not found |
rate_limited | 429 | Too many requests |
Never expose license keys in client-side code
Always validate licenses server-side for web applications
Implement offline grace periods
Allow 24-72 hours of offline usage for desktop applications
Cache validation results
Reduce API calls by caching results for 5-15 minutes
Use HTTPS for all API calls
Ensure all license validation traffic is encrypted
Handle rate limits gracefully
Implement exponential backoff for retries
Full-featured SDK for Node.js applications
Python library with async support
.NET SDK for desktop and server apps
cURL and Postman collection