ExisOne Node.js SDK
Embed our cross-platform Node.js/TypeScript library to generate hardware IDs, activate and validate licenses, and send support tickets. Perfect for Node.js backends and Electron desktop apps.
Install
npm install exisone-client
Or with yarn/pnpm:
yarn add exisone-client pnpm add exisone-client
Initialize
import { ExisOneClient } from 'exisone-client';
const client = new ExisOneClient({
baseUrl: 'https://your-api-host', // must be https
accessToken: 'exo_at_<public>_<secret>', // create in Access Tokens UI
offlinePublicKey: undefined // optional: set for offline license validation
});
// Optional: change base URL later
client.withBaseUrl('https://another-host');
// Library version
const sdkVersion = client.getVersion();
baseUrl can also be set via environment variable EXISONE_BASEURL.
For offline license validation, set offlinePublicKey to your tenant's RSA public key (PEM format).
Obtain this from the Crypto Keys page.
Capabilities
- Hardware ID:
generateHardwareId()— cross-platform fingerprint (salted SHA-256) - Activate:
activate({...})→ returnsActivationResultwith success/error details - Validate:
validate({...})→ returnsValidationResultwith status, expiration, features - Deactivate:
deactivate({...})(requires the same hardware) - Generate key:
generateActivationKey({...})(requiresgeneratepermission) - Support ticket:
sendSupportTicket({...})(requiresemailpermission) - Offline Validation:
validateOffline(offlineCode, hardwareId)→ validates locally without servervalidateSmart({...})→ auto-detects online/offline, falls back gracefullydeactivateSmart({...})→ opportunistic server sync
Quick Start
import { ExisOneClient } from 'exisone-client';
// Initialize
const client = new ExisOneClient({
baseUrl: 'https://www.exisone.com',
accessToken: 'exo_at_xxx_yyy'
});
// 1) Hardware ID (store locally)
const hwid = client.generateHardwareId();
// 2) Activation with version (user enters key/email)
const result = await client.activate({
activationKey,
email: userEmail,
hardwareId: hwid,
productName: 'MyProduct',
version: '1.0.0'
});
if (!result.success) {
if (result.errorCode === 'version_outdated') {
console.log(`Please upgrade to version ${result.minimumRequiredVersion}`);
} else {
console.log(result.errorMessage);
}
}
// 3) Validate on app start (requires 'verify' permission)
const validation = await client.validate({
activationKey,
hardwareId: hwid,
productName: 'MyProduct',
version: '1.0.0'
});
if (validation.status === 'version_outdated') {
console.log(`Update required: minimum version is ${validation.minimumRequiredVersion}`);
} else if (validation.isValid) {
console.log(`Licensed until: ${validation.expirationDate}`);
console.log(`Features: ${validation.features.join(', ')}`);
}
// 4) Optional: Deactivate from the same hardware
const success = await client.deactivate({
activationKey,
hardwareId: hwid,
productName: 'MyProduct'
});
// 5) (Publisher tooling) Generate a new key for a product
const key = await client.generateActivationKey({
productName: 'MyProduct',
email: 'user@example.com',
planId: 1
});
// 6) Submit support ticket from client
await client.sendSupportTicket({
productName: 'MyProduct',
email: userEmail,
subject: 'Subject',
message: 'Message body'
});
TypeScript Support
Full TypeScript support with all types exported:
import {
ExisOneClient,
ExisOneClientOptions,
ActivationResult,
ValidationResult,
OfflineValidationResult,
SmartValidationResult,
DeactivationResult,
generateHardwareId
} from 'exisone-client';
Offline License Validation
For customers without internet access, generate offline activation codes from the License Keys page by providing their Hardware ID.
Setup
const client = new ExisOneClient({
baseUrl: 'https://your-api-host',
accessToken: 'your-token',
offlinePublicKey: `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...
-----END PUBLIC KEY-----`
});
Smart Validation (Recommended)
Auto-detects online vs offline keys. Falls back to offline if server is unreachable.
const hwid = client.generateHardwareId();
// Works with both online keys (XXXX-XXXX-XXXX-XXXX) and offline codes
const result = await client.validateSmart({
activationKeyOrOfflineCode: licenseKeyOrOfflineCode,
hardwareId: hwid,
productName: 'MyProduct'
});
if (result.isValid) {
console.log(`Licensed until: ${result.expirationDate}`);
console.log(`Offline mode: ${result.wasOffline}`);
console.log(`Features: ${result.features.join(', ')}`);
} else {
console.log(`Invalid: ${result.errorMessage}`);
}
Direct Offline Validation
// Validate completely offline - no server calls
const result = client.validateOffline(offlineCode, hwid);
if (result.isValid) {
console.log(`Product: ${result.productName}`);
console.log(`Expires: ${result.expirationDate}`);
} else if (result.isExpired) {
console.log('License expired');
} else if (result.hardwareMismatch) {
console.log('Wrong machine - license bound to different hardware');
} else {
console.log(`Invalid: ${result.errorMessage}`);
}
CommonJS Usage
const { ExisOneClient } = require('exisone-client');
const client = new ExisOneClient({
baseUrl: 'https://www.exisone.com',
accessToken: 'your-api-token'
});
Electron Apps
The SDK works in both main and renderer processes (with Node.js integration enabled):
// main.js (Electron main process)
const { ExisOneClient } = require('exisone-client');
const client = new ExisOneClient({
baseUrl: 'https://www.exisone.com',
accessToken: process.env.EXISONE_TOKEN
});
// Generate hardware ID once at startup
const hardwareId = client.generateHardwareId();
// Expose to renderer via IPC
ipcMain.handle('validate-license', async (event, activationKey) => {
return client.validate({ activationKey, hardwareId });
});
Error Handling
import { ExisOneClient } from 'exisone-client';
const client = new ExisOneClient(options);
try {
const result = await client.validate({ activationKey, hardwareId });
} catch (err) {
if (err instanceof Error) {
console.log(`Error: ${err.message}`);
}
}
API Reference
// Version
getVersion(): string
// Hardware
generateHardwareId(): string
// Activation
activate(params: {
activationKey: string;
email: string;
hardwareId: string;
productName: string;
version?: string;
}): Promise<ActivationResult>
// Validation (Online)
validate(params: {
activationKey: string;
hardwareId: string;
productName?: string;
version?: string;
}): Promise<ValidationResult>
// Validation (Offline)
validateOffline(offlineCode: string, hardwareId: string): OfflineValidationResult
validateSmart(params: {
activationKeyOrOfflineCode: string;
hardwareId: string;
productName?: string;
}): Promise<SmartValidationResult>
// Deactivation
deactivate(params: {
activationKey: string;
hardwareId: string;
productName: string;
}): Promise<boolean>
deactivateSmart(params: {
activationKeyOrOfflineCode: string;
hardwareId: string;
productName: string;
}): Promise<DeactivationResult>
// Generation (publisher)
generateActivationKey(params: {
productName: string;
email: string;
planId?: number;
validityDays?: number;
}): Promise<string>
// Features
getLicensedFeatures(activationKey: string): Promise<string[]>
// Support
sendSupportTicket(params: {
productName: string;
email: string;
subject: string;
message: string;
}): Promise<void>
// Configuration
withBaseUrl(baseUrl: string): ExisOneClient
Environment Variables
| Variable | Description |
|---|---|
EXISONE_BASEURL | Default base URL if not specified in options |
Requirements
- Node.js 18+ (uses native
fetch) - Windows, Linux, macOS
- Zero external dependencies
Common Errors
- 403 verify permission required: Add
verifyto the token in Access Tokens UI. - Activation key not found in this tenant: Token and key must belong to same tenant.
- 400 Bad Request on activation: Ensure product name is correct.
- version_outdated: Client version is below the minimum required.
Changelog
- 0.7.0: Initial Node.js SDK release with full feature parity to .NET and Python SDKs.