> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://buildwithfern.com/learn/llms.txt. ## 2.34.0 **`(feat):`** Add `unified-client-options` configuration flag. When enabled, all auth parameters, global headers, and `BaseUrl` are consolidated into `ClientOptions` so the client constructor takes a single argument with no positional parameters: ```yaml # generators.yml groups: dotnet-sdk: generators: - name: fernapi/fern-csharp-sdk config: unified-client-options: true ``` **Before** (default): ```csharp var client = new MyClient( "my-api-key", clientOptions: new ClientOptions { BaseUrl = "..." } ); ``` **After** (with `unified-client-options: true`): ```csharp var client = new MyClient( new ClientOptions { ApiKey = "my-api-key", BaseUrl = "https://api.example.com", } ); ``` Supported auth schemes: bearer token, basic auth (username/password), header auth, OAuth client credentials (clientId/clientSecret + custom params), and inferred auth. Global headers (non-literal) are also included. Properties on `ClientOptions` use the appropriate C# semantics based on the parameter's characteristics: * **Has environment variable fallback** — `public string? ApiKey { get; set; }`. Nullable and mutable so the constructor can apply the fallback via `clientOptions.ApiKey ??= GetFromEnvironmentOrThrow(...)`. * **Optional (no environment variable)** — `public string? ApiKey { get; init; }`. Nullable, immutable after construction. * **Required (no environment variable, not optional)** — `public required string ApiKey { get; init; }`. Non-nullable, enforced at the call site by the compiler. `BaseUrl` is also `required` when no default environment is configured, replacing the previous behavior of silently defaulting to `""`. When any `ClientOptions` field is `required`, the constructor parameter becomes non-nullable (`ClientOptions clientOptions` instead of `ClientOptions? clientOptions = null`), and `Clone()` uses an internal copy constructor annotated with `[SetsRequiredMembers]`. ## 2.33.1 **`(fix):`** Fix README generation to use the `package-name` field from `generator.yml` for the NuGet package name in installation instructions and shields. Previously, the README always used the namespace (or `package-id` custom config) instead of the configured `package-name`, which is the actual NuGet package identifier. ## 2.33.0 **`(feat):`** WebSocket factory methods now resolve the base URL from the main client's multi-URL environment when the channel specifies a `baseUrl`. This allows WebSocket clients to use environments defined on the root client (e.g., `Environment.Wss`) instead of requiring separate per-WebSocket environment classes. ## 2.32.2 **`(fix):`** Fix CS1501 build error for literal struct `GetHashCode` on `netstandard2.0` and `net462` targets. `string.GetHashCode(StringComparison)` is only available in .NET Core 2.1+ / .NET Standard 2.1+. The generated code now uses `StringComparer.Ordinal.GetHashCode(Value)` which is available on all frameworks. ## 2.32.1 **`(fix):`** Fix referenced request bodies with `application/x-www-form-urlencoded` content type to generate `FormRequest` instead of `JsonRequest`. Previously, endpoints using a `$ref` schema with form-urlencoded content type would incorrectly send JSON-serialized bodies, causing auth token requests (e.g., OAuth) to fail.