# `Xai.Client`
[🔗](https://github.com/beamlab-xai/xai/blob/main/lib/xai/client.ex#L1)

The main client for interacting with xAI's gRPC APIs.

Closely modeled after `xai_sdk.Client` in the official Python SDK.

## Example

    client = Xai.Client.new(api_key: System.get_env("XAI_API_KEY"))

    chat = Xai.Chat.create(client, model: "grok-4.5")
    chat = Xai.Chat.append(chat, Xai.Chat.user("Hello"))
    {:ok, response} = Xai.Chat.sample(chat)

For long-running operations (video, deferred), the client manages the channel.

## Options

* `:api_key` - falls back to `XAI_API_KEY`
* `:management_api_key` - for Collections / management (falls back to `XAI_MANAGEMENT_API_KEY`)
* `:endpoint` - default "api.x.ai:443"
* `:ssl` - whether to use TLS for the gRPC connection, default `true`
* `:timeout` - default 30 minutes
* `:adapter` - the `GRPC.Stub` transport adapter, default `GRPC.Client.Adapters.Gun`.
  Both `:gun` and `:mint` are optional dependencies of this package — add
  whichever one you actually use to your own `mix.exs`. Pass
  `adapter: GRPC.Client.Adapters.Mint` to use Mint instead of Gun (no
  `:cowlib` in its dependency tree). Callers who only use `Xai.Realtime`
  (WebSocket, via `websockex`) never call `Xai.Client.new/1` at all and
  need neither `:gun` nor `:mint`.

# `grpc_channel`

```elixir
@type grpc_channel() :: %GRPC.Channel{
  accepted_compressors: term(),
  adapter: term(),
  adapter_payload: term(),
  codec: term(),
  compressor: term(),
  cred: term(),
  headers: term(),
  host: term(),
  interceptors: term(),
  port: term(),
  ref: term(),
  scheme: term()
}
```

A connected gRPC channel.

Declared here as the struct rather than reusing `GRPC.Channel.t()`: grpc
1.0.3 dropped the `@type t` from that module, leaving only the `defstruct`,
so the named type no longer resolves and dialyzer reports `unknown_type`.
Naming it locally says the same thing without depending on the dependency
re-declaring it, and keeps the struct out of the `@spec`s themselves.

# `t`

```elixir
@type t() :: %Xai.Client{
  api_key: String.t() | nil,
  channel: grpc_channel(),
  endpoint: String.t(),
  management_api_key: String.t() | nil,
  timeout: pos_integer()
}
```

# `channel`

```elixir
@spec channel(t()) :: grpc_channel()
```

Get the raw gRPC channel (for advanced use or direct stub calls).

# `default_timeout`

Get the configured default timeout.

# `new`

```elixir
@spec new(keyword()) :: t()
```

Create a new client.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
