Skip to content
LogoLogo

Quickstart

The 30-second tour: install, authenticate, spawn a sandbox, run a command, and tear it down. For a full guided lesson, see the tutorial; for the conceptual picture, start with what a VM sandbox is.

At a glance

  • Package: @nodeops-createos/sandbox (npm)
  • Import: import { createClient } from "@nodeops-createos/sandbox"
  • Base URL: https://api.sb.createos.sh (override with CREATEOS_SANDBOX_BASE_URL)
  • Auth: API key via the apiKey option or CREATEOS_SANDBOX_API_KEY

1. Install

bun add @nodeops-createos/sandbox
# or: npm install @nodeops-createos/sandbox

The SDK is ESM-only with zero runtime dependencies. It runs on Node 20+, Bun, Deno, Cloudflare Workers, Vercel Edge, and the browser.

2. Get an API key

Provision a key through your createos-sandbox control plane (your operator's identity portal or CLI). The key is per-user; treat it like a database password and keep it out of source control.

3. Configure and authenticate

The client targets the production control plane by default; set baseUrl (or CREATEOS_SANDBOX_BASE_URL) only to point at a different one. Give it an API key. The simplest path is two environment variables:

export CREATEOS_SANDBOX_BASE_URL="https://api.sb.createos.sh"
export CREATEOS_SANDBOX_API_KEY="sk_…"
import { createClient } from "@nodeops-createos/sandbox";
 
const client = createClient(); // reads CREATEOS_SANDBOX_BASE_URL + CREATEOS_SANDBOX_API_KEY
// or pass them explicitly:
// createClient({ baseUrl: "https://…", apiKey: "sk_…" });

Confirm the key works before going further:

console.log(await client.whoami());

4. Spawn a sandbox

const sandbox = await client.createSandbox({
  shape: "s-4vcpu-4gb",
  rootfs: "devbox:1",
});
console.log("ready:", sandbox.id, sandbox.status);

createSandbox blocks until the sandbox is running by default. Pass { wait: false } to return as soon as the row exists and poll yourself with waitUntilRunning. Pick a shape from client.listShapes() and a rootfs from client.listRootfs().

5. Run a command

const result = await sandbox.runCommand("uname", ["-a"]);
console.log(result.result.stdout);

runCommand buffers stdout/stderr and resolves when the command exits. For long-running commands, stream the output. See How-to: streaming.

6. Tear down

await sandbox.destroy();

destroy is asynchronous on the server; call sandbox.waitUntilDestroyed() if you need the row reclaimed before continuing.

Put it together

Sandboxes bill while they run, so wrap the work in try / finally and always destroy:

import { createClient } from "@nodeops-createos/sandbox";
 
const client = createClient();
const sandbox = await client.createSandbox({ shape: "s-4vcpu-4gb", rootfs: "devbox:1" });
try {
  const out = await sandbox.runCommand("uname", ["-a"]);
  console.log(out.result.stdout);
} finally {
  await sandbox.destroy();
}

Cost control. A sandbox you forget to destroy keeps billing. Either tear it down in finally, or set an idle auto-pause so it stops billing on its own: createSandbox({ …, auto_pause_after_seconds: 300 }). See How-to: lifecycle.

Troubleshooting

  • CreateosSandboxAuthError on the first call: the API key is missing or wrong. Verify with await client.whoami().
  • CreateosSandboxConnectionError: the control plane is unreachable. Check CREATEOS_SANDBOX_BASE_URL and any corporate proxy or firewall.
  • CreateosSandboxTimeoutError from createSandbox: the sandbox never reached running before the wait budget elapsed. Increase waitTimeoutMs, or pass { wait: false } and poll yourself.
  • CreateosSandboxServerError with status 503: the host pool is saturated. The SDK already retried with backoff; try again after the suggested Retry-After window. See reliability.

Next steps