Changelog
2.90.1
(fix): XML (TwiML) record types implement value equality: Equals/GetHashCode (and ==) compare the
rendered XML, so VoiceResponse.FromXml(xml).Equals(VoiceResponse.FromXml(parsed.ToXml())) and
new Say { Message = "x" }.Equals(new Say { Message = "x" }) are true. Previously the record
default compared the collection members by reference and was always false.
2.90.0
(feat): Add opt-in user-agent-only config. When enabled, generated clients send the User-Agent
header (including the structured form from include-platform-headers) 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.
2.89.0
(feat): The generated WebhooksHelper HMAC verifier now accepts a per-call algorithm override via an optional algorithm parameter on verifySignature,
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.
2.88.0
(feat): XML (TwiML) types keep text segments, typed child elements and raw XmlElement children in a
single ordered Content list, so ToXml() emits them in the order they were added
(Response.Say(a).AddChild(custom).Say(b) yields <Say>a</Say><Custom /><Say>b</Say>) and
FromXml() preserves document order, including the position of unknown elements and repeated
wrapper elements. Adds AddText(string) to XML types and XmlElement for mixed content such as
<Say>Hi <break strength="weak" /> world</Say>. Typed child properties and AdditionalChildren
remain available; AdditionalChildren is now derived from Content.
2.87.0
(feat): Support SDK variables (variables in api.yml / x-fern-sdk-variables in OpenAPI). Path
parameters bound to a variable via x-fern-sdk-variable are removed from endpoint
signatures and request types and are configured once on the client through the generated
ClientOptions.<Variable> property. String variables that declare an env fall back to that
environment variable, and a variable that is still unset fails with a clear
ArgumentException before the request is sent.
2.86.3
(fix): XML-encoded (TwiML) types now return their XML representation from
ToString() instead of JSON, and ToXml() prepends the
<?xml version="1.0" encoding="utf-8"?> declaration by default.
Pass ToXml(xmlDeclaration: false) to omit it.
2.86.2
(fix): Fix RequestOptions.AdditionalBodyProperties throwing InvalidOperationException on endpoints
without a request body (e.g. GET requests). When the request body is null, the additional
properties are now sent as the JSON request body.
(fix): RequestOptions.AdditionalBodyProperties is now applied to form-urlencoded requests. The additional
properties are merged into the form body (the additional property wins on a key collision) before
encoding. Multipart requests remain unsupported.
2.86.1
(chore): Bump bundled @fern-api/generator-cli to 0.10.3. When the hosted auto-version analysis of the
full SDK diff fails, generator-cli now retries chunk-by-chunk instead of silently applying a
PATCH bump; any remaining unavailable or incomplete analysis adds a “Version bump not verified”
notice to the SDK PR body and disables automerge.
2.86.0
(feat): Fluent child methods on XML-encoded (TwiML) types (e.g. response.Say(...), say.Break(...))
now carry <param> documentation for every argument, taken from the child type’s property
descriptions, and include the child type’s own description in the method summary.
2.85.0
(feat): Generate the shared WebhooksHelper from the API-wide api.settings.webhook-signature
setting in generators.yml (IR sdkConfig.webhookSignatureVerification). The helper is
emitted even when the API definition models no webhooks; webhook-specific signature
overrides still produce their own named helpers.
2.84.3
(fix): RawClient now applies the configured Timeout to each retry attempt individually instead of
sharing a single budget across all attempts and backoff delays. Note that Timeout therefore no
longer bounds the total duration of a call that is retried; the worst case is roughly
Timeout * (MaxRetries + 1) plus backoff. If a retry attempt fails after an earlier attempt
already received an API response (e.g. a 429), that response is returned instead of a generic
cancellation error.
2.84.2
(chore): Bump bundled @fern-api/generator-cli to 0.10.1. Auto-versioned MAJOR/MINOR bumps no longer
produce a version-only changelog.md block when the AI analysis returns an empty changelog
entry; the PR description, version bump reason, or commit message body is used instead.
2.84.1
(fix): Honor the org-level whitelabel setting (readmeConfig.whiteLabel) and the apiName/disabledSections (IR disabledFeatures) readme
config options when generating README.md. Previously the “Built with Fern” badge was always emitted.
2.84.0
(feat): Object types with XML encoding metadata (e.g. TwiML) now implement IXmlNode with ToXml()/ToXElement(),
static FromXml(string)/FromXElement(XElement) parsers, and fluent child builder methods
(response.Say("Hello", voice: "man").Dial(...)). Unknown attributes and child elements are preserved in
AdditionalAttributes/AdditionalChildren and re-emitted; AddChild(XmlElement) adds arbitrary elements.
Parsing rejects malformed XML, mismatched root elements and DTDs. Types without XML metadata are unchanged.
2.83.3
(fix): Fix the generated root client passing a grantType argument to OAuthTokenProvider
when the token endpoint declares a required, non-literal grant_type property.
OAuthTokenProvider hardcodes grant_type: "client_credentials" and never took that
parameter, so the generated SDK failed to compile with
'OAuthTokenProvider' does not contain a constructor that takes 4 arguments.
2.83.2
(fix): Stop dropping the examples of endpoints whose request body is bytes or a file upload. The IR’s
ExampleRequestBody cannot carry those bodies, so such examples read as bodyless and the
endpoint lost its snippets and generated tests.
2.83.1
(fix): Honor the x-fern-retries: { disabled: true } extension (retries: { disabled: true } in a Fern
definition) at the endpoint level. Requests for those endpoints are now sent exactly once, even when
the client or the per-request options configure retries.
2.83.0
(feat): Added a generate-documentation-file config option (default true) so the
generated csproj emits XML documentation and the published NuGet package ships
lib/<tfm>/<Namespace>.xml, giving consumers IntelliSense. CS1591 is
suppressed so enabling documentation does not introduce warnings for
undocumented members.
(feat): Added a package-metadata config block for NuGet metadata written into the
generated csproj: description, authors, tags, copyright, icon,
project-url, repository-url, repository-type, include-source-link
(adds Microsoft.SourceLink.GitHub) and include-symbols (produces a
.snupkg).
2.82.1
(fix): Global headers typed as a literal<"..."> with an env fallback no longer throw when
neither the constructor parameter nor the environment variable is set. The literal is
known at compile time, so it is now used as the header’s default value.
(fix): The generated X-Fern-SDK-Version header value is now emitted as a globally qualified
reference, so it can no longer be shadowed by a constructor parameter or local that
PascalCases to Version (previously error CS1061: 'string' does not contain a definition for 'Current').
2.82.0
(fix): With respect-optional-request-body enabled, examples that omit an optional request body are no
longer dropped from the generated snippets and reference.
(feat): Add a respect-optional-request-body option. When enabled, an endpoint whose request body the API
does not require takes that body as Body? request = null, so the caller can leave the argument out
and the request is sent with no body and no body content type. Examples that supply no body render
as client.BulkRefundAsync(). The option defaults to false, so existing signatures and snippets are
unchanged.