CreateosSandboxClient
The SDK entry point. Owns transport configuration (auth, base URL, timeouts,
retries) and exposes catalog and identity calls, the sandbox factory, and the
templates / networks / disks sub-APIs. Every method reaches the
control plane and also throws CreateosSandboxServerError on 5xx
responses and CreateosSandboxConnectionError on network
failure; per-method Throws sections list only conditions specific to that
call.
At a glance
- Package:
@nodeops-createos/sandbox(npm) - Import:
import { createClient } from "@nodeops-createos/sandbox" - Base URL:
https://api.sb.createos.sh— override withCREATEOS_SANDBOX_BASE_URL - Auth: API key via the
apiKeyoption orCREATEOS_SANDBOX_API_KEY
Construction
TypeScript1import { CreateosSandboxClient, createClient } from "@nodeops-createos/sandbox";23// Read credentials from environment variables4const box = new CreateosSandboxClient();56// Explicit options7const box = new CreateosSandboxClient({8 baseUrl: "https://api.sb.createos.sh",9 apiKey: process.env.CREATEOS_SANDBOX_API_KEY,10});1112// Factory alias — identical behaviour13const box = createClient({ baseUrl: "https://api.sb.createos.sh" });
new CreateosSandboxClient(options?)
TypeScript1new CreateosSandboxClient(options: CreateosSandboxClientOptions = {}): CreateosSandboxClient
Resolves options against environment defaults and constructs the
transport. Throws CreateosSandboxError synchronously for invalid options
(invalid baseUrl URL, both apiKey and authHeaders provided, no
fetch available).
Options
| Name | Type | Default | Description |
|---|---|---|---|
baseUrl | string | CREATEOS_SANDBOX_BASE_URL env var, then the production default | Control-plane base URL. Defaults to the production control plane when absent from both options and env. |
apiKey | string | CREATEOS_SANDBOX_API_KEY env var | API key sent as X-Api-Key. Mutually exclusive with authHeaders. |
authHeaders | HeadersInit | — | Auth headers used instead of an API key (e.g. a session token). Mutually exclusive with apiKey. |
timeoutMs | number | 60000 | Per-request timeout in ms. 0 disables it. |
retry | RetryOptions | false | 2 retries, 500 ms base, 30 s ceiling | Exponential-backoff retry policy, or false to disable retries entirely. |
headers | HeadersInit | — | Headers merged into every outgoing request. |
hooks | ClientHooks | — | Lifecycle hooks for zero-dependency observability. Payloads are pre-redacted — credentials never reach a hook. |
fetch | typeof fetch | globalThis.fetch | Custom fetch implementation. |
userAgent | string | SDK default | Overrides the User-Agent header. |
Env-var resolution order — explicit option wins, then environment variable, then the built-in default.
retry shape (RetryOptions):
| Field | Default | Description |
|---|---|---|
maxRetries | 2 | Extra attempts after the first (3 total). |
baseDelayMs | 500 | Base backoff delay in ms. |
maxDelayMs | 30000 | Backoff ceiling in ms. |
Idempotent methods (GET/HEAD/PUT/DELETE) retry on network errors and
408/500/502/503/504. Non-idempotent methods retry only on 429/503.
Streaming requests are never retried.
hooks shape (ClientHooks):
TypeScript1interface ClientHooks {2 onRequest?: (ctx: RequestHookContext) => void | Promise<void>;3 onResponse?: (ctx: ResponseHookContext) => void | Promise<void>;4 onRetry?: (ctx: RetryHookContext) => void | Promise<void>;5}
If a hook returns a promise it adds its own latency to the call — keep hook work cheap, or dispatch slow work without awaiting the promise. Errors thrown inside a hook are swallowed so a misbehaving observer cannot crash a real request.
createClient(options?)
TypeScript1function createClient(options?: CreateosSandboxClientOptions): CreateosSandboxClient
Convenience factory. Equivalent to new CreateosSandboxClient(options).
Example
TypeScript1import { createClient } from "@nodeops-createos/sandbox";23const box = createClient({ apiKey: process.env.CREATEOS_SANDBOX_API_KEY });
Accessors
| Accessor | Type | Description |
|---|---|---|
box.http | CreateosSandboxHttp | Low-level transport. Escape hatch for requests the SDK does not model. See helpers. |
box.baseUrl | string | Resolved base URL (read-only). |
box.templates | TemplatesApi | Template (custom rootfs) operations. See sub-APIs. |
box.networks | NetworksApi | Overlay network operations. See sub-APIs. |
box.disks | DisksApi | S3-disk catalog operations. See sub-APIs. |
Sandbox factory
createSandbox
TypeScript1createSandbox(2 request: CreateSandboxRequest,3 options?: CreateSandboxOptions,4): Promise<Sandbox>
Creates a sandbox and, by default, waits until it reaches running before
resolving. Pass { wait: false } to return a Sandbox handle
as soon as the server row exists (status will be creating).
Internally the SDK issues POST /v1/sandboxes, then immediately fetches the
full SandboxView via GET /v1/sandboxes/:id (the create response lacks
status and created_at required by the handle). When wait is not false
it then polls waitUntilRunning with a budget of waitTimeoutMs (default
120 s).
CreateSandboxRequest fields
| Field | Type | Required | Description |
|---|---|---|---|
shape | string | Yes | Shape id from listShapes() — e.g. s-4vcpu-4gb. |
rootfs | string | — | Rootfs catalog name or template id/name. Omit for the host default. |
name | string | — | User-facing VM name, unique per user. Auto-generated when omitted. |
networks | NetworkEntry[] | — | Overlay networks to join at create time. |
disk_mib | number | — | Overlay disk size in MiB. 0 or omit for the shape default. |
egress | string[] | — | Egress allowlist. [] or ["*"] allows all. |
envs | Record<string, string> | — | Env vars injected into every command inside the VM. |
ssh_pubkeys | string[] | — | OpenSSH public keys authorized for the SSH gateway. |
host_id | string | — | Pin to a specific host id. |
region | string | — | Pin to a region. Must equal the server's configured region — cross-region routing is not supported. |
auto_pause_after_seconds | number | — | Idle auto-pause timeout in seconds (range 60–86400). Omit to disable. |
bandwidth_quota_bytesis not settable at create time — the server rejects a non-zero value. Grow bandwidth post-create withSandbox.rechargeBandwidth().
CreateSandboxOptions fields
Extends RequestOptions.
| Field | Type | Default | Description |
|---|---|---|---|
wait | boolean | true | Wait until the sandbox reaches running. Set false to return early. |
waitTimeoutMs | number | 120000 | Budget for the wait poll, in ms. |
Throws
CreateosSandboxValidationError— shape or rootfs unknown.CreateosSandboxAuthError— API key missing or revoked.CreateosSandboxPermissionError— caller hit quota.CreateosSandboxTimeoutError— per-request timeout or wait budget elapsed.
Example
TypeScript1import { CreateosSandboxClient } from "@nodeops-createos/sandbox";23const box = new CreateosSandboxClient();4const sandbox = await box.createSandbox({5 shape: "s-4vcpu-4gb",6 rootfs: "devbox:1",7 envs: { CI: "1" },8});9try {10 const { result } = await sandbox.runCommand("bash", ["-c", "echo hello"]);11 console.log(result.stdout);12} finally {13 await sandbox.destroy();14}
getSandbox
TypeScript1getSandbox(id: string, options?: RequestOptions): Promise<Sandbox>
Connects to an existing sandbox by id. Returns a Sandbox
handle backed by the current server-side view.
Parameters
| Name | Type | Description |
|---|---|---|
id | string | Sandbox id (e.g. sb_01h…). |
options | RequestOptions | Per-request overrides. |
Returns Promise<Sandbox>
Throws
CreateosSandboxNotFoundError— no sandbox with that id exists.CreateosSandboxAuthError— API key missing or revoked.CreateosSandboxPermissionError— sandbox belongs to another tenant.CreateosSandboxTimeoutError— per-request timeout elapsed.
Example
TypeScript1const sandbox = await box.getSandbox("sb_01h…");2console.log(sandbox.status);
getSandboxByIP
TypeScript1getSandboxByIP(ip: string, options?: RequestOptions): Promise<Sandbox>
Connects to an existing sandbox by its VM private IP.
Parameters
| Name | Type | Description |
|---|---|---|
ip | string | VM private IP address (e.g. 10.0.0.42). |
options | RequestOptions | Per-request overrides. |
Returns Promise<Sandbox>
Throws
CreateosSandboxNotFoundError— no sandbox with that IP exists.CreateosSandboxAuthError— API key missing or revoked.CreateosSandboxPermissionError— sandbox belongs to another tenant.CreateosSandboxTimeoutError— per-request timeout elapsed.
Example
TypeScript1const sandbox = await box.getSandboxByIP("10.0.0.42");2console.log(sandbox.id);
listSandboxes
TypeScript1listSandboxes(options?: ListSandboxesOptions): Promise<Sandbox[]>
Lists the caller's sandboxes as connected Sandbox handles.
Walks every page by default (server caps pages at 500 items). Pass limit to
cap the total number of handles returned.
Parameters (ListSandboxesOptions) extends RequestOptions.
| Field | Type | Description |
|---|---|---|
limit | number | Cap on the total handles returned. Omit to fetch every page. |
status | "running" | "creating" | "destroyed" | "failed" | Filter to one lifecycle state. |
Returns Promise<Sandbox[]>
Throws
CreateosSandboxAuthError— API key missing or revoked.CreateosSandboxTimeoutError— per-request timeout elapsed.
Example
TypeScript1const running = await box.listSandboxes({ status: "running" });2for (const s of running) console.log(s.id, s.ip);
iterateSandboxes
TypeScript1iterateSandboxes(options?: ListSandboxesOptions): AsyncGenerator<Sandbox>
Streams the caller's sandboxes as connected handles, fetching one page at a
time. Prefer over listSandboxes when the list may be large and you want to
start processing before every page is fetched.
Accepts the same ListSandboxesOptions as listSandboxes.
Returns AsyncGenerator<Sandbox>
Example
TypeScript1for await (const s of box.iterateSandboxes({ status: "running" })) {2 console.log(s.id, s.ip);3}
Catalog & identity
whoami
TypeScript1whoami(options?: RequestOptions): Promise<WhoAmIView>
Returns the identity associated with the configured API key.
Returns Promise<WhoAmIView> — { user_id: string; stats: WhoAmIStatsView }.
Throws
CreateosSandboxAuthError— API key missing or revoked.CreateosSandboxTimeoutError— per-request timeout elapsed.
Example
TypeScript1const me = await box.whoami();2console.log(me.user_id, me.stats.running);
listShapes
TypeScript1listShapes(options?: RequestOptions): Promise<Shape[]>
Lists the available sandbox shapes (vCPU / RAM / disk presets). Unauthenticated — no API key required.
Returns Promise<Shape[]> — each Shape has id, vcpu, mem_mib,
default_disk_mib, and optional cpu_quota_pct. See
Shape for the full type.
Throws
CreateosSandboxTimeoutError— per-request timeout elapsed.
Example
TypeScript1const shapes = await box.listShapes();2console.log(shapes.map((s) => `${s.id}: ${s.vcpu} vCPU, ${s.mem_mib} MiB`));
listRootfs
TypeScript1listRootfs(options?: RequestOptions): Promise<RootfsData>
Lists the catalog of built-in rootfs images. Unauthenticated. The response
carries the default name used when a create request omits rootfs, a plain
rootfs string array of valid names, and optional rich entries metadata.
Returns Promise<RootfsData> — { rootfs: string[]; default: string; entries?: RootfsEntry[] }.
Throws
CreateosSandboxTimeoutError— per-request timeout elapsed.
Example
TypeScript1const catalog = await box.listRootfs();2console.log("default rootfs:", catalog.default);3console.log("available:", catalog.rootfs);
listHosts
TypeScript1listHosts(options?: RequestOptions): Promise<HostPublic[]>
Lists the worker hosts visible to the caller. Walks every page.
Returns Promise<HostPublic[]> — each entry has id, status
("active" | "draining" | "dead"), free_mib, vm_count, and optional
rootfses.
Throws
CreateosSandboxAuthError— API key missing or revoked.CreateosSandboxPermissionError— caller cannot enumerate hosts.CreateosSandboxTimeoutError— per-request timeout elapsed.
Example
TypeScript1const hosts = await box.listHosts();2console.log(hosts.map((h) => `${h.id}: ${h.free_mib} MiB free`));
iterateHosts
TypeScript1iterateHosts(options?: RequestOptions): AsyncGenerator<HostPublic>
Streams worker hosts one page at a time. Prefer over listHosts for large
fleets.
Returns AsyncGenerator<HostPublic>
Example
TypeScript1for await (const h of box.iterateHosts()) console.log(h.id, h.status);
healthz
TypeScript1healthz(options?: RequestOptions): Promise<HealthzResponse>
Liveness probe. Unauthenticated. Returns { up: true } once the control plane is
accepting traffic. Does not check database or scheduler readiness — use
readyz for that.
Returns Promise<HealthzResponse> — { up: boolean }.
Throws
CreateosSandboxTimeoutError— per-request timeout elapsed.
Example
TypeScript1const { up } = await box.healthz();2console.log("live:", up);
readyz
TypeScript1readyz(options?: RequestOptions): Promise<ReadyzResponse>
Readiness probe. Unauthenticated. Returns { ready: false, reason } instead of
throwing when the server responds 503 — callers can distinguish "not ready yet"
from a real error without catching. Retries are disabled for this call.
Returns Promise<ReadyzResponse> — { ready: boolean; reason?: string; scheduler_last_ok_ms_ago?: number }.
Throws
CreateosSandboxTimeoutError— per-request timeout elapsed.CreateosSandboxServerError— any non-503error response.
Example
TypeScript1const r = await box.readyz();2if (!r.ready) {3 console.warn("control plane not ready:", r.reason);4}
Per-request options (RequestOptions)
Every method accepts an optional RequestOptions object as its last argument.
These override the client-level defaults for that single call.
| Field | Type | Description |
|---|---|---|
signal | AbortSignal | Cancel the request (and any in-flight retry backoff). |
headers | HeadersInit | Headers merged into this request, overriding client defaults. |
timeoutMs | number | Per-request timeout in ms, overriding the client default. 0 disables it. |
retry | RetryOptions | false | Retry policy for this request, overriding the client default. |
Example — cancel a slow list
TypeScript1const controller = new AbortController();2setTimeout(() => controller.abort(), 5_000);34const sandboxes = await box.listSandboxes({ signal: controller.signal });
Sub-APIs
The client exposes three sub-API objects for operations on named resources:
| Accessor | Purpose |
|---|---|
box.templates | Build and manage custom rootfs images (Dockerfiles). |
box.networks | Create and manage overlay networks. |
box.disks | Register and manage S3-backed disk volumes. |
Full method reference: Sub-APIs.