PHP SDK

Official PHP SDK for LOX Backup. Modern PHP 8.1+ client with strongly-typed models.

v0.1.0Updated 2026-01-01
Installation
composer require lox-backup/lox-php

Requirements

  • PHP 8.1 or higher
  • Composer

Quick Start

<?php

require 'vendor/autoload.php';

use Lox\Client;
use Lox\Models\BackupStatus;

// Create client
$client = new Client('lox_key_xxx');

// Upload a backup
$backup = $client->backups->upload('/path/to/backup.tar.gz', [
    'name' => 'daily-backup',
    'tags' => ['production', 'database'],
    'retention_days' => 90,
    'wait' => true, // Wait for processing to complete
]);

echo "Backup created: {$backup->uuid} (status: {$backup->status->value})\n";

// List backups
$result = $client->backups->list([
    'tags' => ['production'],
    'page_size' => 10,
]);

echo "Found {$result->total} backups\n";

foreach ($result->items as $backup) {
    echo "- {$backup->name}: {$backup->status->value}\n";
}

Configuration

<?php

// Custom base URL
$client = new Client('lox_key_xxx', [
    'base_url' => 'https://api.custom-backlox.com',
]);

// Custom timeout
$client = new Client('lox_key_xxx', [
    'timeout' => 60,
]);

// Custom HTTP client (Guzzle)
$httpClient = new \GuzzleHttp\Client([
    'verify' => true,
]);
$client = new Client('lox_key_xxx', [
    'http_client' => $httpClient,
]);

Backups

Upload

$backup = $client->backups->upload('/path/to/file.tar.gz', [
    'name' => 'my-backup',
    'tags' => ['production'],
    'retention_days' => 30,
    'description' => 'Daily database backup',
    'wait' => true,
]);

List

use Lox\Models\BackupStatus;

$result = $client->backups->list([
    'tags' => ['production'],
    'status' => BackupStatus::COMPLETED,
    'page' => 1,
    'page_size' => 20,
]);

foreach ($result->items as $backup) {
    echo "{$backup->uuid}: {$backup->name} ({$backup->sizeBytes} bytes)\n";
}

Download

// Download with progress callback
$path = $client->backups->download($uuid, '/tmp/restored.tar.gz',
    function($downloaded, $total) {
        $percent = round($downloaded / $total * 100);
        echo "Progress: {$percent}%\n";
    }
);

// Or just get the download URL
$info = $client->backups->getDownloadUrl($uuid);
echo "Download from: {$info->url}\n";

Other Operations

// Get single backup
$backup = $client->backups->get($uuid);

// Delete backup
$client->backups->delete($uuid);

// Request restore
$job = $client->backups->restore($uuid);

// Wait for backup to complete
$backup = $client->backups->waitForCompletion($uuid, timeout: 3600, pollInterval: 5);

// Get statistics
$stats = $client->backups->getStats();
echo "Total: {$stats->totalBackups}, Completed: {$stats->completedBackups}\n";

// Get profiles (grouped by source/component)
$profiles = $client->backups->getProfiles('wordpress');
foreach ($profiles as $profile) {
    echo "{$profile->source}/{$profile->component}: {$profile->totalBackups} backups\n";
}

// Get latest backup per component
$latest = $client->backups->getLatest('wordpress');
foreach ($latest as $item) {
    $date = $item->lastBackupAt?->format('Y-m-d H:i') ?? 'Never';
    echo "{$item->component}: {$date}\n";
}

Storage Targets

use Lox\Models\StorageType;

// List storage targets
$targets = $client->storage->list();

// Get single target
$target = $client->storage->get($id);

// Create target
$target = $client->storage->create([
    'name' => 'AWS Glacier',
    'storage_type' => StorageType::S3_GLACIER,
    'config' => [
        'bucket' => 'my-bucket',
        'region' => 'us-east-1',
        'access_key_id' => 'AKIA...',
        'secret_access_key' => '...',
    ],
    'priority' => 1,
    'retention_days' => 365,
]);

// Update target
$target = $client->storage->update($id, [
    'is_enabled' => false,
]);

// Delete target
$client->storage->delete($id);

// Test connectivity
$result = $client->storage->test($id);
echo "Test queued: {$result->taskId}\n";

// Health summary
$summary = $client->storage->getHealthSummary();
echo "{$summary->healthy}/{$summary->total} targets healthy\n";

Tenant

// Get current tenant
$tenant = $client->tenant->getCurrent();
echo "Tenant: {$tenant->name} ({$tenant->slug})\n";

// Get quota
$quota = $client->tenant->getQuota();
echo "Used: {$quota->usedBytes} / {$quota->quotaBytes} bytes\n";
echo "Usage: {$quota->usagePercentage}%\n";
echo "Available: " . $quota->getAvailableBytes() . " bytes\n";

Notification Channels

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

use Lox\Models\ChannelType;
use Lox\Models\NotificationEvent;

// Create a webhook channel
$channel = $client->notificationChannels->create([
    'name' => 'Production Alerts',
    'channel_type' => ChannelType::WEBHOOK,
    'config' => ['url' => 'https://example.com/webhook'],
    'events' => [NotificationEvent::BACKUP_COMPLETED, NotificationEvent::BACKUP_FAILED],
]);
echo "Webhook secret: {$channel->config['secret']}\n";

// Create a Slack channel
$slack = $client->notificationChannels->create([
    'name' => 'Slack Alerts',
    'channel_type' => ChannelType::SLACK,
    'config' => [
        'webhook_url' => 'https://hooks.slack.com/services/...',
        'channel' => '#backup-alerts',
    ],
]);

// List channels
$channels = $client->notificationChannels->list();
foreach ($channels as $ch) {
    $status = $ch->isHealthy ? 'healthy' : 'unhealthy';
    echo "{$ch->name} ({$ch->channelType->value}): {$status}\n";
}

// Test a channel
$result = $client->notificationChannels->test($channelUuid);
echo "Test result: {$result->status}\n";

// Get summary
$summary = $client->notificationChannels->getSummary();
echo "Total: {$summary->totalChannels}, Unhealthy: {$summary->unhealthyChannels}\n";

// Enable/disable
$client->notificationChannels->enable($channelUuid);
$client->notificationChannels->disable($channelUuid);

// Delete
$client->notificationChannels->delete($channelUuid);

Backup Agents

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

use Lox\Models\OSType;

// Register a new agent
$registration = $client->agents->register([
    'hostname' => 'server-01',
    'os_type' => OSType::LINUX,
    'display_name' => 'Production Server 01',
    'capabilities' => ['file', 'block'],
    'hardware_info' => [
        'cpu_cores' => 8,
        'memory_gb' => 32,
    ],
]);
echo "Agent UUID: {$registration->uuid}\n";
echo "Token: {$registration->registrationToken}\n";

// Get install command
$cmd = $client->agents->getInstallCommand($agentUuid);
echo $cmd->recommendedCommand . "\n";

// List agents
$agents = $client->agents->list();
foreach ($agents as $agent) {
    echo "{$agent->hostname} ({$agent->osType->value}): {$agent->status->value}\n";
}

// Get summary
$summary = $client->agents->getSummary();
echo "Online: {$summary->onlineAgents}, Offline: {$summary->offlineAgents}\n";

// Update agent
$agent = $client->agents->update($agentUuid, [
    'display_name' => 'New Display Name',
]);

// Enable/disable
$client->agents->enable($agentUuid);
$client->agents->disable($agentUuid);

// Regenerate token
$reg = $client->agents->regenerateToken($agentUuid);

// Delete agent
$client->agents->delete($agentUuid);

Backup Jobs

Create and manage scheduled backup jobs for automated machine backups.

use Lox\Models\JobType;
use Lox\Models\BackupMode;

// Create a backup job
$job = $client->jobs->create([
    'agent_uuid' => $agentUuid,
    'name' => 'Daily Full Backup',
    'job_type' => JobType::FILE,
    'sources' => [
        ['type' => 'path', 'value' => '/home'],
        ['type' => 'path', 'value' => '/var/www'],
    ],
    'exclusions' => ['*.log', '*.tmp', 'node_modules'],
    'backup_mode' => BackupMode::FULL,
    'schedule_cron' => '0 2 * * *',  // Daily at 2 AM
    'schedule_enabled' => true,
    'retention_policy' => [
        'daily' => 7,
        'weekly' => 4,
        'monthly' => 12,
    ],
    'compression' => 'zstd',
    'compression_level' => 6,
    'encryption_enabled' => true,
    'verify_after_backup' => true,
]);
echo "Job created: {$job->uuid}\n";

// List jobs (optionally filter by agent)
$jobs = $client->jobs->list();  // or $client->jobs->list($agentUuid)
foreach ($jobs as $j) {
    echo "{$j->name}: {$j->status->value}\n";
}

// Run job immediately
$result = $client->jobs->run($jobUuid, 'full');
echo "Backup started: {$result->backupUuid}\n";

// List job's backups
$backups = $client->jobs->listBackups($jobUuid);

// Update job
$job = $client->jobs->update($jobUuid, [
    'name' => 'New Job Name',
    'schedule_cron' => '0 3 * * *',
]);

// Enable/disable
$client->jobs->enable($jobUuid);
$client->jobs->disable($jobUuid);

// Delete job and all its backups
$client->jobs->delete($jobUuid);

Machine Backups

Manage machine backup restore points created by backup jobs.

// List machine backups
$backups = $client->machineBackups->list(['status' => 'completed', 'limit' => 50]);
foreach ($backups as $b) {
    echo "{$b->uuid}: {$b->backupType} ({$b->sizeBytes} bytes)\n";
}

// Get specific backup
$backup = $client->machineBackups->get($backupUuid);
echo "Files: {$backup->filesCount}\n";

// Restore backup
$restore = $client->machineBackups->restore($backupUuid, [
    'restore_type' => 'full',
    'target_type' => 'original',
    'overwrite_existing' => false,
    'preserve_permissions' => true,
    // For alternate restore:
    // 'target_agent_uuid' => 'other-agent-uuid',
    // 'target_path' => '/restore/path',
    // For selective restore:
    // 'selected_items' => ['/home/user/documents'],
]);
echo "Restore job: {$restore->uuid}\n";

// Delete backup
$client->machineBackups->delete($backupUuid);

Error Handling

use Lox\Exceptions\AuthenticationException;
use Lox\Exceptions\NotFoundException;
use Lox\Exceptions\QuotaExceededException;
use Lox\Exceptions\BackupFailedException;
use Lox\Exceptions\BackupQuarantinedException;
use Lox\Exceptions\RateLimitedException;
use Lox\Exceptions\LoxException;

try {
    $backup = $client->backups->get($uuid);
} catch (NotFoundException $e) {
    echo "Backup not found\n";
} catch (AuthenticationException $e) {
    echo "Invalid API key\n";
} catch (QuotaExceededException $e) {
    echo "Storage quota exceeded: {$e->usedBytes}/{$e->quotaBytes} bytes\n";
} catch (BackupFailedException $e) {
    echo "Backup failed: {$e->getMessage()}\n";
} catch (BackupQuarantinedException $e) {
    echo "Backup quarantined: {$e->getMessage()}\n";
    foreach ($e->threats as $threat) {
        echo "  - {$threat}\n";
    }
} catch (RateLimitedException $e) {
    echo "Rate limited. Retry after: {$e->retryAfter} seconds\n";
} catch (LoxException $e) {
    echo "Error: {$e->getMessage()} (code: {$e->getErrorCode()})\n";
}

Exception Classes

ExceptionHTTP StatusDescription
AuthenticationException401Invalid or missing API key
NotFoundException404Resource not found
QuotaExceededException413Storage quota exceeded
RateLimitedException429Too many requests
BackupQuarantinedException400Malware detected

Models

The SDK uses strongly-typed models with readonly properties:

ModelDescription
BackupBackup record with status, size, checksums
BackupStatsAggregate statistics
BackupProfileGrouping by source/component
LatestBackupLatest backup per component
DownloadInfoPre-signed download URL info
StorageTargetStorage target configuration
TenantTenant information
TenantQuotaStorage quota with helper methods