Changelog

3.88.3

(fix): Respect custom OAuth token headers and prefixes for client credentials authentication.

3.88.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 reference.md section, snippets and docs comments.

(fix): Positional path parameters that an example does not supply are now rendered with their client-default value instead of undefined, so generated snippets typecheck.

3.88.1

(fix): Endpoints that disable retries (x-fern-retries: { disabled: true } in OpenAPI, or retries: { disabled: true } in a Fern definition) now always emit maxRetries: 0, overriding both client-level and request-level maxRetries. Previously this configuration was only honored by the Python SDK generator and was silently ignored in TypeScript.

3.88.0

(fix): With respectOptionalRequestBody enabled, examples that omit an optional request body are no longer dropped from the generated reference, snippets, and docs comments.

(feat): Add respectOptionalRequestBody. With it enabled, an endpoint whose request body the API does not require takes an optional body parameter — refund(id: string, request?: RefundRequest) — keeping the body’s own type rather than widening it to RefundRequest | undefined, and sending no body when the caller omits it. Examples that supply no body render as client.refund(id), and the generated wire test for such an example no longer asserts a request body. Defaults to false, so signatures and snippets are unchanged until you opt in.

3.87.4

(fix): Skip endpoint examples that omit a request body the endpoint declares. The generated request type requires the body, so rendering such an example produced a call missing a required argument in the reference, the docstrings, the snippets and the generated tests.

3.87.3

(fix): Fix dynamic snippets emitting a dangling argument delimiter (e.g. client.refunds.refund("id", )) when an example omits the request body.

3.87.2

(fix): Send the caller’s request when fetching the first page of a next_uri/next_path paginated endpoint. Previously the first page was requested through the same headers-only helper used for subsequent pages, so query parameters, request bodies and requestOptions.queryParams were silently dropped (and the unused request parameter was emitted as _request). Subsequent pages keep using the next URL as-is.

3.87.1

(fix): The appInfo User-Agent helper emitted when allowUserAgentAppInfo is enabled no longer uses a control-character regex range, so generated SDKs lint cleanly under rules such as Biome’s noControlCharactersInRegex without a suppression comment. Escaping behavior is unchanged.

3.87.0

(feat): Add a requireBaseUrl config option. When enabled, baseUrl is a required client option and environment is optional, for APIs whose users always pass an explicit server URL. Generated snippets, README, and wire tests use baseUrl accordingly. The option is ignored for APIs with multiple base URLs, whose clients resolve each URL from environment. Defaults to false, so existing SDKs are unchanged.

3.86.0

(feat): Add opt-in allowUserAgentAppInfo config. When enabled, generated clients accept an appInfo: { name, version?, comment? } option whose product token is appended to the User-Agent header ({sdk}/{version} ... {product}/{product-version} ({comment})), following RFC 9110. Disabled by default, so existing generated output is unchanged, and it composes with includePlatformHeaders, the user-agent template config, and the default {package}/{version} value. Caller-supplied values are token-encoded.

3.85.2

(fix): Respect the user-agent config template when includePlatformHeaders is enabled. The structured User-Agent previously always used the npm package name and version, ignoring the configured template.

3.85.1

(fix): Fixed the generated wire tests for endpoints that use offset pagination. The tests asserted page.hasNextPage() was true for every example, but the generated client reports no next page when the response returns fewer items than the requested page size (the pagination step), or when the response’s has-next-page property is false. The wire test now evaluates the same condition against the mocked response, and only asserts hasNextPage()/getNextPage() when a next page is actually expected.

3.85.0

(feat): Add an opt-in optional-auth config flag. When enabled, client auth parameters are made optional even when the API spec mandates auth on all endpoints (isAuthMandatory=true), so the client can be constructed without credentials. Requests are then sent unauthenticated when no credentials are supplied, instead of throwing from the auth provider. Useful for hand-maintained wrapper clients that authenticate via external means (e.g. cloud provider credentials). Defaults to false, so existing behavior is unchanged.

3.84.0

(feat): Generated error classes now redeclare the body property with the error’s typed body (e.g. public declare readonly body: MyErrorBody;) instead of inheriting body?: unknown from the base API error class. This makes err.body.<field> type-check in catch blocks without casting when the error has a declared body schema.

3.83.2

(fix): Global headers declared with an env now fall back to that environment variable at runtime. The resolution order for a global header is the explicit option, then the environment variable, then the client default.

3.83.1

(fix): Scope the passthrough client.fetch() auth headers to the configured base URL. Auth headers are now only attached when the resolved request URL has the same origin as the configured base URL (or environment), so passing an absolute cross-origin URL into the passthrough fetch escape hatch no longer leaks the SDK’s credentials to an unrelated host. Relative paths and same-origin absolute URLs are unaffected. Passthrough debug logs now redact credentials in the request URL, matching the main fetcher.

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.