# Ascii Box (/docs/providers/box)



Ascii Box provides persistent Linux VMs with files, bounded commands, HTTPS previews, desktop access, and stop/resume snapshots.

## Installation [#installation]

```bash title="Terminal"
bun add @opencoredev/sandbox-sdk ai zod @asciidev/box-sdk
```

## Authentication [#authentication]

Create an API key in the Box dashboard, then set `BOX_API_KEY` on the server that creates sandboxes.

```bash title=".env"
BOX_API_KEY=box_your_key
```

Pass `apiKey` to `box()` only when environment-based configuration is not available.

## Run a command [#run-a-command]

```ts title="box.ts"
import { createSandbox } from "@opencoredev/sandbox-sdk";
import { box } from "@opencoredev/sandbox-sdk/box";

await using sandbox = await createSandbox({ provider: box() });
await sandbox.files.write("hello.txt", "hello from Box");
console.log((await sandbox.run("cat hello.txt")).stdout);
```

The Box command API separates stdout and stderr. Commands default to 30 seconds and support at most 60 seconds. The API does not expose a streaming or background-process handle, so `sandbox.processes.start()` returns an `unsupported` error.

## Run an AI SDK agent [#run-an-ai-sdk-agent]

<ProviderAISDKExample provider="box" />

## Expose a preview [#expose-a-preview]

Start the server in the Box, bind it to `0.0.0.0`, then expose its port.

```ts title="preview.ts"
const preview = await sandbox.ports.expose(3000);
const response = await preview.request!("/health");
```

The adapter requests a public Box URL by default because that mode passed end-to-end live validation. Pass `box({ public: false })` to request Box's native token-gated mode; the adapter removes `_token` from `preview.url` and keeps it inside `request()`.

## Managed lifecycle [#managed-lifecycle]

The managed provider surface maps `stop()` to Box archive/snapshot, `resume()` to native resume, and `destroy()` to deletion. Normal `sandbox.stop()` performs full cleanup: it archives a running Box when required, waits for that transition, then deletes it.

Use `sandbox.raw.client` for native prompts, events, desktop streaming, forks, and snapshot inspection. The current native Box model is available at `sandbox.raw.box`.

## Options [#options]

| Option         | Type             | Default                         | Behavior                                      |
| -------------- | ---------------- | ------------------------------- | --------------------------------------------- |
| `apiKey`       | `string`         | `BOX_API_KEY`                   | Authenticates Box API requests.               |
| `baseUrl`      | `string`         | `BOX_BASE_URL` or public v1 URL | Overrides the Box API endpoint.               |
| `ttlSeconds`   | `number \| null` | Box service default             | Sets auto-archive; `null` disables it.        |
| `noEnv`        | `boolean`        | `false`                         | Withholds account-level secrets from the Box. |
| `name`         | `string`         | Generated by Box                | Applies a friendly name after provisioning.   |
| `public`       | `boolean`        | `true`                          | Returns ungated hosted URLs when true.        |
| `readyTimeout` | `number`         | `600000`                        | Limits the provisioning wait in milliseconds. |

Per-sandbox values passed to `createSandbox({ env })` are sent through Box's native `env` field. Box accepts at most 100 variables and 64 KB total.

## Read next [#read-next]

See [Ports](/docs/api/ports), compare exact modes in [Compatibility](/docs/reference/compatibility), or open the [Box SDK guide](https://docs.ascii.dev/box/sdks/typescript).
