Skip to main content

Installation

npm install @pocketenv/sdk
# or
bun add @pocketenv/sdk

Authentication

Token resolution order:
  1. Sandbox.configure({ token }) or inline Sandbox.create({ token })
  2. POCKETENV_TOKEN environment variable
  3. ~/.pocketenv/token.json
Sandbox.configure() is optional if you have a token file or env var set.

Quick start

import { Sandbox } from "@pocketenv/sdk";

const sandbox = await Sandbox.create({ base: "openclaw" });

const result = await sandbox.sh`echo hello`;
console.log(result.stdout); // "hello\n"

await sandbox.stop();
await sandbox.delete();

Sandbox lifecycle

// Create
const sandbox = await Sandbox.create({
  base: "openclaw",
  name: "my-sandbox",
  provider: "cloudflare",
});

// Fetch existing
const existing = await Sandbox.get("sandbox-id");

// List
const { sandboxes, total } = await Sandbox.list({ limit: 20, offset: 0 });

// Start / stop / delete
await sandbox.start({ repo: "github:myorg/myapp", keepAlive: true });
await sandbox.stop();
await sandbox.delete();

Builder pattern

Useful when setting many options:
const sandbox = await Sandbox.builder("openclaw")
  .name("api-sandbox")
  .provider("daytona")
  .vcpus(4)
  .memory(8192)
  .disk(20)
  .env("NODE_ENV", "production")
  .env("PORT", "3000")
  .secret("DATABASE_URL", process.env.DATABASE_URL!)
  .secret("API_KEY", process.env.API_KEY!)
  .keepAlive()
  .create();
Available builder methods: name, description, provider, topics, repo, vcpus, memory, disk, readme, env, secret, keepAlive, token, baseUrl.

Running commands

// Tagged template literal (safe interpolation)
const dir = "/home/user/app";
const result = await sandbox.sh`ls -la ${dir}`;
console.log(result.stdout);
console.log(result.stderr);
console.log(result.exitCode);

// Raw exec
await sandbox.exec("npm install");

Environment variables & secrets

// Env vars (plaintext)
await sandbox.env.put("API_URL", "https://api.example.com");
const vars = await sandbox.env.list();
await sandbox.env.delete(varId);

// Secrets (encrypted, redacted in responses)
await sandbox.secret.put("API_KEY", process.env.API_KEY!);
const secrets = await sandbox.secret.list();
await sandbox.secret.delete(secretId);

Ports & networking

const exposed = await sandbox.expose(3000, "Web server");
console.log(exposed.previewUrl);

await sandbox.unexpose(3000);

const ports = await sandbox.ports.list();

// VS Code in the browser
const vscode = await sandbox.vscode();
console.log(vscode.previewUrl);

Files

await sandbox.file.write("/app/config.json", JSON.stringify({ debug: true }));

const files = await sandbox.file.list();
const file  = await sandbox.file.get(fileId);
await sandbox.file.delete(fileId);

Services

const service = await sandbox.service.add("web", {
  command: "npm start",
  description: "Node.js web server",
  ports: [3000],
});

await sandbox.service.start(service.id);
await sandbox.service.restart(service.id);
await sandbox.service.stop(service.id);
await sandbox.service.delete(service.id);

Volumes

await sandbox.volume.create("data", "/mnt/data");
const volumes = await sandbox.volume.list();
await sandbox.volume.delete(volumeId);

Backups

const backup = await sandbox.createBackup("/workspace", "pre-deploy", "7d");
const backups = await sandbox.listBackups();
await Sandbox.restoreBackup(backupId); // static method

SSH keys & Tailscale

const keys = await sandbox.getSshKeys();
await sandbox.putSshKey(publicKey, privateKey);

await sandbox.tailscale.setAuthKey("tskey-auth-...");
const key = await sandbox.tailscale.getAuthKey();

Sub-resource reference

Sub-resourceMethods
sandbox.filewrite, list, get, update, delete
sandbox.envput, list, get, update, delete
sandbox.secretput, list, get, update, delete
sandbox.volumecreate, list, get, update, delete
sandbox.portslist
sandbox.serviceadd, list, start, stop, restart, update, delete
sandbox.tailscalegetAuthKey, setAuthKey
sandbox.backupcreate, list, restore