Skip to main content
Most applications configure the SDKs entirely through environment variables. Set SAIL_API_KEY (or run sail auth login once) and you’re done; the endpoint variables below matter only for custom or self-hosted deployments. Every SDK reads the same variables and the same credential store. Use export SAIL_API_KEY=sk_... for SDK scripts, CI jobs, and background agents. If SAIL_API_KEY is unset, the SDKs fall back to the credential sail auth login stores under ~/.sail. The environment variable always wins.

Endpoint overrides

Each of these overrides one endpoint, for custom or self-hosted stacks:
  • SAIL_API_URL: the main Sail API. Default https://api.sailresearch.com.
  • SAILBOX_API_URL: the Sailbox API. Default https://sailbox-api.sailresearch.com.
  • SAILBOX_INGRESS_URL: the base URL used to build an exposed listener’s public address when the service does not return one.
Configuration is read when a client is created. To pick up changed variables in a long-lived process: in Python, call sail.reset_transports() (the SDK resolves once per process); in TypeScript, construct a new client with Client.fromEnv() and repoint the object model with setDefaultClient; in Rust, construct a new client with Client::from_env().

Worker threads

The Python and TypeScript SDKs run their network calls on a small pool of background threads shared by the whole process, and the Rust SDK uses the same pool for its blocking calls. The pool is sized to the machine: one thread per CPU, with at least 2 and at most 8. That is plenty for most applications, including ones that drive many Sailboxes concurrently, because the threads spend nearly all of their time waiting on the network. Rust code that awaits the async API does not use this pool. Those calls run on your application’s own async runtime, so the setting below does not affect them. Set SAIL_RUNTIME_THREADS to override the pool size, for example to give a large fan-out workload more headroom or to keep a constrained process at exactly one thread. Values from 1 to 256 are accepted; anything else is ignored and the default applies. The variable is read once per process, when the SDK first performs work, so set it before your program starts using the SDK.

Inspecting the configuration

Each SDK exposes the configuration it resolved from the environment:

Python constructors

  • Config.from_env() resolves the configuration and requires an API key (from SAIL_API_KEY or the stored sail auth login credential), raising ValueError if none is found.
  • Config.from_env_optional_api_key() is the same, but does not require an API key. Use it when you want a Config without a key, for example so sail.voyage can run in no-op mode.
For the Voyage and agent attribution environment variables, see the Voyages environment table.

Retries

The SDKs retry transient failures automatically. By default they make up to 3 attempts with exponential backoff and full jitter, honoring a server Retry-After when one is present:
  • 502 / 503 / 504 are retried.
  • 429 is retried only when the response includes a valid Retry-After.
  • 500 and other statuses are surfaced immediately, without a retry.
Mutations that are not safe to repeat skip these retries and make a single attempt. exec retries transient failures against a waking or migrating Sailbox for up to ten minutes, reusing its idempotency key so a retried launch still runs the command once.