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: node_selector, ingress_enabled, ingress_url_template, and ingress_bytes are absent from the published OpenAPI spec. 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_quota_bytesnumber?Transferable byte quota
ingress_bytesnumber?Inbound bytes observed (never enforced)
node_selectorRecord<string, string>?Scheduler placement labels
host_idstring?Host the sandbox is placed on
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 /** True when the sandbox was already terminal or was reclaimed inline. */
3 status: Extract<SandboxStatus, "destroying" | "destroyed" | "paused" | "error">;
4}

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; note that 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. See fc-sdk issue #70.

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.