SDKs
TypeScript SDK
Zero-dependency client for the Licentric licensing API using native fetch().
Requirements
Node.js 18+ or any browser environment with
fetch support. No runtime dependencies.Installation
Install
npm install @licentric/sdk
# Or install from source
git clone https://github.com/AbleVarghese/licentric.git
cd licentric/sdks/typescript
npm install && npm run buildClient Initialization
setup.ts
import { Licentric } from "@licentric/sdk";
// Initialize with your API key
const client = new Licentric({ apiKey: "lk_live_your_api_key_here" });
// With custom base URL
const client = new Licentric({
apiKey: "lk_live_your_api_key_here",
baseUrl: "https://your-instance.licentric.com/api/v1",
});Config Properties
| Parameter | Type | Required | Description |
|---|---|---|---|
| apiKey | string | Required | Your Licentric API key (lk_live_... or lk_test_...) |
| baseUrl | string | Optional | API base URL. Defaults to https://licentric.com/api/v1 |
Methods
validate()
Validate a license key. Returns a promise resolving to a ValidationResult.
| Parameter | Type | Required | Description |
|---|---|---|---|
| key | string | Required | The license key to validate |
| fingerprint | string | Optional | Machine fingerprint to check device activation |
| entitlements | string[] | Optional | Entitlement codes the license must satisfy |
validate.ts
const result = await client.validate({
key: "MYAPP-XXXX-XXXX-XXXX-XXXX",
fingerprint: "abc123def456", // optional
entitlements: ["export_pdf", "sso"], // optional
});
if (result.valid) {
console.info(`License valid: ${result.code}`);
console.info(`Entitlements: ${result.entitlements.join(", ")}`);
} else {
console.warn(`License invalid: ${result.code}`);
}activate()
Activate a machine against a license. Returns a Promise<Machine>.
| Parameter | Type | Required | Description |
|---|---|---|---|
| key | string | Required | The license key to activate against |
| fingerprint | string | Required | Unique machine fingerprint (min 8 characters) |
| name | string | Optional | Human-readable machine name |
| platform | string | Optional | "macos" | "windows" | "linux" | "docker" | "kubernetes" |
activate.ts
const machine = await client.activate({
key: "MYAPP-XXXX-XXXX-XXXX-XXXX",
fingerprint: "abc123def456",
name: "Developer Workstation", // optional
platform: "macos", // optional
});
console.info(`Machine activated: ${machine.id}`);
console.info(`Fingerprint: ${machine.fingerprint}`);deactivate()
Deactivate a machine to free up a device slot. Returns Promise<void>.
| Parameter | Type | Required | Description |
|---|---|---|---|
| machineId | string | Required | UUID of the machine to deactivate |
| licenseKey | string | Required | The license key the machine belongs to |
deactivate.ts
// Release the device slot (useful for floating licenses)
await client.deactivate(
"machine-uuid-here",
"MYAPP-XXXX-XXXX-XXXX-XXXX",
);heartbeat()
Send a heartbeat for an active machine. Returns the updated Machine record.
| Parameter | Type | Required | Description |
|---|---|---|---|
| machineId | string | Required | UUID of the machine to heartbeat |
| licenseKey | string | Required | The license key the machine belongs to |
heartbeat.ts
// Send a heartbeat to keep the machine alive
const machine = await client.heartbeat(
"machine-uuid-here",
"MYAPP-XXXX-XXXX-XXXX-XXXX",
);
// Typical heartbeat interval
setInterval(async () => {
await client.heartbeat(machineId, licenseKey);
}, 5 * 60 * 1000); // every 5 minutescheckout()
Check out an Ed25519-signed offline license file. Uses API key authentication.
| Parameter | Type | Required | Description |
|---|---|---|---|
| licenseId | string | Required | UUID of the license to check out |
| input.fingerprint | string | Required | Machine fingerprint to bind the file to |
| input.ttl | number | Optional | TTL in seconds (3600-7776000). Defaults to 1209600 (14 days) |
checkout.ts
// Download an Ed25519-signed offline license file
const licenseFile = await client.checkout(
"license-uuid-here",
{
fingerprint: "abc123def456",
ttl: 1209600, // 14 days (default)
},
);
console.info(`Certificate: ${licenseFile.certificate}`);
console.info(`TTL: ${licenseFile.ttl} seconds`);Licentric.fingerprint()
Static utility to generate a stable machine fingerprint from hardware attributes. Node.js only.
fingerprint.ts
// Generate a stable machine fingerprint (Node.js only)
const fingerprint = Licentric.fingerprint();
// Returns a SHA-256 hash of hostname + platform + CPU model + CPU countTypeScript Interfaces
All response types are fully typed and exported from the package.
types.ts
interface ValidationResult {
valid: boolean;
code: string;
license: License | null;
machine: Machine | null;
entitlements: string[];
metadata: Record<string, unknown>;
}
interface Machine {
id: string;
licenseId: string;
fingerprint: string;
name: string | null;
platform: string | null;
hostname: string | null;
heartbeatStatus: "NOT_STARTED" | "ALIVE" | "DEAD";
lastHeartbeatAt: string | null;
cores: number | null;
metadata: Record<string, unknown>;
createdAt: string;
updatedAt: string;
}
interface License {
id: string;
status: "active" | "suspended" | "expired" | "revoked" | "banned";
productId: string;
policyId: string;
name: string | null;
expiresAt: string | null;
userEmail: string | null;
userName: string | null;
usesCount: number;
metadata: Record<string, unknown>;
createdAt: string;
updatedAt: string;
}
interface LicenseFile {
license: License;
fingerprint: string;
ttl: number;
certificate: string | null;
}Error Handling
All SDK errors extend LicentricError. Use instanceof checks to handle specific error types.
| Error Class | HTTP Status | Properties |
|---|---|---|
| AuthenticationError | 401 | message, statusCode, code |
| ValidationError | 400 | message, statusCode, code, details |
| NotFoundError | 404 | message, statusCode, code |
| RateLimitError | 429 | message, statusCode, code, retryAfter |
| LicentricError | Any | message, statusCode, code, details |
errors.ts
import {
Licentric,
LicentricError,
AuthenticationError,
ValidationError,
NotFoundError,
RateLimitError,
} from "@licentric/sdk";
try {
const result = await client.validate({ key: "MYAPP-XXXX-XXXX-XXXX-XXXX" });
} catch (error) {
if (error instanceof AuthenticationError) {
// HTTP 401 — invalid or missing credentials
} else if (error instanceof ValidationError) {
// HTTP 400 — invalid request parameters
} else if (error instanceof NotFoundError) {
// HTTP 404 — resource does not exist
} else if (error instanceof RateLimitError) {
// HTTP 429 — wait error.retryAfter seconds
} else if (error instanceof LicentricError) {
// Other API error — check error.statusCode, error.code
}
}