> This page is for SDK, version Legacy.
> For other versions, use one of these documentation indexes:
> - Current (default): https://buildwithfern.com/learn/sdks/current/llms.txt
> - Legacy: https://buildwithfern.com/learn/sdks/legacy/llms.txt

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

# Changelog

## October 16, 2026

## 1.70.7

**`(fix):`** Multipart form requests now send enum fields as plain form values (`DUE_DILIGENCE`)
instead of JSON-encoded strings (`"DUE_DILIGENCE"`), matching the other SDKs.
Lists of enums are sent the same way, one plain part per value.

## 1.70.6

**`(fix):`** `WebhooksHelper.verifyRequest` now parses `name=value` settings headers when
`webhook-signature.algorithm-header` sets `key-id-parameter`/`algorithm-parameter`
(e.g. Twilio's `X-Twilio-Webhooks-Signature-Settings: key=<id>,algorithm=HMAC_SHA256`),
so the key resolver receives the bare key ID instead of `key=<id>`. Requires IR 67.33.0.

## October 14, 2026

## 1.70.5

**`(fix):`** Format `date` and `date-time` path parameters before encoding them into the request URL.
Previously a `date` path parameter was sent as Go's default `time.Time` string
(e.g. `/schedule-by-date/2023-01-15%2000:00:00%20+0000%20UTC`) instead of `2023-01-15`.

**`(fix):`** Generated wire tests now expect object, map, and list query parameters in the same
`key[field]=value` form the SDK sends, instead of comparing against `"[object Object]"`.

## October 13, 2026

## 1.70.4

**`(fix):`** The generated `WebhooksHelper` now consumes `algorithm-header` from `api.settings.webhook-signature`:
a request-level `verifyRequest` helper reads the configured signature header first (missing or empty
fails early with "could not run: missing signature header"), then the algorithm-selection header
(e.g. `X-Twilio-Webhook-Signature-Settings: <key_id>;HMAC_SHA256`) to pick the HMAC algorithm from
the configured wire values and hand the key ID to an application-supplied secret resolver. When the
header is absent the configured default algorithm and the plain secret are used, so legacy
auth-token flows keep working. Following `VerifySignature`, the Go helper reports these early
failures as `(false, error)` rather than logging. `VerifySignatureWithAlgorithm` additionally accepts
the configured wire values alongside the generic algorithm names.

## October 12, 2026

## 1.70.3

**`(fix):`** Unknown JSON keys that match a declared field's wire name case-insensitively (e.g. `VALUE` next to a
declared `value`) are no longer kept in `ExtraProperties` when decoding, so they are not re-emitted
after the declared field on encode. Case-insensitive, last-wins decoders such as Go's `encoding/json`
would otherwise read the re-emitted key instead of the declared field. `MarshalJSONWithExtraProperties`
now also rejects extra properties that collide case-insensitively with a declared key. Unknown keys
that don't collide (e.g. `brand_new_field`) are still preserved and round-tripped.

## October 8, 2026

## 1.70.2

**`(fix):`** SSE unions discriminated by the `event:` line (`x-fern-discriminator-context: protocol`) now parse
both variant styles: envelope variants (`{event, data: Payload}`) are built from the `data:` JSON,
and payload variants (the `data:` JSON itself) get the `event:` value injected as the discriminant.
The event name no longer has to be repeated inside the `data:` JSON.

## 1.70.1

**`(fix):`** Fix uncompilable streaming methods when `errorCodes: per-endpoint` is set and the endpoint declares no
specific error responses. The streaming call no longer references the global `ErrorCodes` variable, which
is not generated in per-endpoint mode.

## October 7, 2026

## 1.70.0

**`(feat):`** XML (TwiML) types can now carry XML comments. `Comment(text)` adds `<!--text-->` inside the element at its
position in the ordered content (interleaved with `AddText` segments and child elements), while
`CommentBefore(text)` / `CommentAfter(text)` render a comment immediately before or after the element
itself (as a sibling in its parent, or around the root element after the XML declaration). Comments in
parsed documents are preserved by `FromXml` and round-trip through `ToXml`; `XmlElement.AddComment` and
the new `core.XmlComment` node expose the same for untyped elements.

## October 6, 2026

## 1.69.1

**`(fix):`** Enum-typed attributes and text on XML (TwiML) types are open on the wire: `FromXml` keeps a value the enum does
not declare (e.g. a voice added after the SDK was generated) instead of returning an error, and it round-trips
through `ToXml`. This matches how the same enums already behave in JSON.

## 1.69.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. `omitFernHeaders` still takes precedence and drops
the `User-Agent` too.

## 1.68.0

**`(feat):`** The generated `WebhooksHelper` HMAC verifier now accepts a per-call algorithm override via a `VerifySignatureWithAlgorithm(...)` method (`VerifySignature` keeps the configured default),
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.

## 1.67.0

**`(feat):`** XML (TwiML) types keep text segments, typed child elements and raw `core.XmlElement` children in a
single ordered `Content` slice, 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 `core.XmlElement` for mixed content such
as `<Say>Hi <break strength="weak" /> world</Say>`. Typed child properties and `ExtraChildren`
remain available and are reconciled into `Content` on serialization.

## 1.66.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 wrappers and are configured once on the client with the generated
`option.With<Variable>(...)` helper (also accepted per request). Variables that declare an
`env` fall back to that environment variable, and a string variable that is still unset
fails with a clear error before the request is sent.

## October 5, 2026

## 1.65.3

**`(fix):`** XML-encoded (TwiML) types now return their XML representation from
`String()` instead of JSON, and `ToXml()` prepends the
`<?xml version="1.0" encoding="UTF-8"?>` declaration. Use
`ToXmlElement().ToXml()` to serialize without the declaration.

## 1.65.2

**`(fix):`** `option.WithBodyProperties` now overrides generated request fields that share the same wire-format key
instead of returning a `cannot add extra property` error, so you can force or replace any JSON or form URL
encoded request body property. The generated README documents the option in a new "Additional Body
Properties" section, including that it isn't applied to multipart file upload or raw byte requests.

## October 2, 2026

## 1.65.1

**`(fix):`** The generated README's client snippets use the configured client constructor (`clientName`,
`exportedClientName`, `clientConstructorName`) instead of always writing `client.NewClient`,
and the Environments section of a multi-URL SDK passes the environment through
`option.WithEnvironment` instead of `option.WithBaseURL`, which takes a string and does not
compile against an environment struct.

## 1.65.0

**`(feat):`** Add the opt-in `legacyNullableAliasPointers` custom config option. When enabled, optional or
nullable fields that reference an alias which already renders as a Go pointer
(e.g. `type DiscoveryURL = *string`) keep the outer pointer (`*DiscoveryURL`), matching
SDKs generated before v1.46.1. Field types, setters, and code snippets all use the legacy
shape. The option is off by default, so existing output is unchanged.

## October 1, 2026

## 1.64.3

**`(fix):`** Restore pointer types for optional fields that reference a nullable list, map, or
`unknown` alias (for example a `type: [object, "null"]` schema with
`additionalProperties`, or a `type: [array, "null"]` schema). Since 1.46.1 these
fields were generated as bare values (`Metadata MetadataAlias`) instead of
pointers (`Metadata *MetadataAlias`), which was a breaking change for existing
SDKs. The double-pointer guard now only applies to aliases that actually render
as Go pointers (nullable primitives, enums, objects, and unions). Dynamic snippets
now render `&Alias{...}` literals for these fields (including aliases of such
aliases), take the address of `unknown` alias values, and no longer emit `&&` for
aliases that already render as pointers.

## September 30, 2026

## 1.64.2

**`(fix):`** Return a completed HTTP response instead of discarding it when the request
context is canceled after the response has been fully received but before
it is decoded. `Caller.Call` previously re-checked `ctx.Err()` at that point
and returned `context.Canceled` / `context.DeadlineExceeded` with a nil
response, which dropped valid responses that had already been buffered (for
example by a logging `http.RoundTripper` that ends its scope before
returning). Calls canceled before the request is sent, and calls whose
response body cannot be read to completion once the context ends, continue
to fail with the context's error, and a canceled context still never
triggers a retry.

**`(fix):`** Fix undiscriminated union deserialization so JSON objects are matched to the correct object
member. Previously, the first object member always won because object `UnmarshalJSON` accepts
unknown keys and doesn't enforce required keys, so values like `{"ends_with": [...]}` were
decoded as an earlier member and silently corrupted on re-serialization. Object members
(including aliases to objects) that don't allow extra properties are now only selected when
the JSON keys are a subset of the member's properties and include all of its required
properties, and permissive object members no longer shadow a later member that matches
exactly. If no member matches exactly, object members whose required keys are present are
tried next, and the previous behavior is kept as the final fallback.

**`(fix):`** Preserve explicit `null` on optional nullable (`optional<nullable<T>>`) object
properties across a JSON decode/re-encode round trip. Previously only required
nullable properties were tracked on decode, so a response field such as
`"holder_category": null` was dropped when the value was marshaled again.
Fields absent from the input remain absent, and plain `optional<T>` fields are
unaffected. The generated `<type>RequiredNullableFields` map is renamed to
`<type>NullableFields`, and generated SDKs now include an optional-nullable
round-trip test for each affected type.

## September 29, 2026

## 1.64.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.

## September 25, 2026

## 1.64.0

**`(fix):`** Object type descriptions are now written directly above the `type X struct` declaration
so `go doc` and editors attach them to the type. Previously the comment landed above the
internal field-bitmask `var (...)` block emitted before the struct.

**`(feat):`** Fluent child methods on XML-encoded (TwiML) types (e.g. `response.Say(...)`,
`dial.AddNumber(...)`) now name the appended element and include the child type's
description in their doc comment.

## 1.63.0

**`(feat):`** Generated error types that carry a body now expose a nil-safe `GetBody()` accessor that
returns the same type as the `Body` field. This lets callers handle every status-specific
error through a single interface-based `errors.As`, e.g.
`type bodyProvider interface{ GetBody() *ErrorBody }`. Errors without a body are unchanged.

**`(fix):`** `reference.md` now documents enum-typed query parameters, headers, and inlined request body
properties (including lists of enums) with the same value types used on the generated request
structs (e.g. `[]acme.CountryCode` instead of `[]*acme.CountryCode`).

**`(fix):`** Generated request types with `date` or `datetime` properties now decode those properties
through `internal.Date` / `internal.DateTime` in `UnmarshalJSON`, matching what their
`MarshalJSON` already emits. Previously `json.Unmarshal` into such a request type rejected
date-only values (e.g. `{"start_date":"2026-01-02"}`) that the type itself had produced.
Request types without date properties are unchanged.

## 1.62.1

**`(fix):`** Point the "Neither an import path nor a module path was specified" warning at the
Go generator README in the fern monorepo; the old `fern-api/fern-go` link now 404s.

## September 24, 2026

## 1.62.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.

## September 23, 2026

## 1.61.0

**`(feat):`** Errors declared with a `4XX` or `5XX` wildcard status code are now decoded into their typed
error struct for any status in the 400-499 / 500-599 range. A concrete status code declared
alongside a wildcard always wins, and a body that fails to decode as the wildcard error's
schema still returns the untyped `*core.APIError`.

## September 22, 2026

## 1.60.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.

## 1.60.1

**`(fix):`** `DateTime.MarshalJSON` now formats with `time.RFC3339Nano`, so fractional seconds
survive a decode/encode round-trip. Whole-second values marshal byte-identically
to before because `.999999999` omits trailing zeros.

**`(fix):`** `Date.UnmarshalJSON` now accepts date-time input (e.g. `2025-02-15T00:00:00Z`) as
a fallback, preserving the calendar date exactly as written and discarding the time.

## September 21, 2026

## 1.60.0

**`(feat):`** Add XML support for xml-encoded object types (e.g. TwiML). Generated types gain
`ToXml()`/`ToXmlElement()`, `<Type>FromXml(string)`/`<Type>FromXmlElement(...)`,
fluent child builders (e.g. `response.Say(...)`, `Add`-prefixed on collision), and
`ExtraAttributes`/`ExtraChildren` to round-trip unknown attributes and elements.
A standard-library `core/xml.go` runtime is emitted only when xml-encoded types exist.

## September 17, 2026

## 1.59.0

**`(feat):`** Generate wire tests for endpoints that return a file download (`io.Reader`). The generated
test calls the raw client, asserts the served `Content-Type`, reads the stream to completion and
compares the bytes against the fixture. The WireMock mapping for these endpoints now serves a
real binary payload (a small valid PDF via `base64Body`, `application/octet-stream`) instead of
the JSON string `""` with `Content-Type: application/json`. This also applies to OpenAPI-imported
endpoints whose only autogenerated examples are error responses (e.g. Plaid's `/asset_report/pdf/get`).

## September 14, 2026

## 1.58.1

**`(fix):`** Preserve required-nullable fields that arrive as `null` when a decoded model is
marshaled again. Generated `UnmarshalJSON` now records which required-nullable
keys were present in the incoming JSON (via a per-type wire-name-to-field-bit
table) so that `MarshalJSON` re-emits them as `null` instead of dropping them.
Fields absent from the input stay absent, and freshly constructed values
(e.g. request bodies) serialize exactly as before.

## September 10, 2026

## 1.58.0

**`(feat):`** Add the `enableNestedRequestBodyPagination` configuration option, which extends
`enableRequestBodyPagination` to page properties that live inside nested request objects, e.g.
`offset: $request.options.offset`. Such endpoints previously generated without a pager, so the
option defaults to `false` to preserve their existing return types.

```yaml
- name: fernapi/fern-go-sdk
  config:
    enableRequestBodyPagination: true
    enableNestedRequestBodyPagination: true
```

The generated pager advances the page on a copy of the request and allocates any optional
intermediate object the caller left nil (`Options: nil` and `Options: &Options{Count: &n}` both
work), across any nesting depth and through aliases to objects, without mutating the caller's
request.

_Showing the 20 most recent of 238 entries. Append `/llms.txt` to the changelog URL for the complete index._