Skip to main content
Sail ships a TypeScript SDK for sailboxes (@sailresearch/sdk on npm), built for TS agent harnesses on Node 22+ and Bun. It shares one engine with the Python and Rust SDKs, so behavior matches across languages. This page covers install and TypeScript-specific notes.

Install

npm install @sailresearch/sdk
pnpm add @sailresearch/sdk
bun add @sailresearch/sdk
Prebuilt native binaries are published per platform (Linux, macOS, Windows) and selected automatically at install time.

Configure

Set SAIL_API_KEY in the environment; the SDK also reads ~/.sail. The object-model statics use this configuration by default, or construct a Client explicitly with Client.fromConfig({ apiKey }).

Quickstart

import { App, Sailbox } from "@sailresearch/sdk";

// Look up (or create) the app your sandboxes belong to.
const app = await App.find("example-app", { mintIfMissing: true });

// Boot a sandbox (defaults to a Debian base image).
const sb = await Sailbox.create({ app, name: "worker-1" });

// Run a command and stream its output.
const proc = await sb.exec("echo hello && ls /");
for await (const chunk of proc.stdout) process.stdout.write(chunk);
const result = await proc.wait();
console.log("exit code:", result.exitCode);

// Move files.
await sb.write("/tmp/note.txt", "hi from the harness\n");
const contents = await sb.read("/tmp/note.txt");

// Expose a port and wait until it is routable.
await sb.expose(8080, "http");
const listener = await sb.waitForListener(8080);
if (listener.endpoint?.kind === "http") {
  console.log("reachable at:", listener.endpoint.url);
}

// Lifecycle: pause / sleep / resume / checkpoint / terminate.
await sb.terminate();

Custom images

Use the fluent Image builder and pass it to Sailbox.create. Local files and directories are hashed and uploaded for you when the sailbox is created.
import { App, Image, Sailbox } from "@sailresearch/sdk";

const app = await App.find("example-app", { mintIfMissing: true });

const image = Image.debian("arm64")
  .aptInstall("git")
  .pipInstall("numpy")
  .addLocalDir("./app", "/app", { ignore: ["node_modules/", ".git/"] })
  .runCommand("pip install -e /app");

const sb = await Sailbox.create({ app, name: "worker", image });

Surface

Voyages (agent tracing) and inference calls are currently Python-only; the TypeScript SDK covers the full sailbox surface. See the Voyages reference.
  • Sailbox: create / get / list / listPage / fromCheckpoint, and per-instance exec, shell, read / write / writeStream / readStream, expose / unexpose / listeners / listener / waitForListener, ingressAuthHeaders, enableSsh, and terminate / pause / sleep / resume / checkpoint / upgrade.
  • App: find / list.
  • Volume: find / list, and per-instance delete.
  • Image: debian / devbox, aptInstall / pipInstall / runCommand / env, addLocalFile / addLocalDir, build, toSpec (Sailbox.create builds it for you).
  • Client: the lower-level surface with the same operations.

Errors

Everything the SDK throws extends SailError, so one catch (e) { if (e instanceof SailError) } handles all of it; subclasses like NotFoundError and SailboxExecutionError let you match specific failures. See Errors for the full hierarchy.

API reference

For the complete listing of every class, method, parameter, and type, see the TypeScript SDK reference.