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.
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() |