4.0.0

(feat): Breaking change for WebSocket users only. REST-only SDKs are unaffected — no code changes required.

Overhaul generated WebSocket clients. The generated API is restructured around a factory → configure → connect lifecycle that separates client creation from connection parameters:

1// Create client from the service tree — no connection params yet
2V1WebSocketClient ws = client.listen().v1WebSocket();
3
4// Register handlers before connecting
5ws.onListenV1Results(results ->
6 System.out.println(results.getChannel().getAlternatives()));
7ws.onError(error -> error.printStackTrace());
8
9// Connect with channel-specific options (required params enforced at compile time)
10ws.connect(V1ConnectOptions.builder()
11 .model(ListenV1Model.NOVA3)
12 .encoding(ListenV1Encoding.LINEAR16)
13 .sampleRate(16000)
14 .build());
15
16// Stream audio and disconnect
17ws.sendMedia(audioBytes);
18ws.disconnect();

Query parameters move from constructor to connect(). The factory method (client.listen().v1WebSocket()) now takes no channel-specific arguments. All query parameters are passed via a builder-pattern ConnectOptions object to connect(), matching the Python SDK’s design. Required parameters use staged builders so missing fields are caught at compile time.

AutoCloseable — clients implement AutoCloseable for try-with-resources, calling disconnect() automatically on scope exit.

Configurable reconnectionreconnectOptions(ReconnectOptions) lets callers tune max retries, backoff delay, and queue size before calling connect().

Generic onMessage(Consumer<String>) handler — fires for every incoming text frame with the raw JSON string, before type-specific dispatch. Useful for logging or custom routing.

Binary WebSocket support — channels that define binary messages now generate typed send and receive methods. Binary frames queue when disconnected and flush on reconnect, matching text behavior.

Shared core typesDisconnectReason and WebSocketReadyState are generated once in the core package instead of duplicated as inner classes inside every WebSocket client.

Thread safety — all handler fields are now volatile so handlers registered from the main thread are visible to OkHttp callback threads. Previously only readyState was volatile.

x-fern-sdk-method-name support — WebSocket send/receive methods use the custom method name from the Fern config when set.

Also removes the deprecated hasWebSocketInstance() method and fires onError for unrecognized incoming message types instead of silently dropping them.

(fix): Fix WebSocket connect() crashing with NullPointerException when the environment URL uses wss:// or ws:// schemes. OkHttp’s HttpUrl.parse() only accepts http/https, so the client now rewrites the scheme before parsing and null-checks the result.

(fix): Fix WebSocket clients always calling environment().getUrl(), which does not exist on multi-URL environment classes. The generator now resolves the correct per-URL getter (e.g. environment().getAgentURL()) based on the channel’s baseUrl field in the IR, matching the pattern already used by REST endpoints.

(fix): Fix WebSocket clients not sending authentication headers when the channel’s auth field is false in the IR. Previously, headers were only applied when websocketChannel.getAuth() was true. connect() now unconditionally applies clientOptions.headers() to the upgrade request, ensuring bearer tokens, API keys, and custom headers are always sent regardless of the channel’s auth configuration.

(fix): Fix WebSocket message serialization wrapping every outgoing message in a {"type": "...", "body": {...}} envelope and expecting the same format for incoming messages. Messages are now serialized directly as flat JSON (the discriminated union already contains the type field), and incoming messages are deserialized from the root JSON object instead of extracting a nested body sub-field.

(fix): Fix binary file upload endpoints (application/octet-stream) serializing the request body through Jackson, which corrupted binary data with JSON string escaping. These endpoints now send raw bytes via InputStreamRequestBody.

3.44.6

(fix): Fix duplicate discriminator keys in union serialization. When a discriminated union variant uses @JsonUnwrapped and the wrapped object already contains the discriminant property (e.g., “type”), the serialized JSON previously contained the key twice. The generator now adds a field-level @JsonIgnoreProperties annotation with allowSetters = true on @JsonUnwrapped fields to suppress the duplicate during serialization while preserving deserialization.

3.44.5

(fix): Fix floating-point serialization of integer-valued doubles. Values like 24000.0 are now serialized as 24000 instead of 24000.0 in JSON output. This prevents API rejections for fields defined as type: number when the value happens to be a whole number. Non-integer double values like 3.14 continue to serialize normally.

3.44.4

(fix): Fix dynamic snippet compilation errors for objects with required fields in staged builders. When an endpoint example omits a required property, the snippet generator now fills in a type-appropriate default value instead of producing an invalid .builder().build() call that skips mandatory builder stages.

(fix): Fix dynamic snippet builder ordering when default values are added for missing required properties. Properties are now re-sorted to match schema declaration order after defaults are injected, ensuring Java staged builder method calls follow the correct sequence.

(fix): Fix undiscriminated union variant matching selecting incorrect variants when example data doesn’t match. Required properties and their nested types are now validated during matching, so variants with mismatched enum values or missing required fields are correctly rejected.

(fix): Fix hardcoded com.seed.api.core.OptionalNullable import in generated README OptionalNullable documentation. The import now uses the correct dynamic package name for the SDK being generated.

(fix): Fix incorrect raw response type name in generated README. The “Access Raw Response Data” section now uses the correct {BaseNamePrefix}HttpResponse class name (e.g., Auth0ApiHttpResponse) instead of the endpoint-derived name (e.g., CreateHttpResponse).

(fix): Fix missing environment URL variables in generated README Usage example. Builder parameters like tenantDomain from OpenAPI server URL templates are now included in the Usage snippet alongside auth parameters.

3.44.3

(fix): Fix auth header prefix missing trailing space.