Skip to content

TypeScript / JavaScript SDK

The @lizen/sdk package is the official TypeScript client for the Lizen API. Zero runtime dependencies, dual ESM/CJS output, full type coverage.

Installation

Terminal window
npm install @lizen/sdk

Quickstart

import { Lizen } from '@lizen/sdk';
const lizen = new Lizen({ apiKey: process.env.LIZEN_API_KEY! });
// Validate a license key at app startup
const result = await lizen.validate({
key: storedLicenseKey,
deviceFingerprint: getMachineId(),
});
if (!result.valid) app.quit();

Client options

const lizen = new Lizen({
apiKey: 'lz_...', // required
baseUrl: 'https://api.lizen.dev/v1', // optional override
timeout: 5000, // ms, default 10000
});

Validation

const result = await lizen.validate({
key: 'MYAPP-ABCD-EFGH-IJKL',
deviceFingerprint: 'sha256_of_machine_id',
appVersion: '1.2.0', // optional
});
// result.valid: boolean
// result.plan: string | null
// result.expiresAt: string | null
// result.activationsUsed: number
// result.activationLimit: number
// result.reason: 'not_found' | 'revoked' | 'expired' | 'activation_limit' (when valid: false)

Keys

// Create
const key = await lizen.keys.create({
productId: 'prod_abc',
plan: 'pro',
activationLimit: 3,
expiresAt: '2027-08-16T12:00:00Z', // omit for perpetual
metadata: { orderId: 'ord_xyz' },
});
// List
const { keys, total } = await lizen.keys.list({
productId: 'prod_abc',
status: 'active',
page: 0,
pageSize: 20,
});
// Get
const key = await lizen.keys.get('lic_def456');
// Revoke
await lizen.keys.revoke('lic_def456', { reason: 'chargeback' });
// Extend
await lizen.keys.extend('lic_def456', { expiresAt: '2028-08-16T12:00:00Z' });

Products

const product = await lizen.products.create({ name: 'My App', slug: 'my-app' });
const products = await lizen.products.list();
await lizen.products.update('prod_abc', { name: 'My App v2' });
await lizen.products.delete('prod_abc');

Analytics

const overview = await lizen.analytics.overview();
const trend = await lizen.analytics.activations({ range: '30d', productId: 'prod_abc' });
const geo = await lizen.analytics.geography();

Offline licenses

// Generate an offline license file
const license = await lizen.offline.generate({
key: 'MYAPP-ABCD-EFGH-IJKL',
deviceFingerprint: 'sha256_of_machine_id',
deviceName: "Alex's MacBook Pro",
});
// license.licenseFile — RS256-signed JWT string to store locally
// license.publicKey — SPKI PEM public key to embed in your app
// license.expiresAt — when the file expires (max 90 days)

Error classes

All errors extend LizenError:

import {
LizenError,
AuthenticationError, // 401
PermissionError, // 403
NotFoundError, // 404
ValidationError, // 400
PlanLimitError, // 422
RateLimitError, // 429 — has .retryAfter (seconds)
} from '@lizen/sdk';
try {
await lizen.keys.create({ productId: 'prod_abc', plan: 'pro' });
} catch (err) {
if (err instanceof PlanLimitError) {
showUpgradeBanner(err.message);
} else if (err instanceof RateLimitError) {
await sleep(err.retryAfter * 1000);
}
}

Retry behavior

The SDK automatically retries 500 errors and network failures with exponential backoff:

AttemptDelay
1st retry200ms
2nd retry400ms
3rd retry800ms (capped at 5s)

4xx errors (except 429) are never retried — they represent a problem with the request, not the server.