PHPackages                             zeevx/php-brimble-sandbox - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. zeevx/php-brimble-sandbox

ActiveLibrary[API Development](/categories/api)

zeevx/php-brimble-sandbox
=========================

Framework-agnostic PHP SDK for the Brimble Sandbox API.

v0.1.0(1mo ago)0581MITPHPPHP ^8.2CI passing

Since Jul 4Pushed 1mo agoCompare

[ Source](https://github.com/zeevx/php-brimble-sandbox)[ Packagist](https://packagist.org/packages/zeevx/php-brimble-sandbox)[ Docs](https://github.com/zeevx/php-brimble-sandbox)[ RSS](/packages/zeevx-php-brimble-sandbox/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (4)Versions (2)Used By (1)

Brimble Sandbox PHP SDK
=======================

[](#brimble-sandbox-php-sdk)

A framework-agnostic PHP client for the [Brimble Sandbox API](https://paper.brimble.io/api-reference/sandboxes): ephemeral compute environments with exec, code execution, files, snapshots, and persistent volumes.

- PHP 8.2+ · Guzzle transport · typed DTOs and enums · SSE streaming exec
- Typed exception mapping, retry with backoff, and the `{ message, data }` envelope handled for you

> Using Laravel? See `zeevx/laravel-brimble-sandbox` for config, a facade, and the container binding.

Install
-------

[](#install)

```
composer require zeevx/php-brimble-sandbox
```

Quick start
-----------

[](#quick-start)

```
use Zeevx\BrimbleSandbox\Sandbox;
use Zeevx\BrimbleSandbox\Requests\ExecInput;
use Zeevx\BrimbleSandbox\Requests\CreateSandbox;

$client = new Sandbox(apiKey: '...');   // or set BRIMBLE_SANDBOX_KEY

$sb = $client->sandboxes()->create(new CreateSandbox(template: 'node-22'));

echo $sb->exec(new ExecInput('node -v'))->stdout;   // "v22.x.x"

$sb->putFile('tmp/app.js', "console.log('hi')");
echo $sb->exec(new ExecInput('node /tmp/app.js'))->stdout;

$sb->destroy();
```

The API key is resolved from the constructor argument first, then the `BRIMBLE_SANDBOX_KEY` environment variable.

Running commands and code
-------------------------

[](#running-commands-and-code)

```
use Zeevx\BrimbleSandbox\Requests\CodeInput;
use Zeevx\BrimbleSandbox\Enums\CodeLanguage;

// Shell command (pipes, &&, redirects all work)
$result = $sb->exec(new ExecInput(
    cmd: 'npm install && npm test',
    timeoutSeconds: 120,
    cwd: '/app',
    env: ['NODE_ENV' => 'test'],
));
$result->stdout;   // string
$result->exitCode; // int
$result->succeeded(); // bool

// Code snippet, no shell escaping needed
$sb->code(new CodeInput(CodeLanguage::Python, "print('hello')"));
```

### Streaming output

[](#streaming-output)

`exec`/`code` can stream stdout/stderr as Server-Sent Events. Iterate the frames as they arrive, then read the final result:

```
$stream = $sb->execStream(new ExecInput('npm install'));

foreach ($stream as $frame) {
    if ($frame->isStdout()) {
        echo $frame->data;
    } elseif ($frame->isStderr()) {
        fwrite(STDERR, $frame->data);
    }
}

$result = $stream->result();   // ExecResult with the captured output + exit code
```

Files
-----

[](#files)

Paths are relative to the sandbox root (`tmp/notes.txt` → `/tmp/notes.txt`). The parent directory must already exist.

```
$sb->putFile('tmp/notes.txt', 'hello');      // upload raw bytes
$contents = $sb->getFile('tmp/notes.txt');   // download as string
$stream   = $sb->downloadStream('big.bin');  // PSR-7 stream for large files
```

Lifecycle, egress, and stats
----------------------------

[](#lifecycle-egress-and-stats)

```
use Zeevx\BrimbleSandbox\Enums\SandboxStatus;
use Zeevx\BrimbleSandbox\Requests\UpdateEgress;
use Zeevx\BrimbleSandbox\Enums\SandboxEgressMode;

$sb->pause();                 // -> ack message
$sb->resume();
$sb->wait(SandboxStatus::Ready);   // client-side poll after a resume

$sb->updateEgress(new UpdateEgress(SandboxEgressMode::Restricted, ['api.openai.com']));

$stats = $sb->stats(hoursAgo: 6);  // CPU / memory / network
```

Snapshots and volumes
---------------------

[](#snapshots-and-volumes)

```
use Zeevx\BrimbleSandbox\Requests\CreateVolume;
use Zeevx\BrimbleSandbox\Enums\VolumeType;

// Snapshots
$snap = $sb->createSnapshot('nightly');
$sb->snapshots();                 // this sandbox, paginated
$client->snapshots()->list();     // all snapshots for the account
$client->snapshots()->delete($snap->id);

// Volumes
$volume = $client->volumes()->create(new CreateVolume(
    name: 'node-cache',
    sizeGB: 10,
    region: $regionId,
    type: VolumeType::Sandbox,
));
$client->volumes()->list();
$client->volumes()->delete($volume->id);
```

Catalog
-------

[](#catalog)

```
$client->regions();     // list: sandbox-eligible regions
$client->templates();   // list: available images
```

Pagination
----------

[](#pagination)

List endpoints return a `Paginated` object you can iterate directly:

```
$page = $client->sandboxes()->list(page: 1, limit: 15);

foreach ($page as $sandbox) { /* SandboxData */ }

$page->totalCount;
$page->currentPage;
$page->hasMorePages();
```

Error handling
--------------

[](#error-handling)

Every non-2xx response raises a typed exception. All API exceptions extend `SandboxApiException` and carry `status`, `method`, `endpoint`, `responseBody`, and `requestId`.

ExceptionStatus`AuthException`401, 403`ValidationException`400, 422`NotFoundException`404`RateLimitException`429 (with `->retryAfter`)`SandboxApiException`any other non-2xx`TransportException`no HTTP response (DNS, connection, timeout)`ConfigurationException`bad/missing config (e.g. no API key)```
use Zeevx\BrimbleSandbox\Exceptions\NotFoundException;
use Zeevx\BrimbleSandbox\Exceptions\SandboxApiException;

try {
    $client->sandboxes()->get($id);
} catch (NotFoundException $e) {
    // ...
} catch (SandboxApiException $e) {
    error_log("{$e->method} {$e->endpoint} -> {$e->status}: {$e->getMessage()}");
}
```

Retries
-------

[](#retries)

Idempotent methods (`GET`, `PUT`, `DELETE`) are retried automatically on `408, 429, 500, 502, 503, 504` with exponential backoff (honouring `Retry-After`). A `POST` is only retried when you pass an idempotency key:

```
$client->sandboxes()->create($input, idempotencyKey: 'my-unique-key');
```

Tune it on the client:

```
$client = new Sandbox(apiKey: '...', timeout: 90.0, maxRetries: 2);
```

Custom HTTP client
------------------

[](#custom-http-client)

Inject your own Guzzle client (middleware, logging, a mock handler in tests):

```
use Zeevx\BrimbleSandbox\Config;

$client = Sandbox::fromConfig(new Config(apiKey: '...'), $myGuzzleClient);
```

Development
-----------

[](#development)

```
composer test      # Pest
composer lint      # Pint
composer analyse   # PHPStan level 8
```

License
-------

[](#license)

MIT

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance90

Actively maintained with recent releases

Popularity12

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

48d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/89e891f62dbee3c7f6979348f5e75af5b72267a9160456918e63f80092281ff4?d=identicon)[zeevx](/maintainers/zeevx)

---

Top Contributors

[![zeevx](https://avatars.githubusercontent.com/u/44035730?v=4)](https://github.com/zeevx "zeevx (2 commits)")

---

Tags

apisdksandboxbrimble

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/zeevx-php-brimble-sandbox/health.svg)

```
[![Health](https://phpackages.com/badges/zeevx-php-brimble-sandbox/health.svg)](https://phpackages.com/packages/zeevx-php-brimble-sandbox)
```

###  Alternatives

[aws/aws-sdk-php

AWS SDK for PHP - Use Amazon Web Services in your PHP project

6.2k555.0M2.8k](/packages/aws-aws-sdk-php)[eslazarev/wildberries-sdk

Wildberries OpenAPI clients (generated).

353.6k](/packages/eslazarev-wildberries-sdk)[tencentcloud/tencentcloud-sdk-php

TencentCloudApi php sdk

3661.3M49](/packages/tencentcloud-tencentcloud-sdk-php)[resend/resend-php

Resend PHP library.

608.3M53](/packages/resend-resend-php)[checkout/checkout-sdk-php

Checkout.com SDK for PHP

563.6M16](/packages/checkout-checkout-sdk-php)[files.com/files-php-sdk

Files.com PHP SDK

2482.9k](/packages/filescom-files-php-sdk)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
