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
import { createClient } from "@nodeops-createos/sandbox";
// Read credentials from environment variables
const box = createClient();
// Explicit options
const box = createClient({
baseUrl: "https://api.sb.createos.sh",
apiKey: process.env.CREATEOS_SANDBOX_API_KEY,
});createClient is the recommended entry point. CreateosSandboxClient is the
underlying class it wraps: createClient(options) is exactly
new CreateosSandboxClient(options). Reach for the class directly only when you
need to subclass it or reference it as a type.
new CreateosSandboxClient(options?)
new CreateosSandboxClient(options: CreateosSandboxClientOptions = {}): CreateosSandboxClientResolves 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, so 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):
interface ClientHooks {
onRequest?: (ctx: RequestHookContext) => void | Promise<void>;
onResponse?: (ctx: ResponseHookContext) => void | Promise<void>;
onRetry?: (ctx: RetryHookContext) => void | Promise<void>;
}If a hook returns a promise it adds its own latency to the call, so 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?)
function createClient(
options?: CreateosSandboxClientOptions,
): CreateosSandboxClient;Convenience factory. Equivalent to new CreateosSandboxClient(options).
Example
import { createClient } from "@nodeops-createos/sandbox";
const 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
createSandbox(
request: CreateSandboxRequest,
options?: CreateSandboxOptions,
): 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
import { createClient } from "@nodeops-createos/sandbox";
const box = createClient();
const sandbox = await box.createSandbox({
shape: "s-4vcpu-4gb",
rootfs: "devbox:1",
envs: { CI: "1" },
});
try {
const { result } = await sandbox.runCommand("bash", ["-c", "echo hello"]);
console.log(result.stdout);
} finally {
await sandbox.destroy();
}getSandbox
getSandbox(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
const sandbox = await box.getSandbox("sb-01h…");
console.log(sandbox.status);getSandboxByIP
getSandboxByIP(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
const sandbox = await box.getSandboxByIP("10.0.0.42");
console.log(sandbox.id);listSandboxes
listSandboxes(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
const running = await box.listSandboxes({ status: "running" });
for (const s of running) console.log(s.id, s.ip);iterateSandboxes
iterateSandboxes(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
for await (const s of box.iterateSandboxes({ status: "running" })) {
console.log(s.id, s.ip);
}Catalog & identity
whoami
whoami(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
const me = await box.whoami();
console.log(me.user_id, me.stats.running);listShapes
listShapes(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
const shapes = await box.listShapes();
console.log(shapes.map((s) => `${s.id}: ${s.vcpu} vCPU, ${s.mem_mib} MiB`));listRootfs
listRootfs(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
const catalog = await box.listRootfs();
console.log("default rootfs:", catalog.default);
console.log("available:", catalog.rootfs);listHosts
listHosts(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
const hosts = await box.listHosts();
console.log(hosts.map((h) => `${h.id}: ${h.free_mib} MiB free`));iterateHosts
iterateHosts(options?: RequestOptions): AsyncGenerator<HostPublic>Streams worker hosts one page at a time. Prefer over listHosts for large
fleets.
Returns AsyncGenerator<HostPublic>
Example
for await (const h of box.iterateHosts()) console.log(h.id, h.status);healthz
healthz(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
const { up } = await box.healthz();
console.log("live:", up);readyz
readyz(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
const r = await box.readyz();
if (!r.ready) {
console.warn("control plane not ready:", r.reason);
}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
const controller = new AbortController();
setTimeout(() => controller.abort(), 5_000);
const 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.
See also
Sandbox: per-sandbox operations returned by factory methods above.- Sub-APIs:
TemplatesApi,NetworksApi,DisksApi. - Errors: full error class hierarchy.
- Types: wire type reference.
- Helpers:
CreateosSandboxHttptransport (accessed viabox.http).