# `OpenrouterSdk.Client`
[🔗](https://github.com/zmzlois/openrouter_sdk/blob/v0.1.0/lib/openrouter_sdk/client.ex#L1)

finch wrapper. two paths:

  * `request/2` — buffered. body collected, json decoded.
  * `stream/2` — sse. returns a lazy `Stream` that yields parsed
    events; consumers can also opt into pid / fun delivery via
    the `:into` option (see `OpenrouterSdk.Api.*` for usage).

middleware wraps both paths so retry / rotation policies see every
request including streams. for streams the middleware sees the
initial `:ok | :error` decision (i.e. whether the stream started)
but does not see the per-chunk events — those flow directly to the
consumer's stream.

# `request`

```elixir
@spec request(OpenrouterSdk.Client.Request.t(), OpenrouterSdk.Config.t()) ::
  {:ok, term()} | {:error, OpenrouterSdk.Error.t()}
```

execute a buffered request. returns {:ok, decoded} | {:error, error}

# `stream`

```elixir
@spec stream(OpenrouterSdk.Client.Request.t(), OpenrouterSdk.Config.t()) ::
  {:ok, Enumerable.t()} | {:error, OpenrouterSdk.Error.t()}
```

execute a streaming request. returns `{:ok, stream}` where `stream`
is a lazy `Stream` of `:done | %SSE.Event{} | {:raw, bytes}` (the
shape depends on opts the api module passes via `req.opts`).

the stream is only safe to consume from the process that calls this
function (it reads from that process mailbox). use `Stream.run/1`,
`Enum.to_list/1`, or pipe through `Stream.map/2` etc.

---

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