Node.js SDK

Official Node.js/TypeScript SDK for LOX Backup API. Full TypeScript support with ESM and CommonJS builds.

v0.1.0Updated 2026-01-01
Installation
npm install @lox-backup/sdk

Requirements

  • Node.js 18 or higher
  • TypeScript 4.7+ (optional, for type definitions)

Quick Start

ESM (Recommended)

import { LoxClient } from '@lox-backup/sdk';

const client = new LoxClient({ apiKey: 'your-api-key' });

// Upload a backup
const backup = await client.backups.upload({
  filePath: 'backup.tar.gz',
  name: 'my-backup',
  tags: ['production', 'database'],
  retentionDays: 30
});

console.log(`Backup created: ${backup.uuid}`);
console.log(`Status: ${backup.status}`);

CommonJS

const { LoxClient } = require('@lox-backup/sdk');

const client = new LoxClient({ apiKey: 'your-api-key' });

async function main() {
  const backup = await client.backups.upload({
    filePath: 'backup.tar.gz',
    name: 'my-backup'
  });

  console.log(`Backup created: ${backup.uuid}`);
}

main();

Configuration

Client Options

import { LoxClient } from '@lox-backup/sdk';

const client = new LoxClient({
  apiKey: 'your-api-key',        // Required: Your LOX API key
  baseUrl: 'https://backlox.com/api', // Optional: API base URL
  timeout: 300000,               // Optional: Request timeout in ms (default: 5min)
  maxRetries: 3,                 // Optional: Max retry attempts (default: 3)
});

Environment Variables

# .env
LOX_API_KEY=your-api-key
LOX_API_URL=https://backlox.com/api
import { LoxClient } from '@lox-backup/sdk';

// Reads from process.env.LOX_API_KEY
const client = new LoxClient();

Backups API

Upload Backup

// Simple upload
const backup = await client.backups.upload({
  filePath: 'backup.tar.gz'
});

// Upload with all options
const backup = await client.backups.upload({
  filePath: 'backup.tar.gz',
  name: 'production-db-2024-01-15',
  description: 'Daily production database backup',
  tags: ['production', 'database', 'mysql'],
  retentionDays: 90,
  waitForCompletion: true,  // Wait for processing
  timeout: 3600000          // Max wait time in ms
});

console.log(`UUID: ${backup.uuid}`);
console.log(`Status: ${backup.status}`);
console.log(`Size: ${backup.sizeBytes} bytes`);

List Backups

// List all backups
const backups = await client.backups.list();

for (const backup of backups) {
  console.log(`${backup.name}: ${backup.status}`);
}

// Filter by status
const completed = await client.backups.list({
  status: 'completed'
});

// Filter by tags
const production = await client.backups.list({
  tags: 'production'
});

// Search by name
const results = await client.backups.list({
  search: 'database'
});

// Pagination
const page1 = await client.backups.list({ limit: 10, offset: 0 });
const page2 = await client.backups.list({ limit: 10, offset: 10 });

Get Backup

const backup = await client.backups.get('550e8400-e29b-41d4-a716-446655440000');

console.log(`Name: ${backup.name}`);
console.log(`Status: ${backup.status}`);
console.log(`Size: ${backup.sizeBytes}`);
console.log(`Created: ${backup.createdAt}`);
console.log(`Tags: ${backup.tags.join(', ')}`);

Restore/Download Backup

// Request restore (generates download URL)
const restore = await client.backups.restore(
  '550e8400-e29b-41d4-a716-446655440000'
);

console.log(`Download URL: ${restore.downloadUrl}`);
console.log(`Expires: ${restore.expiresAt}`);

// Download using the URL
import { createWriteStream } from 'fs';
import { pipeline } from 'stream/promises';

const response = await fetch(restore.downloadUrl);
await pipeline(
  response.body,
  createWriteStream('restored-backup.tar.gz')
);

Delete Backup

await client.backups.delete('550e8400-e29b-41d4-a716-446655440000');
console.log('Backup deleted');

Wait for Completion

// Upload without waiting
const backup = await client.backups.upload({
  filePath: 'backup.tar.gz',
  waitForCompletion: false
});

console.log(`Upload started: ${backup.uuid}`);

// Wait for completion later
const completed = await client.backups.waitForCompletion(backup.uuid, {
  timeout: 3600000,    // Max wait time in ms
  pollInterval: 5000   // Check every 5 seconds
});

console.log(`Backup completed: ${completed.status}`);

Tenant API

Get Current Tenant

const tenant = await client.tenant.getCurrent();

console.log(`Name: ${tenant.name}`);
console.log(`Email: ${tenant.email}`);
console.log(`Created: ${tenant.createdAt}`);

Get Storage Quota

const quota = await client.tenant.getQuota();

console.log(`Used: ${quota.usedBytes} bytes`);
console.log(`Quota: ${quota.quotaBytes} bytes`);
console.log(`Usage: ${quota.usagePercentage}%`);
console.log(`Unlimited: ${quota.unlimited}`);

// Check if storage is available
const hasSpace = await client.tenant.hasAvailableStorage(100 * 1024 * 1024);
if (hasSpace) {
  console.log('100MB available');
} else {
  console.log('Not enough storage');
}

Storage API

// List storage targets
const targets = await client.storage.list();

for (const target of targets) {
  console.log(`${target.name}: ${target.provider} - ${target.status}`);
}

// Get health summary
const health = await client.storage.getHealthSummary();

console.log(`Healthy: ${health.healthyCount}`);
console.log(`Degraded: ${health.degradedCount}`);
console.log(`Offline: ${health.offlineCount}`);

Notification Channels API

Manage notification channels for backup alerts via webhook, Slack, Discord, and more.

Create Channel

import { LoxClient, ChannelType, NotificationEvent } from '@lox-backup/sdk';

const client = new LoxClient();

// Create a webhook channel
const webhook = await client.notificationChannels.create({
  name: 'Production Alerts',
  channelType: ChannelType.WEBHOOK,
  config: { url: 'https://example.com/webhook' },
  events: [NotificationEvent.BACKUP_COMPLETED, NotificationEvent.BACKUP_FAILED],
});

console.log(`Webhook secret: ${webhook.config.secret}`);

// Create a Slack channel
const slack = await client.notificationChannels.create({
  name: 'Slack Alerts',
  channelType: ChannelType.SLACK,
  config: {
    webhookUrl: 'https://hooks.slack.com/services/...',
    channel: '#backup-alerts',
  },
});

// Create a Discord channel
const discord = await client.notificationChannels.create({
  name: 'Discord Alerts',
  channelType: ChannelType.DISCORD,
  config: {
    webhookUrl: 'https://discord.com/api/webhooks/...',
    username: 'LOX Backup Bot',
  },
});

List and Manage Channels

// List all channels
const channels = await client.notificationChannels.list();

for (const channel of channels) {
  console.log(`${channel.name} (${channel.channelType}): ${channel.isHealthy ? 'healthy' : 'unhealthy'}`);
}

// Get channel summary
const summary = await client.notificationChannels.getSummary();
console.log(`Total: ${summary.totalChannels}, Unhealthy: ${summary.unhealthyChannels}`);

// Test a channel
const result = await client.notificationChannels.test(channel.uuid);
if (result.status === 'success') {
  console.log('Channel is working!');
}

// Enable/disable channel
await client.notificationChannels.disable(channel.uuid);
await client.notificationChannels.enable(channel.uuid);

// Update channel
const updated = await client.notificationChannels.update(channel.uuid, {
  name: 'New Name',
  regenerateSecret: true,  // For webhook channels
});

// Delete channel
await client.notificationChannels.delete(channel.uuid);

Backup Agents API

Manage backup agents for Veeam-style machine backup with agent registration and monitoring.

Register Agent

import { LoxClient, OSType } from '@lox-backup/sdk';

const client = new LoxClient();

// Register a new agent
const registration = await client.agents.register({
  hostname: 'server-01',
  osType: OSType.LINUX,
  displayName: 'Production Server 01',
  capabilities: ['file', 'block'],
  hardwareInfo: {
    cpuCores: 8,
    memoryGb: 32,
    disks: [{ path: '/', sizeGb: 500 }],
  },
});

console.log(`Agent UUID: ${registration.uuid}`);
console.log(`Registration Token: ${registration.registrationToken}`);

// Get install command
const cmd = await client.agents.getInstallCommand(registration.uuid);
console.log(cmd.recommendedCommand);

List and Manage Agents

// List all agents
const agents = await client.agents.list();

for (const agent of agents) {
  console.log(`${agent.hostname} (${agent.osType}): ${agent.status}`);
}

// Get agent summary
const summary = await client.agents.getSummary();
console.log(`Online: ${summary.onlineAgents}, Offline: ${summary.offlineAgents}`);
console.log(`Total data protected: ${summary.totalDataProtectedBytes} bytes`);

// Get specific agent
const agent = await client.agents.get('agent-uuid');
console.log(`Success rate: ${agent.successRate}%`);
console.log(`Total backups: ${agent.totalBackups}`);

// Update agent
const updated = await client.agents.update('agent-uuid', {
  displayName: 'New Display Name',
});

// Enable/disable agent
await client.agents.disable('agent-uuid');
await client.agents.enable('agent-uuid');

// Regenerate token
const newReg = await client.agents.regenerateToken('agent-uuid');
console.log(`New token: ${newReg.registrationToken}`);

// Delete agent
await client.agents.delete('agent-uuid');

Backup Jobs API

Create and manage scheduled backup jobs for automated machine backups.

Create Job

import { LoxClient, JobType, BackupMode } from '@lox-backup/sdk';

const client = new LoxClient();

// Create a file backup job
const job = await client.jobs.create({
  agentUuid: 'agent-uuid',
  name: 'Daily Full Backup',
  jobType: JobType.FILE,
  sources: [
    { type: 'path', value: '/home' },
    { type: 'path', value: '/var/www' },
  ],
  exclusions: ['*.log', '*.tmp', 'node_modules'],
  backupMode: BackupMode.FULL,
  scheduleCron: '0 2 * * *',  // Daily at 2 AM
  scheduleEnabled: true,
  retentionPolicy: {
    daily: 7,
    weekly: 4,
    monthly: 12,
  },
  compression: 'zstd',
  compressionLevel: 6,
  encryptionEnabled: true,
  verifyAfterBackup: true,
});

console.log(`Job created: ${job.uuid}`);

Run and Manage Jobs

// List all jobs
const jobs = await client.jobs.list();

// Filter by agent
const agentJobs = await client.jobs.list('agent-uuid');

// Run job immediately
const result = await client.jobs.run(job.uuid, 'full');
console.log(`Backup started: ${result.backupUuid}`);

// List job's backups
const backups = await client.jobs.listBackups(job.uuid);

for (const backup of backups) {
  console.log(`${backup.uuid}: ${backup.status} - ${backup.sizeBytes} bytes`);
}

// Update job
const updated = await client.jobs.update(job.uuid, {
  name: 'New Job Name',
  scheduleCron: '0 3 * * *',  // Change to 3 AM
});

// Enable/disable job
await client.jobs.disable(job.uuid);
await client.jobs.enable(job.uuid);

// Delete job and all its backups
await client.jobs.delete(job.uuid);

Machine Backups API

Manage machine backup restore points created by backup jobs.

// List all machine backups
const backups = await client.machineBackups.list();

// Filter by status
const completed = await client.machineBackups.list({ status: 'completed' });

// Get specific backup
const backup = await client.machineBackups.get('backup-uuid');
console.log(`Type: ${backup.backupType}`);
console.log(`Size: ${backup.sizeBytes} bytes`);
console.log(`Files: ${backup.filesCount}`);

// Create restore job
const restore = await client.machineBackups.restore('backup-uuid', {
  restoreType: 'full',            // 'full' or 'selective'
  targetType: 'original',         // 'original' or 'alternate'
  overwriteExisting: false,
  preservePermissions: true,
  // For alternate restore:
  // targetAgentUuid: 'other-agent-uuid',
  // targetPath: '/restore/path',
  // For selective restore:
  // selectedItems: ['/home/user/documents', '/var/www'],
});

console.log(`Restore job: ${restore.uuid}`);
console.log(`Status: ${restore.status}`);

// Delete backup
await client.machineBackups.delete('backup-uuid');

Error Handling

import { LoxClient } from '@lox-backup/sdk';
import {
  LoxError,
  AuthenticationError,
  NotFoundError,
  QuotaExceededError,
  ValidationError,
  RateLimitError,
  TimeoutError,
} from '@lox-backup/sdk/errors';

const client = new LoxClient();

try {
  const backup = await client.backups.upload({
    filePath: 'backup.tar.gz'
  });
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Invalid API key');
  } else if (error instanceof QuotaExceededError) {
    console.error('Storage quota exceeded');
  } else if (error instanceof NotFoundError) {
    console.error('Resource not found');
  } else if (error instanceof ValidationError) {
    console.error(`Validation error: ${error.message}`);
  } else if (error instanceof RateLimitError) {
    console.error('Rate limited, try again later');
  } else if (error instanceof TimeoutError) {
    console.error('Request timed out');
  } else if (error instanceof LoxError) {
    console.error(`API error: ${error.message}`);
  } else {
    throw error;
  }
}

TypeScript Types

The SDK exports all TypeScript types for full type safety:

import type {
  Backup,
  BackupStatus,
  BackupListParams,
  UploadOptions,
  Tenant,
  TenantQuota,
  StorageTarget,
  StorageHealth,
  RestoreResult,
} from '@lox-backup/sdk';

// Type-safe backup handling
function processBackup(backup: Backup): void {
  if (backup.status === 'completed') {
    console.log(`Ready: ${backup.name}`);
  }
}

// Type-safe options
const options: UploadOptions = {
  filePath: 'backup.tar.gz',
  name: 'typed-backup',
  tags: ['typescript'],
  retentionDays: 30,
};

Backup Type

FieldTypeDescription
uuidstringUnique identifier
namestringBackup name
statusBackupStatus'pending' | 'validating' | 'scanning' | 'distributing' | 'completed' | 'failed' | 'quarantine'
sizeBytesnumberFile size in bytes
checksumSha256stringSHA-256 hash
tagsstring[]Tags for organization
retentionDaysnumberDays until expiration
createdAtDateCreation timestamp
expiresAtDateExpiration timestamp

Complete Example

#!/usr/bin/env node
/**
 * LOX Backup - Database Backup Script (TypeScript)
 */
import { LoxClient } from '@lox-backup/sdk';
import { QuotaExceededError } from '@lox-backup/sdk/errors';
import { execSync } from 'child_process';
import { mkdtempSync, rmSync } from 'fs';
import { join } from 'path';
import { tmpdir } from 'os';

async function backupDatabase(): Promise<boolean> {
  const client = new LoxClient();

  // Check storage quota
  const quota = await client.tenant.getQuota();
  console.log(`Storage used: ${quota.usagePercentage}%`);

  // Create temp directory
  const tmpDir = mkdtempSync(join(tmpdir(), 'backup-'));
  const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
  const dumpFile = join(tmpDir, `db_${timestamp}.sql.gz`);

  try {
    // Dump PostgreSQL database
    execSync(`pg_dump mydb | gzip > ${dumpFile}`, { stdio: 'inherit' });

    // Upload to LOX
    const backup = await client.backups.upload({
      filePath: dumpFile,
      name: `postgres-mydb-${timestamp}`,
      tags: ['postgres', 'production', 'automated'],
      retentionDays: 30,
      waitForCompletion: true
    });

    console.log('Backup complete!');
    console.log(`  UUID: ${backup.uuid}`);
    console.log(`  Size: ${backup.sizeBytes.toLocaleString()} bytes`);
    console.log(`  Expires: ${backup.expiresAt}`);

    return true;
  } catch (error) {
    if (error instanceof QuotaExceededError) {
      console.error('ERROR: Storage quota exceeded!');
      console.error('Please delete old backups or upgrade your plan.');
      return false;
    }
    throw error;
  } finally {
    // Cleanup
    rmSync(tmpDir, { recursive: true });
  }
}

backupDatabase().catch(console.error);