Docs

API Reference

Get a handle with sandbox(name) from @alienplatform/sdk (TypeScript) or alien_bindings::Bindings::from_env()?.sandbox(name).await? (Rust). The Rust request and response types live in alien_bindings::traits.

Every sandbox uses the image, limits, and network rules declared in alien.ts. No call can override them.

An operation the platform does not support raises OPERATION_NOT_SUPPORTED. Check Platform Capabilities or call capabilities() before relying on anything beyond create, run, and terminate.

capabilities

Lists what this platform's backend supports.

const names: string[] = await box.capabilities()
if (names.includes("jobs")) { /* start a job */ }

Returns: TypeScript: the names of the supported capabilities. Rust: a SandboxCapabilities struct with one bool per capability. The TypeScript list never contains snapshot, because the TypeScript binding has no method for it.


create

Creates a sandbox and resolves once it can run a command.

create(options?: CreateSandboxOptions): Promise<SandboxInstance>

const created = await box.create()
ParameterTypeRequiredDescription
sandboxIdstringNoRequested id. Honored on Local and Kubernetes. AWS, Azure, and GCP allocate their own id and ignore this.
envRecord<string, string>NoEnvironment for every command. Azure only; AWS and GCP refuse it, Kubernetes and Local ignore it. Use env on runCommand for portable code.
tenantKeystringNoNot supported. AWS, Azure, and GCP refuse it; Kubernetes and Local ignore it.
timeoutMsnumberNoLifetime of this sandbox in milliseconds. AWS and GCP only. It can shorten the declared maxLifetimeSeconds, never extend it.

Returns: a SandboxInstance. Keep its sandboxId; every later call addresses the sandbox by it.

Errors: OPERATION_NOT_SUPPORTED for an option the platform refuses. SANDBOX_UNREACHABLE (AWS, GCP) or SANDBOX_COMMAND_FAILED (Azure) when the sandbox isn't ready in time. SANDBOX_NOT_AS_DECLARED (Azure) when it started without its egress policy; create a new one.


get

Fetches a sandbox by id. Requires reconnect.

get(sandboxId: string): Promise<SandboxInstance | null>

const found = await box.get(sandboxId)
ParameterTypeRequiredDescription
sandboxIdstringYesThe id create or getOrCreate returned.

Returns: the sandbox, or null / None if it doesn't exist. On Kubernetes, only the process that created a sandbox can get it.


getOrCreate

Fetches the sandbox named by sandboxId, or creates one if it does not exist, and reports which happened.

getOrCreate(options?: CreateSandboxOptions): Promise<ResolvedSandbox>

const { sandbox, created } = await box.getOrCreate({ sandboxId: savedId })

Takes the same options as create. timeoutMs bounds only a sandbox this call creates; a found sandbox keeps the lifetime it was created with.

Returns: { sandbox, created }. The call isn't atomic: two callers with the same id can both get created: true.


list

Lists the sandboxes of this Sandbox resource.

list(): Promise<SandboxInstance[]>

Returns: the sandboxes on GCP and Local. On Kubernetes, only the sandboxes the calling process created.

Errors: OPERATION_NOT_SUPPORTED on AWS and Azure. Reach a sandbox whose id you hold with get.


runCommand

Runs a command and streams its output.

runCommand(sandboxId: string, command: string, options: RunCommandOptions): AsyncIterable<CommandFrame>

for await (const frame of box.runCommand(sandboxId, "python3", {
  args: ["main.py"],
  timeoutMs: 60_000,
})) {
  if (frame.kind === "stdout") process.stdout.write(frame.data)
  if (frame.kind === "exit") console.log(frame.exitCode, frame.truncated)
}
ParameterTypeRequiredDescription
sandboxIdstringYesThe sandbox to run in.
commandstringYesThe program to run, without a shell. For a shell line, pass sh with args: ["-c", line].
options.timeoutMsnumberYesHow long the command may run. At most 24 hours on Azure and Local.
options.argsstring[]NoArguments, each passed as one argument.
options.cwdstringNoWorking directory inside the sandbox.
options.envRecord<string, string>NoEnvironment for this command, on top of the sandbox's own.

Returns: stdout and stderr frames with raw bytes, then one exit frame with the exit code. truncated is true when output hit the size cap. A non-zero exit code is not an error.

Errors: SANDBOX_COMMAND_FAILED when the command didn't finish, including a timeout. SANDBOX_OUTCOME_UNKNOWN when it was sent and may have run; don't repeat it. SANDBOX_UNREACHABLE when it was never sent; safe to retry.


startJob

Starts a command as a job that outlives this call. Requires jobs (AWS, GCP, Kubernetes).

startJob(sandboxId: string, command: string, options: RunCommandOptions): Promise<string>

const jobId = await box.startJob(sandboxId, "make", { args: ["test"], timeoutMs: 20 * 60_000 })

Takes the same parameters as runCommand.

Returns: the job id (JobStart { job_id } in Rust).

Errors: SANDBOX_OUTCOME_UNKNOWN when the job may have started; don't repeat it. A start is refused while 16 jobs are running.


pollJob

Reads a job's output after a sequence number, and how it ended once it has. Requires jobs.

pollJob(sandboxId: string, jobId: string, sinceSeq?: number): Promise<JobPoll>

const poll = await box.pollJob(sandboxId, jobId, lastSeq)
ParameterTypeRequiredDescription
sandboxIdstringYesThe sandbox the job runs in.
jobIdstringYesThe id startJob returned.
sinceSeqnumberNoReturn only frames after this seq. Omit to read from the first frame; afterwards pass the highest seq you have seen.

Returns: { running, frames, exit?, error? }. exit is set when the command exited, error when it ended another way, such as a timeout.

Errors: SANDBOX_UNREACHABLE is safe to retry.


cancelJob

Stops a job's command. Requires jobs.

cancelJob(sandboxId: string, jobId: string): Promise<void>

Errors: SANDBOX_UNREACHABLE is safe to retry.


readFile

Reads a file out of the sandbox. Requires files.

readFile(sandboxId: string, path: string): Promise<Buffer>

const report = await box.readFile(sandboxId, "work/report.json")
ParameterTypeRequiredDescription
sandboxIdstringYesThe sandbox to read from.
pathstringYesPath inside the sandbox. .. is refused. See Files.

Returns: the file's bytes. At most 32 MiB on AWS, GCP, and Kubernetes.

Errors: A refused path or a file over the size cap is not retryable. SANDBOX_UNREACHABLE is safe to retry.


writeFiles

Writes files into the sandbox, creating parent directories. Requires files.

writeFiles(sandboxId: string, files: Record<string, Buffer | string>): Promise<void>

await box.writeFiles(sandboxId, { "work/main.py": "print('hello')" })
ParameterTypeRequiredDescription
sandboxIdstringYesThe sandbox to write to.
filesRecord<string, Buffer | string>YesPath to contents. A string is written as UTF-8. At most 32 MiB per file on AWS, GCP, and Kubernetes.

The TypeScript binding writes files one at a time, so a failure can leave some files written.

Errors: A refused path or a file over the size cap is not retryable. SANDBOX_UNREACHABLE is safe to retry.


pause / resume

Pauses a sandbox with its state preserved, and resumes it. Requires pauseResume (AWS, Azure).

pause(sandboxId: string): Promise<void>
resume(sandboxId: string): Promise<void>

A running command is suspended with the sandbox, and its timeout stops counting until resume. On Azure, the sandbox is deleted once a paused command's timeout passes.


terminate

Destroys a sandbox. Idempotent: terminating a sandbox that does not exist succeeds.

terminate(sandboxId: string): Promise<void>

On Azure and GCP, terminate returns after the platform confirms the sandbox is gone.


preview

Returns an endpoint and headers for reaching a port inside the sandbox, such as a web server the code started. Requires preview: AWS when the declaration lists previewPorts, and Local.

preview(sandboxId: string, port: number): Promise<SandboxPreview>

const preview = await box.preview(sandboxId, 8080)
ParameterTypeRequiredDescription
sandboxIdstringYesThe sandbox to reach.
portnumberYesMust be listed in the declaration's previewPorts. Any other port raises OPERATION_NOT_SUPPORTED.

Returns: a SandboxPreview (Rust: PreviewCapability): send requests to endpoint with the headers. On AWS it expires after 30 minutes. On Local it's bound to 127.0.0.1 and doesn't expire.


snapshot

Rust only. No platform reports it. GCP captures a snapshot that nothing can restore yet; elsewhere the call raises OPERATION_NOT_SUPPORTED.

async fn snapshot(&self, sandbox_id: &str) -> Result<String>

Types

interface SandboxInstance {
  sandboxId: string                                        // the id every later call addresses
  state: "starting" | "running" | "paused" | "terminated"
  generation: number                                       // changes when the sandbox is replaced; compare for equality
}

interface ResolvedSandbox {
  sandbox: SandboxInstance
  created: boolean                                         // true when this call created it
}

interface CreateSandboxOptions {
  sandboxId?: string
  tenantKey?: string
  env?: Record<string, string>
  timeoutMs?: number
}

interface RunCommandOptions {
  timeoutMs: number
  args?: string[]
  cwd?: string
  env?: Record<string, string>
}

type CommandFrame =
  | { kind: "stdout" | "stderr"; seq: number; data: Buffer }
  | { kind: "exit"; exitCode: number; truncated: boolean }

interface JobPoll {
  running: boolean
  frames: CommandFrame[]
  exit?: { code: number; truncated: boolean }
  error?: { code: string; message: string }              // code, e.g. "timeoutExceeded"
}

Errors

Raised when the stack is planned:

CodeMeaningRetryable
SANDBOX_CAPABILITY_UNSUPPORTEDThe declaration needs a capability the target platform lacks. The message names the capability and the platform.No
SANDBOX_LIMIT_INVALIDA field of the declaration is invalid for the target platform, such as a quantity no AWS size or Azure sizing rule allows, or an image in the wrong form.No
SANDBOX_PLATFORM_UNSUPPORTEDThe target platform has no sandbox backend.No

Raised by the binding:

CodeMeaningRetryable
OPERATION_NOT_SUPPORTEDThe platform does not support this operation or option.No
SANDBOX_UNREACHABLEThe operation did not reach the sandbox, or the connection dropped before it took effect.Yes
SANDBOX_OUTCOME_UNKNOWNThe operation was sent and never reported its outcome. It may have taken effect; don't repeat a command or job start.No
SANDBOX_COMMAND_FAILEDA command or sandbox operation did not complete, including a command that reached its timeout.No
SANDBOX_NOT_AS_DECLAREDAzure only. The sandbox came up without a restriction its declaration asked for, such as its egress policy. Create a new one.No
INVALID_INPUTA request value is invalid, such as a create-time timeoutMs of 0 on AWS or GCP.No

In TypeScript, errors are AlienError values; match on error.code. isSandboxOutcomeUnknown(error) from @alienplatform/bindings also finds the code when it is wrapped in another error.


Platform Capabilities

The capabilities a declaration is checked against when the stack is planned. Create, run, and terminate work everywhere and are not listed.

CapabilityAWSGCPAzureKubernetesLocal
files: read and write filesyesyesyesyesyes
reconnect: reach a sandbox from a later callyesyesyesyesyes
jobs: start, poll, and cancel jobsyesyesnoyesno
preview: reach a port inside the sandboxyesnononoyes
pauseResumeyesnoyesnono
snapshotnonononono
domainEgressRules: allowDomains egressnonoyesnono
egressDeny: deny egress is enforcedyes, except DNSyesyesyesyes
enforcedLimits: cpu, memory, and disk ceilingsyesyes, except diskyesyesyes
processLimit: maxProcessesnonononoyes
sandboxLifetime: maxLifetimeSecondsyesyesnoyesno
supervisorPidNamespacenonononono
supervisorIsolation: the command runs as a different user than the process supervising ityesnononoyes

At runtime, capabilities() returns the same table, except that AWS reports preview only when the declaration lists previewPorts, and Kubernetes doesn't report sandboxLifetime.

On this page