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

# Configuration

> createClient options, credential resolution, and the provider-client helpers.

`createClient(options)` is a factory function that returns a client. Call it directly; it is not a class, so do not use `new`.

## Credential resolution

Each URL and credential resolves with a per-option precedence, so an app can construct the client from the environment alone:

* URLs (`baseUrl`, `gatewayUrl`) — option → environment variable → built-in default.
* `apiKey`, `projectId`, `env` — option → environment variable (no default).
* `format` — option only.

Authenticate with `apiKey` (a to11 API key). For control-plane calls the SDK sets `Authorization: Bearer <apiKey>` for you and carries the project in the URL path.

<Note>
  Keep credentials server-side. A to11 API key carries gateway access, so it must never ship in browser code — the SDK throws if you construct a client with `apiKey` in a browser context (like OpenAI's `dangerouslyAllowBrowser`). The same goes for a `providerApiKey` (BYOK). Use the SDK from a server, CLI, or backend job.
</Note>

## Options

| Option           | Type                          | Resolves from               | Default                                                                                         |
| ---------------- | ----------------------------- | --------------------------- | ----------------------------------------------------------------------------------------------- |
| `baseUrl`        | `string`                      | option → `TO11_API_URL`     | `https://api.to11.ai`                                                                           |
| `gatewayUrl`     | `string`                      | option → `TO11_GATEWAY_URL` | `https://gw.to11.ai` (host only, no `/v1`)                                                      |
| `apiKey`         | `string`                      | option → `TO11_API_KEY`     | — (throws if constructed in a browser)                                                          |
| `providerApiKey` | `string`                      | option                      | — (BYOK; carried by `openaiOptions()` / `anthropicOptions()` as the provider client's `apiKey`) |
| `projectId`      | `string`                      | option → `TO11_PROJECT_ID`  | —                                                                                               |
| `env`            | `string`                      | option → `TO11_ENV`         | — (must match `^[a-z0-9-]{1,63}$`)                                                              |
| `format`         | `"openai" \| "anthropic"`     | option                      | — (omit for the neutral render result)                                                          |
| `onUnknownRole`  | `"drop" \| "warn" \| "error"` | option                      | `"drop"`                                                                                        |
| `timeoutMs`      | `number`                      | option                      | `30000`                                                                                         |
| `maxRetries`     | `number`                      | option                      | `3`                                                                                             |

## What the client exposes

* Resource namespaces `prompts` and `projectEnvironments`.
* Accessors for the resolved config: `baseUrl`, `gatewayUrl` (the gateway root, host only — no `/v1`), `apiKey`, `projectId` (or `undefined` when unset), and `env` (or `undefined` when unset). `providerApiKey` (BYOK) is deliberately not exposed — it's a secret, not a config value to read.
* Provider-client options `openaiOptions()` and `anthropicOptions()`, each returning `{ baseURL, apiKey, defaultHeaders }` for a gateway-pointed client.
* The context factory `session()`, `conversation()`, and `turn()` — see [Sessions, conversations & turns](/docs/reference/typescript-sdk/sessions-and-turns).

The `projectId` set here is the default for **every** `prompts.*` method — `render()` and the lifecycle / version / label calls (`get`, `list`, `getVersion`, `moveLabel`, …). Bind it once on the client and omit it per call; pass `projectId` on an individual call only to override.

## Provider-client options

`openaiOptions()` and `anthropicOptions()` return spread-ready options — `{ baseURL, apiKey, defaultHeaders }` — for a provider client that targets the gateway. Both point at the same gateway; the `baseURL` differs only by each SDK's own convention: `openaiOptions()` returns `${gatewayUrl}/v1` (the OpenAI client puts `/v1` in `baseURL`), while `anthropicOptions()` returns the gateway root (the Anthropic client appends `/v1/messages` itself). `defaultHeaders` carries the **static tenant auth** (`x-to11-authorization`, `x-to11-project-id`, and `x-to11-env` when set), so the client authenticates on its own; add `turn().headers(prompt)` per call for the request's trace id and prompt provenance.

```ts theme={null}
import OpenAI from "openai";
import Anthropic from "@anthropic-ai/sdk";

const openai = new OpenAI(to11.openaiOptions());
const anthropic = new Anthropic(to11.anthropicOptions());
```

`projectId` is required (it becomes `x-to11-project-id`); the helpers throw without one, or without an `apiKey`.

### apiKey: managed vs BYOK

The returned `apiKey` is the provider client's key:

* **Managed (default):** with no `providerApiKey`, `apiKey` is the to11 key as a placeholder. The gateway ignores it and runs the call on the project's **configured provider credential**.
* **BYOK:** set `providerApiKey` on `createClient` (or pass `apiKey` per call — see below) and it becomes the provider client's key, forwarded upstream. Whether the gateway uses it depends on the provider's passthrough mode; otherwise the stored credential still wins.

### Overrides and passthrough

Both helpers accept an optional overrides object. The three managed fields are merged — `apiKey` and `baseURL` override; `defaultHeaders` shallow-merges over the tenant-auth headers (caller wins) — and **any other key passes through untouched** to the provider client, so no outer spread is needed:

```ts theme={null}
// BYOK for one call + a provider-SDK option, in one expression. Pass a real
// provider key — an absent `apiKey` falls back to the managed placeholder.
const openai = new OpenAI(to11.openaiOptions({ apiKey: OPENAI_API_KEY, timeout: 60_000 }));

// add a header while keeping the tenant-auth headers
const anthropic = new Anthropic(to11.anthropicOptions({ defaultHeaders: { "x-trace": "1" } }));
```

For Vercel AI / LangChain, whose constructors take a different shape, build the base URL from `to11.gatewayUrl` (the gateway root) — an OpenAI-compatible client wants `${to11.gatewayUrl}/v1` — and attach `turn().headers()` (or `gatewayAuthHeaders`) yourself. See the [Vercel AI SDK integration](/docs/integrations/vercel-ai-sdk) guide for a full example.
