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

**`(feat):`** Generate interfaces for WebSocket API classes (e.g., `IStreamApi`, `ITranscribeApi`)
to improve testability. Each WebSocket client now implements a corresponding interface
that declares all public event properties, `Status`, `ConnectAsync`, `Send`, and
`CloseAsync`. The root client interface (`ICortiClient`) also includes factory method
signatures (`CreateStreamApi`, `CreateTranscribeApi`) when WebSockets are enabled.

## 2.38.1

**`(fix):`** Fix `Event<T>` thread-safety issue. `RaiseEvent` now snapshots the subscriber
collections under a lock before iterating, and `Subscribe`, `Unsubscribe`, and
`UnsubscribeAll` are synchronized to prevent `InvalidOperationException` when
handlers are added or removed concurrently from different threads.

## 2.38.0

**`(feat):`** Add optional `CancellationToken` parameter to all public async WebSocket methods
(`ConnectAsync`, `CloseAsync`, and `Send` overloads). The token is threaded through
the internal `WebSocketClient`, `WebSocketConnection`, and down to the underlying
`ClientWebSocket.SendAsync`/`ConnectAsync`/`CloseAsync` calls, enabling callers to
cancel long-running WebSocket operations.

## 2.37.2

**`(fix):`** Fix WebSocket binary messages being sent with `WebSocketMessageType.Text` instead of
`WebSocketMessageType.Binary`. `RequestBinaryMessage` and `RequestBinarySegmentMessage`
now correctly use `WebSocketMessageType.Binary` when calling `SendAsync`, ensuring
audio data (e.g. webm/opus chunks) is sent as binary frames.

## 2.37.1

**`(fix):`** Add `ReadAsPropertyName` and `WriteAsPropertyName` overrides to all remaining
custom `JsonConverter` types: `EnumSerializer<TEnum>` (native C# enums),
`DateTimeSerializer`, `DateAsDateTimeConverter`, discriminated union converters,
and literal type converters. Without these overrides, `System.Text.Json` throws
`NotSupportedException` when any of these types is used as a `Dictionary<TKey, TValue>`
key. This complements the `IStringEnum` fix in 2.35.1.

## 2.37.0

**`(feat):`** Replace separate deserialization and serialization tests with a single round-trip
serialization test using `JsonAssert.Roundtrips<T>(inputJson)`. The helper deserializes
JSON to `T`, re-serializes, and compares to the original JSON via `JsonElement` deep
equality, producing diff-reportable failures.

## 2.36.0

**`(feat):`** Add `UsingObjectDictionaryComparer` to test comparers for handling
`Dictionary<string, object?>` fields. System.Text.Json deserializes
`object?` values as `JsonElement`, so structural equality comparisons
need to serialize both sides before comparing. The `UsingDefaults()`
chain now includes this comparer automatically.

## 2.35.1

**`(fix):`** Add `ReadAsPropertyName` and `WriteAsPropertyName` overrides to the generated
`IStringEnum` JsonConverter. Without these overrides, `System.Text.Json` throws
`NotSupportedException` at runtime when serializing or deserializing a
`Dictionary<TStringEnum, TValue>`. This is applied to all generated `IStringEnum`
types so dictionary-key usage works without requiring regeneration.

## 2.35.0

**`(fix):`** Fix WebSocket binary message sending. Binary messages (e.g. audio bytes) are now
sent as raw bytes instead of being JSON-serialized, which caused servers to reject
them with CONFIG\_DENIED.

**`(fix):`** Fix WebSocket incoming message deserialization. `TryDeserialize` now passes
`JsonSerializerOptions` so the generated literal property setters correctly
validate const discriminator fields (e.g. `type: "transcript"` vs `type: "flushed"`)
during deserialization.

**`(feat):`** Add forward-compatible `UnknownMessage` event to WebSocket clients. When the server
sends an event type not recognized by the SDK, it is now dispatched to the
`UnknownMessage` event handler (as a `JsonElement`) instead of raising an exception.
This allows SDKs to gracefully handle new server event types without requiring
regeneration.