5.41.2
(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. The lower-level verifySignature is unchanged and still returns
false without throwing.
5.41.1
(fix): Models that keep unknown JSON keys no longer keep one that matches a declared field except for case
(e.g. VALUE next to value). Such a key used to be sent again after the declared field, so a
case-insensitive decoder on the receiving end (e.g. Go’s encoding/json) read it instead of the
field’s value. Other unknown keys (e.g. brand_new_field) are still kept and sent as before.
5.41.0
(feat): Wire tests now cover every example instead of only the first one per endpoint. Each user-specified
example gets its own test (or the first autogenerated success example when there are none), and when
none of an endpoint’s user examples is an error example, the autogenerated error examples are added
too. Error tests assert the typed error the client raises for the status code (or the base ApiError
when the client can’t dispatch to a typed error) along with its status_code and body. Each test is
served by its own X-Test-Id-scoped WireMock stub with the declared status code, and the test client
disables retries. Set wire_tests.fallback_to_autogenerated_error_examples: false to leave out
autogenerated error examples.
5.40.0
(feat): Support inferred bearer auth with type: refresh-token. The generated InferredAuthTokenProvider
always sends grant_type="refresh_token" to the get-token endpoint, and grant_type is no longer
a client constructor parameter. Users pass only the refresh token (and any other non-literal
token endpoint parameters).
(feat): Inferred auth now works next to other auth schemes (auth: any and endpoint-security) when it has
credentials of its own, e.g. a type: refresh-token scheme next to OAuth client credentials.
The client takes the inferred credentials as optional constructor parameters (shared ones such as
client_id are added once) and uses the inferred token provider when they are passed, so
Client(refresh_token=...) and Client(client_id=..., client_secret=...) both work.
5.39.5
(fix): Fix the root client docstring example for global headers and root path parameters
that have a client-default. The example now passes the default as a keyword
argument (e.g. version="2024-01-01") instead of a bare positional value, which
was a SyntaxError when it followed another keyword argument.
5.39.4
(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.
5.39.3
(fix): Stop automatically replaying requests after server disconnects or incomplete responses (httpx.RemoteProtocolError), which could duplicate non-idempotent POST/PATCH operations, even after a 200 status was received. Connection-establishment failures and HTTP-status retries are unchanged. Set request_options={"retry_remote_protocol_errors": True} only when replaying the request is safe to explicitly restore the previous behavior.
5.39.2
(fix): Generated core/pydantic_utilities.py now type-checks under pydantic 2.14, which made mypy report
var-annotated on the module-level TypeAdapter instances.
5.39.1
(fix): XML (TwiML) fluent child methods (response.say(...), gather.play(...), …) keep document order on
Python 3.12+. The ordered content list is a pydantic private attribute, and the runtime_checkable
Protocol used to find it stopped matching on 3.12 (where isinstance uses inspect.getattr_static),
so children appended by the fluent methods were ordered after text and add_child(...) elements, e.g.
r.say("a"); r.add_child(XmlElement("Custom")); r.say("b") rendered <Custom/><Say>a</Say><Say>b</Say>.
5.39.0
(feat): XML (TwiML) models can now carry XML comments. comment(text) adds <!--text--> inside the element at
its position in the ordered content (interleaved with add_text segments and child elements), while
comment_before(text) / comment_after(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 from_xml and round-trip through to_xml; XmlElement.add_comment
and the new XmlComment node expose the same for untyped elements.
5.38.0
(feat): Generate a unit test file per XML-encoded (TwiML) type alongside the models, covering
fromXml/toXml round trips, escaping, unknown attributes/children, open enum passthrough,
child ordering, and rejection of malformed XML, wrong root elements and DOCTYPE declarations.
5.37.2
(fix): XML (TwiML) child builders keep their legacy names when they collide with the element’s text
field: dial.number("+15551234567") and message.body("b") now work instead of raising
TypeError: 'NoneType' object is not callable. The text is still passed as the same constructor
keyword (Dial(number="+1555")) but is stored under a trailing underscore (dial.number_) so the
builder method stays callable; add_number/add_body are no longer generated.
5.37.1
(fix): List-valued XML (TwiML) attributes accept a single space-separated string in addition to
a list, matching the legacy call style: response.gather(input="speech dtmf") no longer
raises a validation error and serializes as input="speech dtmf".
5.37.0
(feat): Add opt-in user_agent_only config (also accepted as userAgentOnly). 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,
X-Fern-SDK-Version, X-Fern-Runtime, and X-Fern-Platform headers. Disabled by default,
so existing generated output is unchanged. omit_fern_headers still takes precedence and
drops the User-Agent too.
5.36.1
(fix): With endpoint-security auth, the client now fetches an OAuth or inferred-auth token only when the
endpoint’s security requirements reference that scheme. Previously every authenticated call fetched
one first, so an endpoint that doesn’t use it (e.g. the token endpoint itself) made an extra token
request and failed if that fetch failed.
5.36.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.
5.35.0
(feat): XML (TwiML) models keep text segments, typed children and undeclared XmlElement children in one
ordered content sequence, so to_xml() writes them in insertion order (say("a"), add_child(...),
say("b") renders <Say>a</Say><Custom /><Say>b</Say>) and from_xml() preserves document order,
including nested mixed content in undeclared children. Builders gain add_text(text) for mixed
content such as Say("Hi ").break_(...).add_text(" world"). Typed child properties and
add_child() keep working as before.
5.34.5
(fix): XML-encoded (TwiML) types now include the <?xml version="1.0" encoding="UTF-8"?>
declaration by default when serialized to XML; pass the declaration flag as false
to omit it. Nested child elements and raw XmlElements are still written without it.
5.34.4
(fix): On Python 3.10 and older, str() on a generated enum member now returns its value (e.g. WALMART_US)
instead of ClassName.WALMART_US, matching enum.StrEnum on Python 3.11+. Previously, enum query
parameters were sent as ClassName.MEMBER on those versions when enum_type: forward_compatible_python_enums
or python_enums was used.
5.34.3
(fix): Redact every header auth scheme’s header (e.g. PLAID-SECRET) in debug logs, in addition to
Authorization and API-key headers, and merge request headers case-insensitively so a
plaid-secret override replaces PLAID-SECRET instead of sending both.
(fix): Map 4XX/5XX wildcard error responses to their typed error classes (concrete status codes
still win) and keep the real HTTP status code on the raised error.