Skip to main content

TypeScript API Reference

Sandbox class

Static methods

Sandbox.create(options?, config?)

Creates a new sandbox and waits until it is running.

static async create(
options?: SandboxCreateOptions,
config?: SandboxConfig
): Promise<Sandbox>

SandboxCreateOptions

PropertyTypeDefaultDescription
flavorSandboxFlavor'python-3.12'Environment preset
memorynumber512Memory in MB (max 8192)
cpunumber1vCPU count (max 4)
ttlnumber60Lifetime in minutes (max 480)
metadataRecord<string, string>Arbitrary key-value tags

SandboxConfig

PropertyTypeDefaultDescription
apiKeystringCODECAPSULES_API_KEY env varAPI key
baseUrlstringhttps://sandbox.codecapsules.io/v1API base URL
timeoutnumber30_000Request timeout in ms
maxRetriesnumber2Retries on transient errors
const sb = await Sandbox.create({ flavor: 'node-20', memory: 1024 });

Sandbox.using(fn, options?, config?)

Creates a sandbox, passes it to fn, and deletes it when done, even if fn throws.

static async using<T>(
fn: (sb: Sandbox) => Promise<T>,
options?: SandboxCreateOptions,
config?: SandboxConfig
): Promise<T>
const result = await Sandbox.using(async (sb) => {
const r = await sb.exec('python -c "print(42)"');
return r.stdout.trim(); // "42"
}, { flavor: 'python-3.12' });

Sandbox.get(id, config?)

Fetch an existing sandbox by ID.

static async get(id: string, config?: SandboxConfig): Promise<Sandbox>
const sb = await Sandbox.get('sb_01hx...');
console.log(sb.status); // 'running'

Instance properties

PropertyTypeDescription
idstringUnique sandbox ID (e.g. sb_01hx...)
flavorstringEnvironment flavor (e.g. python-3.12)
statusSandboxStatusLast known status (call refresh() for a live value)
expiresAtDateWhen the sandbox will be automatically deleted
infoReadonly<SandboxInfo>Full sandbox info snapshot

Instance methods

sb.exec(command, options?)

Execute a shell command and wait for it to complete.

async exec(command: string, options?: ExecOptions): Promise<ExecResult>

ExecOptions

PropertyTypeDefaultDescription
stdinstringContent written to stdin
timeoutnumber30Timeout in seconds (max 300)
envRecord<string, string>Additional environment variables

ExecResult

PropertyTypeDescription
stdoutstringStandard output
stderrstringStandard error
exitCodenumberExit code (0 = success)
durationMsnumberWall-clock time in milliseconds
execIdstringUnique execution ID
commandstringThe command that was run
startedAtDateExecution start time
completedAtDateExecution end time
const r = await sb.exec('python --version');
console.log(r.stdout); // "Python 3.12.3\n"
console.log(r.exitCode); // 0

// With options
const r2 = await sb.exec('pip install numpy', { timeout: 120 });
const r3 = await sb.exec('echo $FOO', { env: { FOO: 'bar' } });

sb.execStream(command, options?)

Execute a command and stream output as it arrives. Yields chunks of stdout and stderr interleaved.

execStream(command: string, options?: ExecOptions): AsyncIterable<string>

The default timeout for streaming is 300 seconds.

for await (const chunk of sb.execStream('python train.py')) {
process.stdout.write(chunk);
}

sb.upload(sandboxPath, content)

Upload content to a path inside the sandbox.

async upload(
sandboxPath: string,
content: Buffer | Uint8Array | string
): Promise<FileInfo>

FileInfo

PropertyTypeDescription
pathstringPath inside the sandbox
sizeBytesnumberFile size in bytes
createdAtDateUpload time
import { readFileSync } from 'fs';

await sb.upload('/workspace/script.py', readFileSync('./script.py'));
await sb.upload('/workspace/config.json', JSON.stringify({ key: 'value' }));

sb.download(sandboxPath)

Download a file from the sandbox as a Uint8Array.

async download(sandboxPath: string): Promise<Uint8Array>
const bytes = await sb.download('/workspace/output.json');
const result = JSON.parse(Buffer.from(bytes).toString());

sb.logs(options?)

Fetch sandbox logs: system events and exec output.

async logs(options?: LogsOptions): Promise<LogEntry[]>

LogsOptions

PropertyTypeDefaultDescription
sinceDateOnly return entries after this timestamp
limitnumber100Max entries (max 1000)

LogEntry

PropertyTypeDescription
tsDateTimestamp
source'system' | 'exec'Log source
messagestringLog message
execIdstring | undefinedAssociated exec ID
const entries = await sb.logs({ limit: 50 });
entries.forEach(e => console.log(`[${e.source}] ${e.message}`));

sb.metrics()

Get live resource usage for the sandbox.

async metrics(): Promise<SandboxMetrics>

SandboxMetrics

PropertyTypeDescription
cpuPercentnumberCPU usage percentage
memoryUsedMbnumberMemory used in MB
memoryLimitMbnumberMemory limit in MB
diskUsedMbnumberDisk used in MB
diskLimitMbnumberDisk limit in MB
execCountnumberNumber of exec calls
uptimeSecondsnumberSandbox uptime
const m = await sb.metrics();
console.log(`CPU: ${m.cpuPercent}%, RAM: ${m.memoryUsedMb}/${m.memoryLimitMb}MB`);

sb.refresh()

Re-fetch sandbox info from the API and update status and other cached properties.

async refresh(): Promise<this>

sb.waitUntilRunning(options?)

Poll until status === 'running', then return. Rarely needed; create() already waits.

async waitUntilRunning(options?: { timeout?: number; interval?: number }): Promise<this>

sb.stop()

Gracefully stop the sandbox. Transitions to 'stopped'. The sandbox can no longer accept exec calls but is not deleted; it still counts against your quota until deleted.

async stop(): Promise<void>

sb.delete()

Delete the sandbox and release all resources immediately.

async delete(): Promise<void>

Types

SandboxFlavor

type SandboxFlavor = 'python-3.12' | 'node-20' | 'browser' | 'full' | (string & {});

The (string & {}) union allows arbitrary flavor strings for future environments while preserving autocomplete for the built-in values.

SandboxStatus

type SandboxStatus = 'starting' | 'running' | 'stopping' | 'stopped' | 'error';

Error classes

All errors extend SandboxError.

ClassWhen thrown
SandboxAuthErrorInvalid or missing API key
SandboxNotFoundErrorSandbox ID not found
SandboxNotReadyErrorSandbox is in error state or timed out waiting to start
SandboxExecTimeoutErrorexec() exceeded the timeout
SandboxRateLimitErrorToo many requests
SandboxQuotaErrorAccount quota exceeded
SandboxAPIErrorUnexpected API error (includes HTTP status and response body)
SandboxRequestTimeoutErrorHTTP request timed out
import { Sandbox, SandboxExecTimeoutError, SandboxAuthError } from '@codecapsules/sandbox';

try {
await Sandbox.using(async (sb) => {
await sb.exec('sleep 999', { timeout: 5 });
});
} catch (err) {
if (err instanceof SandboxExecTimeoutError) {
console.log('Command timed out');
}
}