> This page is for SDKs.

> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://buildwithfern.com/learn/llms.txt.

## 4.29.0

**`(feat):`** Add opt-in `userAgentOnly` config. When enabled, generated clients send the `User-Agent`
header (including the structured form from `includePlatformHeaders`) but omit the
`X-Fern-Language`, `X-Fern-SDK-Name`, and `X-Fern-SDK-Version` headers. Disabled by default,
so existing generated output is unchanged. `omit-fern-headers` still takes precedence and drops
the `User-Agent` too.

## 4.28.0

**`(feat):`** The generated `WebhooksHelper` HMAC verifier now accepts a per-call algorithm override via a `verifySignature(...)` overload taking an `algorithm` argument,
one of `sha1`, `sha256`, `sha384` or `sha512`. When omitted, the algorithm configured in
`webhook-signature` is used, so existing callers are unchanged. This lets one endpoint verify both
legacy HMAC-SHA1 (auth-token) and HMAC-SHA256 (shared-key) signed webhooks.
The verifier also logs a warning distinguishing an early failure (missing signature header) from a
failed verification (signature mismatch); it still returns `false` and never throws.

## 4.27.0

**`(feat):`** XML (TwiML) types now keep their content in a single ordered sequence
(`List<XmlNode>` exposed via `getContent()`): typed child methods such as
`say(...)`, `addChild(XmlElement)` and the new `addText(String)` all append
to it, so `toXml()` emits typed children, generic children and text segments
in exactly the order they were added, and `fromXml()` preserves the original
positions. The text property (e.g. `message`) remains the leading text of the
element. New `XmlNode` core class; `XmlReader.leadingText`/`content` and
`XmlWriter.content` helpers.

## 4.26.0

**`(feat):`** SDK variables that declare an environment variable fallback (`env` in `api.yml` or `x-fern-env` on
`x-fern-sdk-variables`) now default to `System.getenv(...)` in the client builder, and `build()`
throws an `IllegalStateException` with a clear message when neither the builder method nor the
environment variable provides a value, instead of rendering `null` into request paths. The check
lives in the generated `setVariables(builder)` hook, so overriding it to supply the value still works.

## 4.25.0

**`(feat):`** Wire tests now cover error responses and every example, not just the first example's happy path.
Each endpoint gets one test per user-specified example. When none of an endpoint's user examples
is an error, the autogenerated error examples are added too. Error tests assert that the call throws
the typed error class (or the base API exception when the status code isn't declared) and check the
status code and error body. Success responses use the endpoint's declared status code instead of
always returning 200, and the test client is built with `maxRetries(0)`.
Set `wire-tests-fallback-to-autogenerated-error-examples: false` to leave out autogenerated error examples.

**`(fix):`** Wire tests now compile when the API has a type named `Test` or `Exception`. The test annotation
and `throws` clause use fully qualified names in that case, so they no longer clash with the imported API type.