跳到导航

Changelog

2.28.2

(fix): List-valued XML (TwiML) attributes accept a single space-separated string in addition to an array, matching the legacy call style: new Gather(['input' => 'speech dtmf']) and $response->gather(['input' => 'speech dtmf']) no longer throw a TypeError.

2.28.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 throwing, and it round-trips through toXml. This matches how the same enums already behave in JSON.

2.28.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.

2.27.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.

2.26.0

(feat): XML (TwiML) types keep text segments, typed child elements and raw XmlElement children in a single ordered content list, so toXml() emits them in the order they were added ($response->say(['message' => 'a']); $response->addChild(new XmlElement('Custom')); $response->say(['message' => 'b']); yields <Say>a</Say><Custom/><Say>b</Say>) and fromXml() preserves document order, including the position of unknown elements. Adds addText(string) to XML types and XmlElement for mixed content such as <Say>Hi <break strength="weak"/> world</Say>. Typed child properties and additional children remain available and are reconciled into the content order on serialization.

2.25.1

(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.

2.25.0

(feat): Add support for SDK variables (x-fern-sdk-variables / variables in api.yml). Each variable becomes an optional, named constructor parameter on the root client (also settable through the options array and per request). Path parameters bound to a variable are removed from endpoint method signatures and request classes and resolved from the client instead. String variables that declare an environment variable fall back to getenv() when no value is passed, and a clear InvalidArgumentException is thrown when a bound variable is still unset at call time.

2.24.2

(fix): Fix JsonSerializableType::jsonDeserialize throwing Unexpected non-string type for date. when a #[Date]-annotated property receives an explicit JSON null. Nullable date and date-time fields now deserialize null to null, matching how omitted keys and the serializer already behave; non-string, non-null values are still rejected.

2.24.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.

2.24.0

(feat): Inline documentation on XML-encoded (TwiML) types: constructors list every documented $values key with its description, fluent child methods carry the child type’s description and per-key docs for the $attributes/child array shape, and text parameters include the text property’s description.

2.23.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.

2.22.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.

2.22.1

(fix): Honor the org-level whitelabel setting (readmeConfig.whiteLabel) and the apiName/disabledSections (IR disabledFeatures) readme config options when generating README.md. Previously the “Built with Fern” badge was always emitted.

2.22.0

(feat): Object types with XML encoding metadata (e.g. TwiML) now extend XmlSerializableType and generate toXml()/toXmlElement(), fromXml()/fromXmlElement(), and fluent child builder methods ($response->say('Hello', ['voice' => 'man'])). Attributes, text, namespaces, prefixes, wrapped lists, separator-delimited lists and enums round-trip; unknown attributes and children are preserved and re-emitted, and parsing rejects DTDs, malformed input and wrong root elements. XML types add ext-dom/ext-libxml to composer.json and a Core\Xml runtime.

2.21.0

(feat): Add rejectEmptyDateTimeStrings (opt-in). deserializeDateTime("") returned the current wall-clock time rather than raising: PHP’s DateTime constructor treats an empty string as “construct for the current moment” and does not throw, so the surrounding catch never fired. Any API that sends "" to mean “not set” therefore produced a plausible, entirely fabricated timestamp with no way for the caller to detect it — a value that can be written back to a database and is indistinguishable from real data afterwards. A malformed string was always handled correctly; it was specifically the empty string that slipped through. The sibling deserializeDate already rejects "", so this also removes an inconsistency between the two. Opt-in because it turns a value callers currently receive into an exception.

2.20.4

(fix): Honor endpoint-level retries: { disabled: true } (x-fern-retries). Requests for those endpoints pin maxRetries to 0, so they are never retried regardless of the client-level or per-request retry options.

2.20.3

(fix): Fixed generated WireMock stubs for OAuth client credentials APIs whose token endpoint is itself marked as authenticated: the token (and refresh) endpoint stub no longer requires an Authorization header, since the token request is made to obtain the token and cannot carry one yet.

2.20.2

(fix): Global headers typed as a literal<"..."> with an env fallback no longer throw when neither the constructor parameter nor the environment variable is set. The literal is known at compile time, so it is now used as the header’s default value.

2.20.1

(fix): Render an empty body in snippets for an example that omits a request body the API does not require. The generated request wrapper still requires the body, so the snippet left the required key out and did not typecheck.

2.20.0

(feat): Add a respectOptionalRequestBody option. When enabled, an endpoint whose request body the API does not require lets the caller leave that body out of the call, and such a call sends neither a body nor a Content-Type header. refund(string $id, RefundRequest $request) becomes refund(string $id, ?RefundRequest $request = null), and a body carried in a request wrapper becomes an omittable property, so new RefundWithHeaderRequest([]) no longer throws. Snippets that supply no body render as $client->bulkRefund();. The option defaults to false, so existing signatures, output, and snippets are unchanged.