API Reference
Complete API reference for Alien Sandbox bindings.
Every method below is reached through the binding, not the resource declaration. The declaration provisions the parent; these create and drive sessions at runtime.
Where a platform lacks a capability the call returns a typed AlienError naming both the
platform and the capability. It never no-ops and never returns a null-ish success — you will
know, and the error will tell you what to change.
capabilities()
const caps: string[] = await box.capabilities()
if (caps.includes("files")) { /* ... */ }Returns what this platform's backend actually supports — a list of capability names in TypeScript, a struct of booleans in Rust. Branch on it rather than catching errors, when you have a sensible fallback.
| Capability | AWS | Azure | GCP | Kubernetes | Local |
|---|---|---|---|---|---|
files | yes | no | yes | yes | yes |
reconnect | yes | yes | no | yes | yes |
preview | yes | no | no | no | yes |
suspendResume | yes | no | no | no | no |
snapshot | no | no | no | no | no |
egressDeny | yes | no | yes | yes | yes |
domainEgressRules | no | no | no | no | no |
enforcedLimits | yes | no | no | yes | yes |
processLimit | no | no | no | no | yes |
sessionLifetime | yes | no | no | yes | no |
supervisorPidNamespace | no | no | no | no | no |
Sessions
create / getOrCreate / get / list
const session = await box.create({ sessionId: "turn-1" })create takes a session id and, optionally, a tenant key. It takes no image, cpu, memory or
port arguments — those come from your alien.Sandbox declaration. An application cannot raise
its own ceilings by asking, which is the point.
get requires reconnect. On GCP it returns the typed error rather than null: a null reads
as "the session expired", when the truth is that GCP cannot address a session from another
instance at all. getOrCreate is the one call that degrades instead — where reconnect is
unavailable it creates a fresh session.
list enumerates this sandbox's sessions on Kubernetes and Local only. AWS, Azure and GCP raise
rather than enumerate — none of their APIs can list sessions scoped to one sandbox. Reach a
session whose id you hold with get.
terminate
await box.terminate(session.sessionId)Terminating a session that is already gone succeeds on Azure and Kubernetes, because terminate is
the cleanup path and a cleanup that fails on an absent session turns teardown into a retry loop.
AWS and Local raise instead — they check the session exists before acting — so treat a
not-found error from terminate as success if you are writing a teardown that must converge.
runCommand
for await (const frame of sandbox.runCommand(sessionId, ["python3", "main.py"], {
deadlineMs: 30_000,
})) {
if (frame.kind === "stdout") process.stdout.write(frame.data)
if (frame.kind === "exit") console.log(frame.exitCode)
}Streams output frames, then exactly one terminal frame.
deadlineis required. A request without one is rejected rather than defaulted — a default deadline is a hang waiting for a slow day.seqis monotonic across stdout and stderr together on AWS, Kubernetes and GCP, so you can interleave them in the order they were produced. Azure and Local return an already-buffered response and number it stdout-then-stderr, which does not reconstruct production order.- Exactly one terminal
exitframe, always last. Frames arestdout,stderrandexit— a failure is a thrown error in TypeScript and a streamErrin Rust, not a frame. A stream that ends without anexitis a transport failure, not a clean exit 0. - Output carries backpressure on AWS, Kubernetes and GCP: a consumer that stops reading stops the sandbox's writer rather than filling memory. Azure and Local buffer the whole response first.
Files
await box.writeFiles(sessionId, { "/work/main.py": bytes })
const out = await box.readFile(sessionId, "/work/out.txt")
await box.mkdir(sessionId, "/work/build")Requires files, which Alien's Azure binding does not implement.
Paths may not escape the session root, and the strength of that varies. On AWS and Kubernetes
the agent opens through openat2, so the kernel resolves and opens in one call and refuses ..,
absolute paths and symlinks rather than following them — code inside the sandbox cannot race a
check it never gets to see. Transfers there are bounded at 32 MiB. Local rewrites paths against
the session root and rejects .. without resolving symlinks; GCP checks for .. and passes the
path through unchanged, and neither applies a size bound.
preview
Rust only. The TypeScript binding exposes no preview method, so capabilities() there
never reports it.
let capability = sandbox.preview(session_id, 8080).await?;| Parameter | Type | Required | Description |
|---|---|---|---|
sessionId | string | Yes | The session to expose. |
port | number | Yes | Must be listed in previewPorts on the resource declaration. |
Returns a typed capability, not a URL string. AWS needs auth headers and a port header. A bare URL cannot carry those, and handing you one would push the auth onto you to get wrong. Local returns an unauthenticated capability with no headers and no expiry.
| Field | Type | Description |
|---|---|---|
endpoint | string | The address to send requests to. |
headers | Record<string, string> | Auth headers that must accompany every request. |
allowedPorts | number[] | Ports this capability covers. |
expiresInSeconds | number | Lifetime of the capability. |
A port not declared in previewPorts cannot be
exposed at runtime, so an application cannot widen its own ingress.
Requires preview, which today means AWS and Local. Kubernetes returns the typed error until the
session-scoped ingress gateway exists, GCP has no mechanism, and Azure's is not implemented yet —
the platform has a per-port URL closed to anonymous traffic, and the binding does not use it.
suspend / resume / snapshot
await box.suspend(sessionId)
await box.resume(sessionId)snapshot is Rust-only and unavailable on every platform; TypeScript exposes no method for it.
suspend/resume need suspendResume, which today is AWS only. snapshot is not available
on any platform yet: AWS has no user-callable session snapshot, and Azure's full-VM capture is not
wired into the binding.
Unsupported Surface
The surface is close enough to Vercel's that porting is small. Two differences will show up when you do:
snapshot()is capability-gated, not universal, and no platform advertises it today. AWS has build-time image capture and suspend/resume but no user-callable session snapshot; Azure captures full VM state and the binding does not use it yet. Both return the typed error.preview()returns a capability, not a URL — see above.