4.37.6
(fix): README generation in self-hosted GitHub mode can clone a private repository with a personal
access token again. Upgrades @fern-api/generator-cli to 0.12.1, which also sends the token as an
Authorization header. Before this, git in the generator image (libcurl 8.23+) dropped the token
from the clone URL and failed with could not read Username.
4.37.5
(fix): XML (TwiML) builders keep the legacy meaning of a String setter whose name is shared by the element’s text
and a child element: Dial.builder().number("+15551234567") sets the text (<Dial>+15551234567</Dial>) as in
twilio-java, number(Number) adds the <Number> child and addNumber(String) adds a child with text; the
text property is no longer renamed to text (the text(...) alias stays).
4.37.4
(fix): XML (TwiML) serialization writes empty elements as <Hangup/> instead of <Hangup />, matching the legacy
twilio-java output byte for byte.
4.37.3
(fix): Discriminated union wrapper classes now annotate equals, hashCode and toString with
@java.lang.Override, matching the other generated types. Previously the bare @Override failed to
compile when the API defined a type named Override in the same package
(incompatible types: Override cannot be converted to Annotation).
4.37.2
(fix): Build core/ObjectMappers.JSON_MAPPER with new ObjectMapper().registerModule(...) instead of
JsonMapper.builder(), so generated SDKs run on Jackson 2.9.x (JsonMapper was the only
Jackson 2.10+ symbol in the generated code and failed with NoClassDefFoundError at runtime).
ObjectMappers.stringify() no longer mutates the shared mapper via
setSerializationInclusion(ALWAYS) (a no-op: ALWAYS is Jackson’s default and generated
models declare @JsonInclude(NON_ABSENT) at class level), and parseErrorBody() catches
IOException (the supertype readValue declares on 2.9) instead of JsonProcessingException.
Mapper configuration and serialized output are unchanged.
4.37.1
(chore): Re-publish the Java SDK generator: the 4.36.0 (retryOnStatusCodes) and 4.37.0 (retryDelays) images were never
pushed because the publish workflow broke on the new ubuntu-latest runner image (JDK 25); this release carries both
features with no further code changes.
4.37.0
(feat): Add retryDelays(List<Duration>) to ClientOptions.Builder and the generated root client builders (sync, async
and multi-auth stages) for an explicit retry schedule: the n-th retry waits for the n-th duration and the request
stops retrying once the list is exhausted, so the list size replaces maxRetries and the exponential backoff
settings. Delays are used as-is (no jitter); Retry-After / X-RateLimit-Reset headers still take precedence
for that attempt. Default behaviour is unchanged.
4.36.0
(feat): Add retryOnStatusCodes(Set<Integer>) to ClientOptions.Builder and the generated root client builders
(sync, async and multi-auth stages). It replaces the default set of HTTP status codes that trigger an automatic
retry (408, 429 and 5xx), so a consumer can retry only 429, or 429 and 503, and have other 5xx responses
returned as-is. The default is unchanged; maxRetries, the backoff settings and Retry-After handling are
unaffected.
4.35.1
(fix): XML (TwiML) builders match the legacy call shapes: when an element’s text property is named like one of
its child elements, the child builder keeps the name (message.body("hi") / body(Body) add a <Body>
child, dial.number("+1…") a <Number>) and the text property is generated as text (getText(),
text(...)); every builder with text content also accepts text(...) next to the field-named setter; and
format: uri string setters get a java.net.URI overload (redirect.url(URI.create("/voice"))).
4.35.0
(feat): Expose maxConcurrentRequests(int) on the generated root client builders (<Client>Builder,
Async<Client>Builder, and the multi-auth builder stages) so the in-flight request cap added in
4.34.0 can be set without constructing ClientOptions by hand, matching timeout and maxRetries.
Subclasses can override the new setConcurrencyLimit(ClientOptions.Builder) hook.
4.34.0
(feat): Add ClientOptions.Builder.maxConcurrentRequests(int), an opt-in cap on how many requests the SDK has in
flight at once. It applies to both the sync and the async client (OkHttp’s dispatcher limits only bound async
calls, and its connection pool only bounds idle connections) and also to an OkHttpClient supplied via
httpClient(...). A request holds a slot until its response body is closed; callers waiting for a slot are
bounded by the call timeout, and retries do not hold a slot during their backoff delay. Implemented by the new
generated core/ConcurrencyLimitingInterceptor.
4.33.0
(feat): Add the legacy-input-stream-upload-overloads option (default false). When true, single-file
upload endpoints get the InputStream overloads from before 4.23.2, such as
create(InputStream stream, String filename). These leave out the request object, so companion
multipart fields are not sent, as before 4.23.2.
4.32.7
(fix): Dynamic snippets now pass a placeholder for a required file the example doesn’t include
(new File("path/to/file")) and Optional.empty() for a missing optional file, instead of
null, which compiled but threw a NullPointerException in the SDK. This applies when
inline-file-properties is off and needs dynamic IR from a CLI that sets isOptional on file
properties; with older IR, missing files are still passed as null.
4.32.6
(fix): XML (TwiML) serialization drops characters outside the XML 1.0 Char production (e.g. \u0001) from text and attribute values instead of emitting XML that no parser accepts.
4.32.5
(fix): XML (TwiML) builders gain a varargs overload for list-valued attributes (gather.input(GatherInputItem.DTMF, GatherInputItem.SPEECH)), a static builder(text) factory for types whose text content is required
(Body.builder("hello")), and typed child overloads under the legacy name when only the text setter used it
(dial.number(Number) next to dial.number(String); addNumber(Number) is kept).
4.32.4
(fix): Path parameter values of exactly . or .. now throw an IllegalArgumentException before
the request is sent. OkHttp’s addPathSegment resolves these as dot-segments, so they could
change which endpoint the request was sent to. Values are checked by a new
core.PathSegments helper.
4.32.3
(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.
4.32.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.
4.32.1
(fix): Unknown JSON keys that match a declared property’s wire name case-insensitively (e.g. VALUE next to
value) are no longer kept in additionalProperties, so they are not re-emitted on serialization where a
case-insensitive, last-wins decoder downstream would read them instead of the declared field. Non-colliding
unknown keys are still preserved and round-tripped.
4.32.0
(feat): Support inferred bearer auth with type: refresh-token. The token supplier always sends
grant_type=refresh_token, and grantType is no longer a client builder option. Only the parameters of
the OAuth refresh token grant (refreshToken, scope, clientId, clientSecret) plus any required
ones are builder options and sent. Optional parameters of other grants on a shared token endpoint, such as
code, codeVerifier and redirectUri, stay on the token endpoint method only.