NodeOps
UK

Types

All types in this file mirror the createos-sandbox control-plane JSON HTTP API. Fields use the server's snake_case names so JSON parses without translation. When the server uses omitempty on a field, the TypeScript field is marked optional (?): the key is absent from the wire payload rather than sent as null. List endpoints return a doubly-nested pagination envelope { data: { data: [...], pagination: { total, limit, offset, count } } }; rootfs is the lone exception (a plain view). The server clamps limit to 500; drive paging from the reported total, not the requested page size. Every type here is re-exported via export * from "./types.js" in index.ts, making the entire surface public.

See also: Client · Sandbox · Sub-APIs


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

JSend envelope

The control plane wraps every response in one of three JSend shapes. The SDK unwraps these transparently; consumers only see them when using the raw CreateosSandboxHttp transport directly.

TypeScript
1export interface SuccessEnvelope<T> {
2 status: "success";
3 data: T;
4}
5
6export interface FailEnvelope {
7 status: "fail";
8 /** Field-keyed object or plain string depending on the endpoint. */
9 data: Record<string, unknown> | string;
10}
11
12export interface ErrorEnvelope {
13 status: "error";
14 message: string;
15 code: number;
16}
17
18export type JSendEnvelope<T> = SuccessEnvelope<T> | FailEnvelope | ErrorEnvelope;

Client & request options

RetryOptions

Exponential-backoff retry policy. Omit a field to keep its default.

TypeScript
1export interface RetryOptions {
2 maxRetries?: number; // Extra attempts after the first. Default 2 (3 total).
3 baseDelayMs?: number; // Base backoff delay in ms. Default 500.
4 maxDelayMs?: number; // Backoff ceiling in ms. Default 30000.
5}

RetryReason

TypeScript
1export type RetryReason = "network" | "status" | "rate-limit";

RequestHookContext

Delivered to ClientHooks.onRequest. All credentials are pre-redacted.

FieldTypeNotes
urlstringURL with userinfo stripped and sensitive query params redacted
methodstringUppercase HTTP method
headersRecord<string, string>Credentials replaced by "redacted"
attemptnumber1 for first try, 2+ for retries

ResponseHookContext

Extends RequestHookContext.

FieldTypeNotes
statusnumberHTTP status code
durationMsnumberElapsed time for the fetch call, in ms
requestIdstring | undefinedServer-supplied request id, when present

RetryHookContext

Extends Omit<ResponseHookContext, "status">.

FieldTypeNotes
statusnumber | undefinedHTTP status, or undefined for network errors
reasonRetryReasonWhy the SDK is retrying
delayMsnumberSleep time before next attempt

ClientHooks

Optional lifecycle hooks for zero-dep observability. Every payload is pre-redacted. Throws inside a hook are swallowed. Hooks are awaited in the request path; keep hook work cheap or dispatch slow work without returning the promise.

TypeScript
1export interface ClientHooks {
2 onRequest?: (ctx: RequestHookContext) => void | Promise<void>;
3 onResponse?: (ctx: ResponseHookContext) => void | Promise<void>;
4 onRetry?: (ctx: RetryHookContext) => void | Promise<void>;
5}

CreateosSandboxClientOptions

Construction options for CreateosSandboxClient. All fields are optional.

FieldTypeNotes
apiKeystring?Sent as X-Api-Key. Falls back to CREATEOS_SANDBOX_API_KEY env var
authHeadersHeadersInit?Auth headers used instead of an API key
baseUrlstring?Control-plane base URL. Falls back to CREATEOS_SANDBOX_BASE_URL, then https://api.sb.createos.sh
fetchtypeof fetch?Custom fetch implementation (useful in tests)
timeoutMsnumber?Per-request timeout in ms. Default 60000. 0 disables
retryRetryOptions | false?Retry policy, or false to disable retries entirely
userAgentstring?Overrides the User-Agent header
hooksClientHooks?Lifecycle hooks for observability

RequestOptions

Per-call overrides accepted by every SDK method.

FieldTypeNotes
signalAbortSignal?Cancel the request and any in-flight retry backoff
headersHeadersInit?Merged into this request, overriding client defaults
timeoutMsnumber?Per-request timeout in ms, overrides client default
retryRetryOptions | false?Retry policy for this request, overrides client default

ExecOptions

TypeScript
1export type ExecOptions = RequestOptions;

Alias for RequestOptions; passed to Sandbox.runCommand and Sandbox.streamCommand.


Catalog & identity

Shape

A sandbox sizing preset. Returned by listShapes().

FieldTypeNotes
idstringShape id passed as CreateSandboxRequest.shape, e.g. s-1vcpu-256mb
vcpunumberVirtual CPU count
mem_mibnumberMemory in MiB
default_disk_mibnumberDefault overlay disk size when the create request omits disk_mib
cpu_quota_pctnumber?cgroup v2 cpu.max quota as a percent of one CPU; absent = unlimited

RootfsEntry

Metadata for one built-in rootfs image in the catalog.

FieldTypeNotes
namestringCatalog name
descriptionstring?Human-readable description
deprecatedboolean?True when this image is being retired
successorstring?Recommended replacement when this image is deprecated

RootfsData

TypeScript
1export interface RootfsData {
2 /** Available rootfs catalog names usable as `CreateSandboxRequest.rootfs`. */
3 rootfs: string[];
4 /** Name used when a create request omits `rootfs`. */
5 default: string;
6 /** Rich per-rootfs metadata; absent when the catalog is empty. */
7 entries?: RootfsEntry[];
8}

Response from listRootfs(). entries is absent when the catalog is empty. This endpoint returns a plain view, not the paginated envelope used by all other list routes.

HostStatus

TypeScript
1export type HostStatus = "active" | "draining" | "dead";

Scheduling state of a worker host.

HostPublic

A worker host visible to the caller. Returned by listHosts().

FieldTypeNotes
idstring
statusHostStatus
free_mibnumberSchedulable memory currently free, in MiB
vm_countnumberSandboxes currently placed on the host
rootfsesstring[]?Rootfs images cached on the host; absent (omitempty) when none

WhoAmIStatsView

Per-state sandbox counts for the calling identity.

FieldTypeNotes
runningnumberSandboxes currently running
pausednumberSandboxes currently paused
othernumberSandboxes in any other state
totalnumberTotal non-destroyed sandboxes

WhoAmIView

Identity behind the configured API key. Returned by whoami().

FieldTypeNotes
user_idstringStable id of the authenticated user
statsWhoAmIStatsViewSandbox counts grouped by lifecycle state

Sandbox

NetworkEntry

References an overlay network by id in CreateSandboxRequest.networks.

TypeScript
1export interface NetworkEntry {
2 id: string;
3}

CreateSandboxRequest

Body of POST /v1/sandboxes. Only shape is required.

Note: bandwidth_quota_bytes is not settable at create time; the server returns 400 for any non-zero value. Grow the quota post-create with Sandbox.rechargeBandwidth().

node_selector and ingress_* fields are not described in the published OpenAPI spec; verify against the live API.

FieldTypeNotes
shapestringRequired. A shape id from listShapes()
rootfsstring?Rootfs catalog name or template id/name; empty = host default
namestring?User-facing VM name, unique per user; empty = auto-generated
networksNetworkEntry[]?Overlay networks to join at create time
disk_mibnumber?Overlay disk size in MiB; 0 = shape default
egressstring[]?Egress allowlist; empty / ["*"] = allow all
envsRecord<string, string>?Env vars injected into every command inside the VM
ssh_pubkeysstring[]?OpenSSH public keys authorized for the SSH gateway
host_idstring?Pin placement to a specific host id; empty = scheduler picks
node_selectorRecord<string, string>?Scheduler placement labels (k8s NodeSelector semantics)
ingress_enabledboolean?Opt the sandbox into HTTP ingress at create time
disksDiskAttachment[]?Disks to mount into the VM at boot
regionstring?Pin to a region; must equal the server's region (no cross-region routing)
auto_pause_after_secondsnumber?Idle auto-pause timeout in seconds (60-86400)
start_pausedboolean?If true, the sandbox boots into paused state

CreateSandboxResponse

Result of POST /v1/sandboxes, returned before the SDK fetches the full SandboxView. Records the resolved placement and boot timing.

FieldTypeNotes
idstring
namestring
ipstringThe VM's private IP
shapestring
rootfsstring
vcpunumber
mem_mibnumberMemory in MiB
disk_mibnumberOverlay disk size in MiB
spawn_msnumberWall-clock time to boot the VM, in ms
egressstring[]Resolved egress allowlist
bandwidth_quota_bytesnumberTransferable byte quota; -1 = unmetered
ingress_url_templatestring?Ingress URL template with literal <port> placeholder; set when ingress is on

SandboxStatus

Lifecycle state of a sandbox. Transitional states (pausing, resuming, forking, creating, destroying) settle into a steady or terminal one.

TypeScript
1export type SandboxStatus =
2 | "creating"
3 | "running"
4 | "pausing"
5 | "paused"
6 | "resuming"
7 | "forking"
8 | "error"
9 | "destroying"
10 | "destroyed"
11 | "failed";

SandboxView

Full server-side projection of a sandbox. Backs the Sandbox handle and is returned by get/list endpoints. Optional fields are omitted by the server (omitempty) rather than sent as null.

Wire drift: ingress_url_template is present on the SDK SandboxView but absent from the published OpenAPI SandboxView schema. Verify against the live API.

FieldTypeNotes
idstring
statusSandboxStatus
ipstring?Absent until the VM is assigned an address (omitted while creating)
vcpunumber
mem_mibnumberMemory in MiB
disk_mibnumberOverlay disk size in MiB
created_atstringRFC 3339 timestamp
ingress_enabledboolean
ingress_url_templatestring?Ingress URL template with <port> placeholder; set when ingress is on
namestring?
running_atstring?RFC 3339 timestamp of when the VM last reached running
destroyed_atstring?RFC 3339 timestamp of when the VM was destroyed
spawn_msnumber?Wall-clock boot time in ms
shapestring?
rootfsstring?
regionstring?
egressstring[]?
envsstring[]?Names of env vars stored on the sandbox; values are never returned
ssh_pubkeysstring[]?
created_bystring?Identity that created the sandbox
bandwidth_ingress_bytesnumber?Inbound bytes observed (never enforced)
paused_atstring?RFC 3339 timestamp of the last pause
last_resumed_atstring?RFC 3339 timestamp of the last resume
forked_fromstring?Source sandbox id when created via fork
auto_pause_after_secondsnumber?Idle auto-pause timeout in seconds; absent when auto-pause is disabled

ListSandboxesOptions

Extends RequestOptions.

FieldTypeNotes
limitnumber?Cap the number of handles returned; omit to fetch every page
status"running" | "creating" | "destroyed" | "failed"?Filter to one lifecycle state

ForkSandboxRequest

Optional overrides applied to a fork. Omitted fields inherit from the source.

FieldTypeNotes
start_pausedboolean?Keep the fork in paused instead of auto-resuming
ssh_pubkeysstring[]?
egressstring[]?
ingress_enabledboolean?
envsRecord<string, string>?
bandwidth_quota_bytesnumber?

PatchSandboxRequest

Body of the sandbox PATCH endpoint, used by Sandbox.setIngress and Sandbox.setAutoPause. Omitted fields are left unchanged.

FieldTypeNotes
ingress_enabledboolean?
auto_pause_after_secondsnumber?Idle auto-pause timeout in seconds (60-86400)
disable_auto_pauseboolean?When true, clears the auto-pause timeout; required because omitting auto_pause_after_seconds means "leave unchanged"

AddSSHPubkeysRequest

Body of Sandbox.addSSHPubkeys: keys to add to a live sandbox.

TypeScript
1export interface AddSSHPubkeysRequest {
2 /** OpenSSH-formatted public keys. Keys already present are de-duplicated. */
3 keys: string[];
4}

AddSSHPubkeysResponse

TypeScript
1export interface AddSSHPubkeysResponse {
2 /** Total `ssh_pubkeys` on the sandbox after the add. */
3 count: number;
4}

DestroyedResponse

TypeScript
1export interface DestroyedResponse {
2 /** Id of the sandbox accepted for destruction. */
3 id: string;
4 /** Status reached by the destroy call. `destroying` for an async reclaim;
5 * `destroyed` when the call was a no-op on an already terminal row or
6 * could be reclaimed inline (paused/error). */
7 status: Extract<SandboxStatus, "destroying" | "destroyed">;
8}

SetEgressRequest

TypeScript
1export interface SetEgressRequest {
2 /** `host:port` allow rules. `null`, omitted, or `[]` means allow all. */
3 egress?: string[] | null;
4}

EgressView

The sandbox's current egress allowlist. Returned by getEgress / setEgress.

TypeScript
1export interface EgressView {
2 id: string;
3 /** Active `host:port` allow rules. Empty = allow all. */
4 egress: string[];
5}

BandwidthView

Bandwidth quota and usage counters. Returned by getBandwidth / rechargeBandwidth.

FieldTypeNotes
idstring
quota_bytesnumberTotal transferable byte quota; -1 = unmetered
used_bytesnumberEgress bytes, billed against the quota
ingress_bytesnumberInbound bytes, observed, never enforced
remaining_bytesnumberBytes left before the VM is network-capped
cappedbooleantrue once the quota is exhausted and egress is blocked

RechargeBandwidthRequest

TypeScript
1export interface RechargeBandwidthRequest {
2 /** Bytes to add to the quota. */
3 add_bytes: number;
4}

ResizeSandboxRequest

TypeScript
1export interface ResizeSandboxRequest {
2 /** New overlay disk size in MiB. Must be larger than the current size. */
3 disk_mib: number;
4}

ResizeSandboxResponse

TypeScript
1export interface ResizeSandboxResponse {
2 /** Disk size in MiB after the grow. */
3 disk_mib: number;
4}

Command execution

ExecRequest

Wire request body for POST /v1/sandboxes/:id/exec.

FieldTypeNotes
cmdstringExecutable to run inside the guest. Not run through a shell; wrap in ["bash", "-c", "…"] for pipes, globbing, or redirection
argsstring[]?Arguments passed to cmd
streamboolean?Stream output as NDJSON frames instead of buffering. Set by streamCommand

ExecResult

Buffered output of a completed command. Returned by runCommand.

FieldTypeNotes
stdoutstringCaptured standard output
stderrstringCaptured standard error
exit_codenumberProcess exit code; 0 = success
errorstring?Agent-level failure (the command could not be started)

ExecResponse

Result of runCommand: the buffered output plus timing.

TypeScript
1export interface ExecResponse {
2 result: ExecResult;
3 /** Wall-clock time the command ran, in milliseconds. */
4 exec_ms: number;
5}

ExecStreamEvent

Discriminated union yielded by Sandbox.streamCommand. Switch on type to handle each kind of event; TypeScript narrows the payload.

TypeScript
1export type ExecStreamEvent =
2 | { type: "stdout"; data: string }
3 | { type: "stderr"; data: string }
4 | { type: "exit"; exitCode: number }
5 | { type: "error"; message: string }
6 | { type: "heartbeat" };

ExecStreamFrame

Raw NDJSON frame as emitted by the server. Exposed for advanced users who want to bypass the ExecStreamEvent projection (e.g. log forwarders that need the snake_case shape).

FieldTypeNotes
stdoutstring?
stderrstring?
exit_codenumber?
errorstring?
hbboolean?Heartbeat marker emitted every 5 s

Handle option types

CreateSandboxOptions

Extends RequestOptions. Passed to CreateosSandboxClient.createSandbox.

FieldTypeNotes
waitboolean?Wait until the sandbox reaches running before resolving; default true
waitTimeoutMsnumber?Budget for the wait in ms; default 120000

WaitOptions

Options for the Sandbox.waitUntil* pollers.

FieldTypeNotes
timeoutMsnumber?Wait budget in ms; default 120000
signalAbortSignal?Cancel the wait
requestRequestOptions?Per-request options applied to each poll refresh; timeoutMs here is the per-request transport timeout, not the overall wait budget

Templates

TemplateStatus

TypeScript
1export type TemplateStatus = "pending" | "building" | "ready" | "failed";

ready once the rootfs image is usable as a sandbox rootfs.

TemplateCreateRequest

Body of templates.create: a Dockerfile to build into a sandbox rootfs.

FieldTypeNotes
namestring
dockerfilestringDockerfile source built into the rootfs image
basestring?Base rootfs catalog name to build on top of; empty = host default

TemplateView

A custom rootfs template. Returned by the templates endpoints.

FieldTypeNotes
idstring
namestring
basestringBase rootfs the template was built on
statusTemplateStatus
ext4_size_bytesnumberSize of the built ext4 rootfs image, in bytes
created_atstringRFC 3339
built_atstring?RFC 3339; absent until ready
dockerfilestring?Present only on detail GET with include: "dockerfile"

GetTemplateOptions

Extends RequestOptions.

TypeScript
1export interface GetTemplateOptions extends RequestOptions {
2 /** Set to `"dockerfile"` to include the original build source in the response. */
3 include?: "dockerfile";
4}

TemplateLogEvent

One NDJSON line from a template build log stream.

FieldTypeNotes
tsstring?Timestamp
levelstring?Log level
linestring?Log line text
attemptnumber?Build attempt number
finalboolean?Terminal frame when true
statusstring?"ready" or "failed" in the terminal frame
[key]unknownAdditional arbitrary fields (index signature)

TemplateLogsOptions

Options for templates.logs / templates.followLogs. Extends RequestOptions.

TypeScript
1export interface TemplateLogsOptions extends RequestOptions {
2 /** Filter to one build attempt. Default = all attempts. */
3 attempt?: number;
4}

Disks

DiskKind

TypeScript
1export type DiskKind = "s3";

Storage backend for a registered disk. Only "s3" today (covers AWS S3, Cloudflare R2, MinIO, and any S3-compatible endpoint).

DiskConfig

Non-secret S3 disk configuration. Persisted server-side as JSON.

FieldTypeNotes
bucketstring
endpointstringS3-compatible endpoint URL
regionstring?
use_path_styleboolean?Force path-style addressing (endpoint/bucket/key) instead of virtual-hosted; needed for MinIO / R2 with custom domains

DiskCredentials

Bucket credentials. Sent only on create; AES-GCM-encrypted at rest and never returned by any read endpoint.

TypeScript
1export interface DiskCredentials {
2 access_key: string;
3 secret_key: string;
4}

DiskCreateRequest

Body of POST /v1/disks.

FieldTypeNotes
namestringUser-scoped name; must match ^[a-z0-9][a-z0-9-]{0,62}$
kindDiskKind
configDiskConfig
credentialsDiskCredentials

DiskView

User-facing projection of a registered disk. Credentials never appear here.

FieldTypeNotes
idstring
namestring
kindDiskKind
configDiskConfigServer returns this as a JSON blob; the SDK exposes it as parsed JSON
created_atstringRFC 3339

DiskMountStatus

TypeScript
1export type DiskMountStatus = "pending" | "mounted" | "error" | "unmounting";

DiskAttachment

One element of CreateSandboxRequest.disks or the body of the attach endpoint.

FieldTypeNotes
disk_idstringA disk_<ulid> id or the user-scoped disk name
mount_pathstringAbsolute path inside the guest, e.g. /mnt/data
sub_pathstring?Bucket sub-folder to expose at mount_path

SandboxDiskView

Per-attachment projection. Returned from GET /v1/sandboxes/:id/disks.

FieldTypeNotes
disk_idstringThe disk_<ulid> id of the registered disk
namestring
kindDiskKind
configDiskConfig
mount_pathstringAbsolute path inside the guest where the disk is mounted
sub_pathstring?Bucket sub-folder exposed at mount_path, when set
mount_statusDiskMountStatus
mount_errorstring?Failure detail when mount_status is "error"

AttachDiskOptions

Options for Sandbox.attachDisk.

FieldTypeNotes
diskIdstringA disk_<ulid> id or the user-scoped disk name
mountPathstringAbsolute path inside the guest, e.g. /mnt/data
subPathstring?Optional bucket sub-folder to expose at mountPath

Note: detachDisk requires the disk_<ulid> id, not the name.

DetachDiskOptions

Options for Sandbox.detachDisk.

FieldTypeNotes
diskIdstringA disk_<ulid> id or the user-scoped disk name
mountPathstringAbsolute path inside the guest where the disk is currently mounted; required because the same disk may be attached at multiple paths and the composite key is (sandbox, disk, mountPath)

DiskDeletedResponse

TypeScript
1export interface DiskDeletedResponse {
2 deleted: boolean;
3}

DiskDetachedResponse

TypeScript
1export interface DiskDetachedResponse {
2 detached: boolean;
3}

Networks

NetworkCreateRequest

TypeScript
1export interface NetworkCreateRequest {
2 name: string;
3}

NetworkMember

A sandbox attached to an overlay network, with its address on that network.

FieldTypeNotes
sandbox_idstring
statusstring
ipstring?The member's IP on this overlay network; absent until the membership is programmed
namestring?The member sandbox's user-facing name, when set

Network

An overlay network. Returned by the networks endpoints.

FieldTypeNotes
idstring
namestring
created_atstringRFC 3339
member_countnumber?Number of attached sandboxes; present on list responses
membersNetworkMember[]?Attached sandboxes with per-network addresses; present on detail GET

Misc / probe responses

OKResponse

Generic acknowledgement returned by endpoints with no richer payload.

TypeScript
1export interface OKResponse {
2 ok: boolean;
3}

HealthzResponse

Liveness probe result. Returned by healthz().

TypeScript
1export interface HealthzResponse {
2 /** True once the control plane process is up. */
3 up: boolean;
4}

ReadyzResponse

Readiness probe result. Returned by readyz().

TypeScript
1export interface ReadyzResponse {
2 /** True once the control plane is ready to serve traffic. */
3 ready: boolean;
4 /** Why the control plane is not ready, when `ready` is false. */
5 reason?: string;
6 /** Milliseconds since the scheduler last completed a healthy pass. */
7 scheduler_last_ok_ms_ago?: number;
8}

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.