> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stateset.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sandbox SDK (Node.js)

> Node.js SDK usage for creating and managing sandboxes.

Create sandboxes, run commands in them, and move files in and out. Get an API
key at [sandbox.stateset.com](https://sandbox.stateset.com).

## Install

```bash theme={null}
npm install @stateset/sandbox-sdk
```

## Initialize the Client

```typescript theme={null}
import { StateSetSandbox } from '@stateset/sandbox-sdk';

const client = new StateSetSandbox({
  baseUrl: 'https://api.sandbox.stateset.app',
  authToken: 'sk-sandbox-YOUR_API_KEY',
  orgId: 'org_YOUR_ORG_ID'
});
```

## Create and Execute

```typescript theme={null}
const sandbox = await client.create({ timeout_seconds: 300 });
const result = await client.execute(sandbox.sandbox_id, {
  command: ['python3', '-c', 'print("Hello from Stateset!")']
});
```

## File Operations

```typescript theme={null}
await client.writeFiles(sandbox.sandbox_id, [
  { path: '/workspace/hello.txt', content: Buffer.from('Hello!').toString('base64') }
]);

const file = await client.readFiles(sandbox.sandbox_id, ['/workspace/hello.txt']);
```

File content crosses the wire as **base64** in both directions, as above —
sending raw text writes the literal characters of your string rather than the
bytes you meant.

## Cleanup

```typescript theme={null}
await client.stop(sandbox.sandbox_id);
```

<Warning>
  A sandbox runs, and bills, until it is stopped or `timeout_seconds` expires.
  Stop it in a `finally` block so a thrown error does not leave one up:

  ```typescript theme={null}
  const sandbox = await client.create({ timeout_seconds: 300 });
  try {
    const result = await client.execute(sandbox.sandbox_id, {
      command: ['python3', '-c', 'print("hello")'],
    });
    console.log(result.stdout);
  } finally {
    await client.stop(sandbox.sandbox_id);
  }
  ```
</Warning>

## Handling failures

`execute` resolves for a command that ran and failed — a non-zero exit is a
result, not an exception. Check `exit_code` yourself; only transport and API
errors reject.

```typescript theme={null}
const result = await client.execute(sandbox.sandbox_id, {
  command: ['npm', 'run', 'build'],
});

if (result.exit_code !== 0) {
  throw new Error(`build failed (${result.exit_code}): ${result.stderr}`);
}
```

## Next steps

<CardGroup cols={2}>
  <Card title="Sandbox quickstart" icon="rocket" href="/stateset-sandbox/stateset-sandbox-quickstart-guide">
    The wider flow, including REPL sessions and checkpoints.
  </Card>

  <Card title="API reference" icon="code" href="/stateset-sandbox/stateset-sandbox-api-reference">
    Every endpoint this SDK wraps.
  </Card>

  <Card title="Python SDK" icon="python" href="/stateset-sandbox/stateset-sandbox-sdk-python">
    The same surface for Python services.
  </Card>

  <Card title="Security guide" icon="shield-halved" href="/stateset-sandbox/stateset-sandbox-security-guide">
    What a sandboxed process can and cannot reach.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.