> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sailresearch.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Rust SDK

> Rust SDK installation and API reference on docs.rs

The Sail Rust SDK (`sail-rs` on crates.io) creates and drives Sailboxes from
Rust: lifecycle, streaming exec, file transfer, ingress, and credential
injection. Behavior matches the [Python](/reference/python-sdk) and
[TypeScript](/reference/typescript-sdk) SDKs.

## Install

```toml theme={null}
[dependencies]
sail-rs = "0.11.2"
# tokio must be a direct dependency to write #[tokio::main]:
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
```

The crate is published as `sail-rs` and imported as `sail`:

```rust theme={null}
use sail::Client;
```

Adding the crate does not install the `sail` CLI. Install the CLI separately
with `curl -fsSL https://cli.sailresearch.com/install.sh | sh`, or see
[Install the CLI](/reference/cli).

## Configure

Set `SAIL_API_KEY` in the environment; the SDK also reads the credential
`sail auth login` stores under `~/.sail`. Construct with `Client::from_env()`,
or use `Client::builder(api_key)` for explicit configuration. See
[Configuration](/reference/sdk-configuration).

## Quickstart

```rust theme={null}
use sail::{Client, CreateSailboxRequest, RunOptions, SailError};

#[tokio::main]
async fn main() -> Result<(), SailError> {
    let client = Client::from_env()?;

    // Look up (or create) the app your Sailboxes belong to.
    let app = client
        .find_app("rust-quickstart", /* mint_if_missing */ true)
        .await?;

    // Create a Sailbox; the default request uses the prebuilt Debian base image.
    let sb = client
        .create_sailbox(
            &CreateSailboxRequest {
                app_id: app.id,
                name: "quickstart".into(),
                ..Default::default()
            },
            /* timeout */ None,
        )
        .await?;

    // Run a command, then terminate the Sailbox whether or not the run failed.
    let run = sb
        .run_shell("echo hello from the guest", RunOptions::default())
        .await;
    sb.terminate().await?;

    print!("{}", run?.stdout);
    Ok(())
}
```

## Runtime

Every method is `async`, driven on a Tokio runtime. Async hosts await the
methods directly. Synchronous code can drive any method with `sail::block_on`,
which runs it to completion on a shared internal runtime. `Client` is cheap to
clone (it shares its connection pools and config behind an `Arc`), so clone it
to share across tasks.

## Surface

<Note>
  Voyages (agent tracing) and inference calls are Python-only; the Rust SDK
  covers the full Sailbox surface. See the [Voyages reference](/voyages-sdk).
</Note>

`create_sailbox` and `create_from_checkpoint` return a `Sailbox`, and
`client.sailbox(id)` binds an existing id without a network call. Every
per-Sailbox operation is a method on it: lifecycle (`info` / `terminate` /
`pause` / `sleep` / `set_auto_sleep` / `resume` / `upgrade`), `checkpoint`,
one-shot `run` / `run_shell`, streaming `exec` / `exec_shell`, filesystem
helpers under `fs()` (one-shot `read` / `write`, streaming `read_stream` /
`write_stream`, directory transfer `upload_dir` / `download_dir`, and
`mkdir` / `remove` / `exists` / `ls`), an interactive `shell`, listeners
(`expose` / `unexpose` / `listeners` / `listener` / `wait_for_listener` /
`ingress_auth_headers`), SSH (`enable_ssh`), and HTTP policy attachment
(`set_http_policy` / `http_policy` / `clear_http_policy`).

`run` and `run_shell` return only the most recent `output_buffer_bytes` of each
stream (1 MiB by default), with the `*_truncated` flags set when older output
was dropped. To get every byte of a stream, use `exec` or `exec_shell` and take
its reader (`reader` or `reader_async`) right after the call returns; Sail then
pauses the command if you fall behind (until a cancel or the timeout ends the
pauses; see `OutputMode`), and dropping the reader releases the stream. A
stream without a reader never pauses the command, and Sail keeps only
its most recent bytes. `ExecOptions::output_mode` changes that: `OutputMode::Pipe`
holds both streams until you take their readers, and `OutputMode::Tail` never
pauses the command. You can read one stream without holding the other. If you
hold both readers, read them at the same time from two tasks. The
[Exec process](/sailbox-sdk#sailboxexecprocess) section has the details.

Org-scoped operations live on the `Client`: `list_sailboxes`,
`create_from_checkpoint`, volumes, apps, the image build pipeline, and secrets
and HTTP policies for [credential injection](/sailboxes-credentials).

<Note>
  Volumes are currently in Alpha. To pilot them, reach out in the [Sail
  Slack](https://join.slack.com/t/sailresearchcrew/shared_invite/zt-41pdcym9j-UU0Ey~A~r6n2H0DQVQsQHQ).
</Note>

## API reference

The full API reference is generated by rustdoc and published on docs.rs. It
covers every module, type, and method in the crate, with source links and
cross-references.

<Card title="sail-rs on docs.rs" icon="rust" href="https://docs.rs/sail-rs">
  Open the complete `sail-rs` reference.
</Card>
