NodeOps
UK

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 with CREATEOS_SANDBOX_BASE_URL
  • Auth: API key via the apiKey option or CREATEOS_SANDBOX_API_KEY

Construction

TypeScript
1import { CreateosSandboxClient, createClient } from "@nodeops-createos/sandbox";
2
3// Read credentials from environment variables
4const box = new CreateosSandboxClient();
5
6// Explicit options
7const box = new CreateosSandboxClient({
8 baseUrl: "https://api.sb.createos.sh",
9 apiKey: process.env.CREATEOS_SANDBOX_API_KEY,
10});
11
12// Factory alias — identical behaviour
13const box = createClient({ baseUrl: "https://api.sb.createos.sh" });

new CreateosSandboxClient(options?)

TypeScript
1new 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

NameTypeDefaultDescription
baseUrlstringCREATEOS_SANDBOX_BASE_URL env var, then the production defaultControl-plane base URL. Defaults to the production control plane when absent from both options and env.
apiKeystringCREATEOS_SANDBOX_API_KEY env varAPI key sent as X-Api-Key. Mutually exclusive with authHeaders.
authHeadersHeadersInitAuth headers used instead of an API key (e.g. a session token). Mutually exclusive with apiKey.
timeoutMsnumber60000Per-request timeout in ms. 0 disables it.
retryRetryOptions | false2 retries, 500 ms base, 30 s ceilingExponential-backoff retry policy, or false to disable retries entirely.
headersHeadersInitHeaders merged into every outgoing request.
hooksClientHooksLifecycle hooks for zero-dependency observability. Payloads are pre-redacted — credentials never reach a hook.
fetchtypeof fetchglobalThis.fetchCustom fetch implementation.
userAgentstringSDK defaultOverrides the User-Agent header.

Env-var resolution order — explicit option wins, then environment variable, then the built-in default.

retry shape (RetryOptions):

FieldDefaultDescription
maxRetries2Extra attempts after the first (3 total).
baseDelayMs500Base backoff delay in ms.
maxDelayMs30000Backoff 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):

TypeScript
1interface 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?)

TypeScript
1function createClient(options?: CreateosSandboxClientOptions): CreateosSandboxClient

Convenience factory. Equivalent to new CreateosSandboxClient(options).

Example

TypeScript
1import { createClient } from "@nodeops-createos/sandbox";
2
3const box = createClient({ apiKey: process.env.CREATEOS_SANDBOX_API_KEY });

Accessors

AccessorTypeDescription
box.httpCreateosSandboxHttpLow-level transport. Escape hatch for requests the SDK does not model. See helpers.
box.baseUrlstringResolved base URL (read-only).
box.templatesTemplatesApiTemplate (custom rootfs) operations. See sub-APIs.
box.networksNetworksApiOverlay network operations. See sub-APIs.
box.disksDisksApiS3-disk catalog operations. See sub-APIs.

Sandbox factory

createSandbox

TypeScript
1createSandbox(
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

FieldTypeRequiredDescription
shapestringYesShape id from listShapes() — e.g. s-4vcpu-4gb.
rootfsstringRootfs catalog name or template id/name. Omit for the host default.
namestringUser-facing VM name, unique per user. Auto-generated when omitted.
networksNetworkEntry[]Overlay networks to join at create time.
disk_mibnumberOverlay disk size in MiB. 0 or omit for the shape default.
egressstring[]Egress allowlist. [] or ["*"] allows all.
envsRecord<string, string>Env vars injected into every command inside the VM.
ssh_pubkeysstring[]OpenSSH public keys authorized for the SSH gateway.
host_idstringPin to a specific host id.
regionstringPin to a region. Must equal the server's configured region — cross-region routing is not supported.
auto_pause_after_secondsnumberIdle auto-pause timeout in seconds (range 60–86400). Omit to disable.

bandwidth_quota_bytes is not settable at create time — the server rejects a non-zero value. Grow bandwidth post-create with Sandbox.rechargeBandwidth().

CreateSandboxOptions fields

Extends RequestOptions.

FieldTypeDefaultDescription
waitbooleantrueWait until the sandbox reaches running. Set false to return early.
waitTimeoutMsnumber120000Budget for the wait poll, in ms.

Throws

Example

TypeScript
1import { CreateosSandboxClient } from "@nodeops-createos/sandbox";
2
3const 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

TypeScript
1getSandbox(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

NameTypeDescription
idstringSandbox id (e.g. sb_01h…).
optionsRequestOptionsPer-request overrides.

Returns Promise<Sandbox>

Throws

Example

TypeScript
1const sandbox = await box.getSandbox("sb_01h…");
2console.log(sandbox.status);

getSandboxByIP

TypeScript
1getSandboxByIP(ip: string, options?: RequestOptions): Promise<Sandbox>

Connects to an existing sandbox by its VM private IP.

Parameters

NameTypeDescription
ipstringVM private IP address (e.g. 10.0.0.42).
optionsRequestOptionsPer-request overrides.

Returns Promise<Sandbox>

Throws

Example

TypeScript
1const sandbox = await box.getSandboxByIP("10.0.0.42");
2console.log(sandbox.id);

listSandboxes

TypeScript
1listSandboxes(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.

FieldTypeDescription
limitnumberCap on the total handles returned. Omit to fetch every page.
status"running" | "creating" | "destroyed" | "failed"Filter to one lifecycle state.

Returns Promise<Sandbox[]>

Throws

Example

TypeScript
1const running = await box.listSandboxes({ status: "running" });
2for (const s of running) console.log(s.id, s.ip);

iterateSandboxes

TypeScript
1iterateSandboxes(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

TypeScript
1for await (const s of box.iterateSandboxes({ status: "running" })) {
2 console.log(s.id, s.ip);
3}

Catalog & identity

whoami

TypeScript
1whoami(options?: RequestOptions): Promise<WhoAmIView>

Returns the identity associated with the configured API key.

Returns Promise<WhoAmIView>{ user_id: string; stats: WhoAmIStatsView }.

Throws

Example

TypeScript
1const me = await box.whoami();
2console.log(me.user_id, me.stats.running);

listShapes

TypeScript
1listShapes(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

Example

TypeScript
1const shapes = await box.listShapes();
2console.log(shapes.map((s) => `${s.id}: ${s.vcpu} vCPU, ${s.mem_mib} MiB`));

listRootfs

TypeScript
1listRootfs(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

Example

TypeScript
1const catalog = await box.listRootfs();
2console.log("default rootfs:", catalog.default);
3console.log("available:", catalog.rootfs);

listHosts

TypeScript
1listHosts(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

Example

TypeScript
1const hosts = await box.listHosts();
2console.log(hosts.map((h) => `${h.id}: ${h.free_mib} MiB free`));

iterateHosts

TypeScript
1iterateHosts(options?: RequestOptions): AsyncGenerator<HostPublic>

Streams worker hosts one page at a time. Prefer over listHosts for large fleets.

Returns AsyncGenerator<HostPublic>

Example

TypeScript
1for await (const h of box.iterateHosts()) console.log(h.id, h.status);

healthz

TypeScript
1healthz(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

Example

TypeScript
1const { up } = await box.healthz();
2console.log("live:", up);

readyz

TypeScript
1readyz(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

Example

TypeScript
1const 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.

FieldTypeDescription
signalAbortSignalCancel the request (and any in-flight retry backoff).
headersHeadersInitHeaders merged into this request, overriding client defaults.
timeoutMsnumberPer-request timeout in ms, overriding the client default. 0 disables it.
retryRetryOptions | falseRetry policy for this request, overriding the client default.

Example — cancel a slow list

TypeScript
1const controller = new AbortController();
2setTimeout(() => controller.abort(), 5_000);
3
4const sandboxes = await box.listSandboxes({ signal: controller.signal });

Sub-APIs

The client exposes three sub-API objects for operations on named resources:

AccessorPurpose
box.templatesBuild and manage custom rootfs images (Dockerfiles).
box.networksCreate and manage overlay networks.
box.disksRegister and manage S3-backed disk volumes.

Full method reference: Sub-APIs.


See also

  • Sandbox — per-sandbox operations returned by factory methods above.
  • Sub-APIsTemplatesApi, NetworksApi, DisksApi.
  • Errors — full error class hierarchy.
  • Types — wire type reference.
  • HelpersCreateosSandboxHttp transport (accessed via box.http).

100,000+ Builders. One Workspace.

Get product updates, builder stories, and early access to features that help you ship faster.

CreateOS is a unified intelligent workspace where ideas move seamlessly from concept to live deployment, eliminating context-switching across tools, infrastructure, and workflows with the opportunity to monetize ideas immediately on the CreateOS Marketplace.