Documentation v1.0.0

Overview

The Laravel Hetzner Storage Box SDK provides a production-ready client interface for managing storage boxes, subaccounts, and schedules. Compatible with PHP 8.2 through 8.5, and Laravel 11 through 13.

Fully Type-Safe DTOs. Every response matches structured class mappings with static `fromArray()` hydrators, allowing autocomplete and IDE indexing.

Installation

Install the package through Composer:

composer require ghostcompiler/laravel-hetzner-storagebox

Publish the configuration assets using the simplified command installer:

php artisan ghost:storagebox install

Configuration

The published configuration file lives at config/hetzner-storagebox.php. You can generate your API Token from the Hetzner Console under Security settings.

return [
    'token' => env('HETZNER_STORAGEBOX_TOKEN'),
    'base_url' => env('HETZNER_STORAGEBOX_BASE_URL', 'https://api.hetzner.com/v1'),
    'timeout' => (int) env('HETZNER_STORAGEBOX_TIMEOUT', 30),
    'retries' => (int) env('HETZNER_STORAGEBOX_RETRIES', 3),
    'retry_backoff' => (int) env('HETZNER_STORAGEBOX_RETRY_BACKOFF', 100),
    'logging' => [
        'enabled' => (bool) env('HETZNER_STORAGEBOX_LOGGING_ENABLED', false),
        'channel' => env('HETZNER_STORAGEBOX_LOGGING_CHANNEL'),
    ],
];

Service Provider

The service provider binds the singleton client and orchestrator to Laravel's service container.

use GhostCompiler\Hetzner\StorageBox\Managers\HetznerStorageBoxManager;

$manager = app(HetznerStorageBoxManager::class);
$boxes = $manager->storageBoxes()->all();

Facades

Interact with the SDK fluently using the Facade accessor.

use GhostCompiler\Hetzner\StorageBox\Facades\HetznerStorageBox;

$box = HetznerStorageBox::storageBoxes()->find(123);

Global Helper

Access the manager globally via the HetznerStorageBox() helper function. For multi-tenant setups, you can pass a dynamic token to generate an isolated, authenticated manager instance.

// Static/default container resolution
$boxes = HetznerStorageBox()->storageBoxes()->get();

// Dynamic authentication
$tenantBoxes = HetznerStorageBox('tenant_specific_token')->storageBoxes()->get();

Storage Boxes

Create, paginate, update, delete, scale, reset passwords, change protection, and manage access parameters (Samba, SSH, WebDAV, etc.) for Storage Boxes.

use GhostCompiler\Hetzner\StorageBox\Facades\HetznerStorageBox;

// Create storage box
$response = HetznerStorageBox::storageBoxes()->create([
    'name' => 'backups-prod',
    'storage_box_type' => 'bx11',
    'location' => 'fsn1',
    'password' => 'secure_password_here'
]);

$box = $response->storageBox;

// Find storage box by ID
$box = HetznerStorageBox::storageBoxes()->find(12345);

// Paginate storage boxes
$paginated = HetznerStorageBox::storageBoxes()->paginate(15, 1);
$boxes = $paginated->items();
$meta = $paginated->meta();

// Update storage box details
$updatedBox = HetznerStorageBox::storageBoxes()->update(12345, [
    'name' => 'backups-prod-v2'
]);

// Reset password
HetznerStorageBox::storageBoxes()->resetPassword(12345, 'new_password_here_123');

// Update access settings
HetznerStorageBox::storageBoxes()->updateAccessSettings(12345, [
    'samba_enabled' => true,
    'ssh_enabled' => true,
    'webdav_enabled' => false,
    'zfs_enabled' => false,
    'reachable_externally' => true
]);

// Change delete protection
HetznerStorageBox::storageBoxes()->changeProtection(12345, true);

// Change storage box product type
HetznerStorageBox::storageBoxes()->changeType(12345, 'bx21');

// Rollback snapshot
HetznerStorageBox::storageBoxes()->rollbackSnapshot(12345, 'snap-2026-06-13');

// Enable snapshot plan
HetznerStorageBox::storageBoxes()->enableSnapshotPlan(12345, [
    'hour' => 4,
    'minute' => 30,
    'timezone' => 'Europe/Berlin'
]);

// Disable snapshot plan
HetznerStorageBox::storageBoxes()->disableSnapshotPlan(12345);

// List folders inside storage box
$folders = HetznerStorageBox::storageBoxes()->folders(12345, '/backups');

// Delete a storage box
HetznerStorageBox::storageBoxes()->delete(12345);

Subaccounts

Create up to 100 subaccounts for a Storage Box. Restrict each subaccount to a specific directory with custom protocols and permissions.

// Get subaccount manager for a specific Storage Box
$subaccountsManager = HetznerStorageBox::storageBoxes()->subaccounts($boxId);

// List all subaccounts
$subaccounts = $subaccountsManager->all();

// Find a subaccount by ID
$sub = $subaccountsManager->find(10);

// Create a new subaccount
$newSub = $subaccountsManager->create([
    'name' => 'web-server-uploads',
    'description' => 'Storage for public uploads',
    'home_directory' => '/public/uploads',
    'access_settings' => [
        'samba_enabled' => false,
        'ssh_enabled' => true,
        'webdav_enabled' => true,
        'zfs_enabled' => false,
        'read_only' => false
    ]
]);

// Update subaccount details
$subaccountsManager->update(10, [
    'name' => 'updated-sub-name',
    'description' => 'Updated description'
]);

// Change subaccount home directory
$subaccountsManager->changeHomeDirectory(10, '/public/new-uploads');

// Reset subaccount password
$subaccountsManager->resetPassword(10, 'SecureSubPassword123!');

// Update subaccount access settings
$subaccountsManager->updateAccessSettings(10, [
    'samba_enabled' => true,
    'ssh_enabled' => true,
    'webdav_enabled' => false
]);

// Delete a subaccount
$subaccountsManager->delete(10);

Snapshots

Capture point-in-time states of your Storage Box filesystems. List, find, create, edit descriptions, or delete snapshots.

// Get snapshot manager for a specific Storage Box
$snapshotsManager = HetznerStorageBox::storageBoxes()->snapshots($boxId);

// List all snapshots
$snapshots = $snapshotsManager->all();

// Find a snapshot by ID
$snapshot = $snapshotsManager->find(20);

// Create a snapshot
$newSnapshot = $snapshotsManager->create([
    'description' => 'Database backup snapshot',
    'labels' => [
        'env' => 'production'
    ]
]);

// Update snapshot description and labels
$snapshotsManager->update(20, [
    'description' => 'Database backup snapshot - updated',
    'labels' => [
        'env' => 'production',
        'status' => 'archived'
    ]
]);

// Delete a snapshot
$snapshotsManager->delete(20);

Storage Box Types

Query available products representing storage box capacities and pricing limits.

$types = HetznerStorageBox::storageBoxTypes()->all();

foreach ($types as $type) {
    echo "Type: {$type->name} | Limit: {$type->snapshotLimit} snapshots";
}

Actions

Track the history and progress of asynchronous operations on Storage Boxes.

// List all actions
$actions = HetznerStorageBox::actions()->all();

// List actions for a specific Storage Box
$boxActions = HetznerStorageBox::storageBoxes()->actions($boxId);

Locations

Retrieve the physical datacenters where Storage Boxes can be provisioned.

$locations = HetznerStorageBox::locations()->all();

Async Requests

Run requests asynchronously to receive a Guzzle Promise which you can resolve later.

$promise = HetznerStorageBox::storageBoxes()->async()->all();

// Perform other operations...

$boxes = $promise->wait();

Batch Concurrent Operations

Group operations to run concurrently using the batch processor.

$results = HetznerStorageBox::batch([
    fn () => HetznerStorageBox::storageBoxes()->find(1),
    fn () => HetznerStorageBox::storageBoxes()->find(2),
    fn () => HetznerStorageBox::storageBoxTypes()->find(4),
]);

Retries & Limits

The HTTP client automatically intercepts `429 Too Many Requests` status codes and delays subsequent calls until the timestamp supplied in the RateLimit-Reset header passes.

$rateLimit = HetznerStorageBox::rateLimit();
echo "Remaining calls: " . $rateLimit['remaining'];

Exceptions

Exceptions map cleanly to HTTP status codes, inheriting from HetznerException.

use GhostCompiler\Hetzner\StorageBox\Exceptions\ValidationException;
use GhostCompiler\Hetzner\StorageBox\Exceptions\RateLimitException;

try {
    HetznerStorageBox::storageBoxes()->create(['name' => '']);
} catch (ValidationException $e) {
    $errors = $e->getErrors(); // field-specific errors
} catch (RateLimitException $e) {
    $seconds = $e->getSecondsUntilReset();
}

Helper Cheatsheet

A quick-reference for the most commonly used methods.

Resource Action Method
Storage Boxes List all HetznerStorageBox::storageBoxes()->all()
Storage Boxes Find one HetznerStorageBox::storageBoxes()->find($id)
Storage Boxes Create HetznerStorageBox::storageBoxes()->create($data)
Subaccounts List all HetznerStorageBox::storageBoxes()->subaccounts($boxId)->all()
Subaccounts Find one HetznerStorageBox::storageBoxes()->subaccounts($boxId)->find($id)
Subaccounts Create HetznerStorageBox::storageBoxes()->subaccounts($boxId)->create($data)
Snapshots List all HetznerStorageBox::storageBoxes()->snapshots($boxId)->all()
Snapshots Find one HetznerStorageBox::storageBoxes()->snapshots($boxId)->find($id)
Snapshots Create HetznerStorageBox::storageBoxes()->snapshots($boxId)->create($data)
Storage Box Types List all HetznerStorageBox::storageBoxTypes()->all()
Locations List all HetznerStorageBox::locations()->all()
Actions List all HetznerStorageBox::actions()->all()