Changelog
3.83.0
(feat): Add support for webhook body-hash binding in the generated verifySignature helper.
When a webhook’s signature declares a body-hash binding, the helper now hashes the raw
request body and compares it to the hash transmitted separately as a query parameter on
the notification URL (e.g. Twilio’s bodySHA256) before verifying the HMAC signature.
Both checks must pass. The body-hash algorithm and encoding are independent of the outer
HMAC’s.
3.82.3
(fix): Fix server URL variable interpolation to render the selected environment’s URL
template instead of always using the first environment’s template. When a client
is constructed with both an environment and server URL variable values (e.g.
region), the base URL is now built from the selected environment’s template(s);
for multi-host environments every host’s template is formatted. An explicitly
provided baseUrl or custom environment value is no longer overridden.
3.82.2
(fix): Generated endpoint JSDoc now documents all thrown error paths: in addition to
the errors declared in the API definition, each method’s @throws annotations
include the base API error class (thrown for any undeclared HTTP error status
code) and the timeout error class (thrown when the request times out).
3.82.1
(fix): Send grant_type: "client_credentials" in the OAuth token request when the token
endpoint models grant_type as a plain (non-literal) string. Previously the
generated OAuthAuthProvider omitted grant_type entirely, so token requests
against OpenAPI-imported specs (where grant_type is an optional string rather
than a literal) failed. A required non-literal grant_type is no longer surfaced
as a user-supplied client-credentials option; it is synthesized automatically.
3.82.0
(feat): Add automatic idempotency-key generation, driven by the centralized
idempotencyKeyGeneration config in the IR. When enabled, the generated SDK attaches a
UUIDv4 idempotency-key header (default Idempotency-Key) to requests whose HTTP method is
listed in the IR (default POST/PUT). A caller-supplied key in request options still takes
precedence.
3.81.0
(feat): Add support for server URL variables (e.g. region/edge routing). Server variables
defined on the API’s environments are now exposed as optional string options on the
client constructor and interpolated into the base URL(s) at request time. Reserved
option names are de-collided by prefixing with serverUrl (e.g. a variable named
environment is exposed as serverUrlEnvironment).
3.80.2
(fix): Fix compile errors in the generated OAuthAuthProvider when the serde layer is
disabled: the token endpoint method is now called with the same camelCase name
that the generated client exposes (previously the original casing, e.g.
CreateOauth2Token, was used). Also guard against optional access_token
response properties so the token refresh path satisfies its Promise<string>
return type instead of string | undefined.
3.80.1
(fix): Make the structured User-Agent (emitted when includePlatformHeaders is
enabled) comply with the RFC 7230 token grammar. The npm package name is now
percent-encoded in the product token so the @ and / of a scoped package
are escaped (e.g. @dummy/sdk/0.0.1 becomes %40dummy%2Fsdk/0.0.1); the
original name can be recovered by URL-decoding. The architecture label is also
normalized so the 64-bit x86 aliases (x64, amd64, x86_64) all report as
the canonical x86_64.
3.80.0
(feat): Add opt-in support for a structured User-Agent header of the form
{sdkName}/{version} ({os}; {arch}) {runtime}/{runtimeVersion}, matching the
Twilio helper-library shape. This is gated behind the includePlatformHeaders
config option and is disabled by default, so existing generated output is
unchanged. When enabled, the platform + runtime information is consolidated
into the User-Agent and the discrete X-Fern-Runtime / X-Fern-Runtime-Version
headers are omitted. The platform group and runtime segment are dropped
gracefully in environments where they cannot be determined (e.g. browsers),
and the header remains subject to omitFernHeaders.
3.79.2
(fix): Pin the npm toolchain used by the generated publish workflow. The
.github/workflows/ci.yml publish job now runs on a pinned Node LTS
(node-version: "lts/Krypton") and calls npm publish directly instead
of npx -y npm@latest publish. Relying on npm@latest pulled whatever
npm release was newest at publish time, so a broken npm release could
break publishing. The pinned Node LTS bundles an npm that supports OIDC
trusted publishing. The npx semver invocation used for backport
detection is also pinned to semver@7.8.1.
3.79.1
(fix): Generated snippets now use baseUrl instead of environment when
no environments are defined in the API spec, matching the actual
constructor parameter users should provide.
3.79.0
(feat): Add a defaultTimeout custom config option, expressed in milliseconds, which is idiomatic for
JavaScript/TypeScript (setTimeout, AbortSignal.timeout(ms)). Use "infinity" to disable the
timeout. The seconds-based defaultTimeoutInSeconds and timeoutInSeconds keys are now
deprecated but continue to work: their values are converted to milliseconds (× 1000). Precedence
is defaultTimeout > defaultTimeoutInSeconds > timeoutInSeconds. Generated SDK output is
unchanged for existing configs.
3.78.2
(fix): Fix a regression where | undefined was dropped from the value type of generated
Record types backed by optional map values (e.g. optional additionalProperties).
Optional map values now correctly generate Record<string, T | undefined> with
serialization record(string(), T.optional()), while unknown/any map values
keep the redundant | undefined stripped (Record<string, unknown>).
3.78.1
(fix): Fix TypeError: Cannot use 'in' operator to search for 'path' in undefined
crash when null or undefined is passed to a file upload parameter at
runtime. The error is now a clear TypeError describing the expected types
instead of a cryptic in operator failure.
3.78.0
(feat): Add an additionalBodyParameters request option that spreads additional parameters into an
endpoint’s JSON request body. Caller-supplied properties override matching keys in the endpoint
body, matching the behavior of the Python, Swift, and Ruby SDKs. Omitting the option leaves the
request body unchanged and never fabricates a body for bodyless requests.
3.77.3
(fix): Revert the automatic renaming of inlined path parameters that collide with request
body properties (introduced in 3.77.1). These collisions are now rejected at the CLI
level: fern check errors and asks the user to deconflict the names (e.g. via
x-fern-parameter-name).
3.77.2
(fix): Fix ESM spec violations for extensionless imports in generated SDKs. The
rename-to-esm-files.js script now resolves bare directory imports
(e.g. from "./oauth" → from "./oauth/index.mjs") and extensionless
file imports (e.g. from "./client" → from "./client.mjs"), which
previously broke Node’s ESM loader and Turbopack (Next 16). Also sets
moduleResolution: "bundler" in tsconfig.esm.json for correct ESM
semantics.
3.77.1
(fix): When an inlined path parameter (inlinePathParameters: true) shares its property name with an
inlined request-body property (e.g. a {idType} path parameter and an idType body field),
the request wrapper now keeps both fields by renaming the path parameter with a PathParam
suffix (e.g. idTypePathParam). Previously the two values were collapsed into a single shared
field, which made it impossible to send different values for the URL path and the request body.
3.77.0
(feat): Implement SSE stream auto-reconnection for resumable endpoints. When an SSE
stream drops mid-connection and the endpoint is marked resumable: true, the
SDK now automatically reconnects using the Last-Event-ID header, honoring
server-sent retry directives clamped to 30 seconds. Reconnection respects
reconnectionEnabled and maxReconnectionAttempts options.
3.76.0
(feat): Add React Query hooks generation support via the generateReactQueryHooks config flag.
When enabled, generates a react-query/ directory with a tRPC-style namespace object
that mirrors the SDK client hierarchy (e.g. seedApi.user.list.useQuery()). Each query
endpoint exposes useQuery, useSuspenseQuery, getQueryKey, getQueryOptions (for SSR/RSC),
and invalidate. Mutation endpoints expose useMutation. Hierarchical cache invalidation
at endpoint, service, and SDK levels. Per-service file splits with wildcard subexports
for tree-shaking. All exports available via a ./react-query package.json subexport
with optional peer dependencies on react and @tanstack/react-query.