> ## 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.

# Configuration

> How the SDK resolves endpoints and retries: sail.Config and sail.RetryPolicy

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

`SAIL_API_URL`, `SAILBOX_API_URL`, `SAIL_IMAGEBUILDER_URL`, and
`SAILBOX_INGRESS_URL` each override one endpoint, for custom or self-hosted
stacks.

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()`.

## Inspecting the configuration

Each SDK exposes the configuration it resolved from the environment:

<CodeGroup>
  ```python Python theme={null}
  import sail

  config = sail.Config.from_env()
  print(config.api_url)  # https://api.sailresearch.com
  ```

  ```typescript TypeScript theme={null}
  import { Client } from "@sailresearch/sdk";

  const client = Client.fromEnv();
  // Or configure explicitly:
  // const client = Client.fromConfig({ apiKey: "sk_..." });
  ```

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

  let client = Client::from_env()?;
  // Or configure explicitly:
  // let client = Client::builder("sk_...").build()?;
  ```
</CodeGroup>

### Python constructors

```python theme={null}
@classmethod
def from_env() -> Config

@classmethod
def from_env_optional_api_key() -> Config
```

* `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.

<Note>
  For the Voyage and agent attribution environment variables, see the [Voyages
  environment table](/voyages-sdk#environment-variables).
</Note>

## 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 always retried.
* **429** is retried only when the response includes a valid `Retry-After`.
* **500** and other statuses are surfaced immediately, without a retry.

In Python, `sail.RetryPolicy` describes this policy, and
`sail.DEFAULT_RETRY_POLICY` (the standard policy above) and `sail.NO_RETRY`
(a single attempt) are the two built-in instances. They're exported so you can
inspect the retry behavior; the SDKs manage retries for you, so there's
nothing to configure per call.
