2.1.2

(fix): Fix generateClientInterfaces to generate interfaces for aggregator-only clients (clients that hold sub-client properties but have no direct API endpoints). Previously, these clients were skipped, leaving the top-level client and intermediate grouping clients without interfaces.

Interfaces now include typed getter method signatures for each sub-client (e.g., getUsers(): UsersClientInterface), and the corresponding client classes implement these getters.

2.1.1

(fix): Fix PHPStan static analysis errors in core runtime classes. Tightens return types (e.g., castKey now returns int|string instead of mixed), adds missing null checks, and improves PHPDoc annotations across JsonSerializer, JsonDeserializer, and Utils. Also fixes BaseApiException::__toString() to use getCode() instead of direct property access and print_r() for non-scalar body values.

(fix): Add of object bound to pagination template generics (CursorPager, OffsetPager) to satisfy PHPStan’s requirement for clone on object types.


2.1.0

(fix): Fix wire test generation for types with required constructor fields. Previously, the test generator would pass empty arrays [] as constructor arguments when no example values were provided for required fields (e.g., new SomeType([])). Now generates appropriate placeholder values based on each field’s type (e.g., new SomeType(['ids' => [1]])).

(feat): Add support for fileDownload (application/octet-stream) and bytes response types. Previously, endpoints returning binary data would throw an error at runtime because no success handling was generated. Now these endpoints return the raw response body as a string.


2.0.0

(feat): Introduce PSR-7/17/18 HTTP interfaces for framework-agnostic HTTP client support.

This restores the PSR-7/17/18 agnostic approach that was temporarily reverted in v1.30.0. The SDK now supports any PSR-18 compliant HTTP client (Guzzle, Symfony HttpClient, etc.) and uses php-http/discovery to automatically find an installed client at runtime.

Breaking changes are minimal, but do exist:

  • Guzzle is no longer a hard dependency (moved to suggest/require-dev)
  • Per-request timeout behavior may differ between HTTP client implementations (currently supported for Guzzle and Symfony)
  • Code that directly catches GuzzleHttp\Exception\RequestException will require a refactor

Migration: Existing Guzzle users should be largely unaffected as Guzzle implements PSR-18. For custom HTTP clients, ensure they implement PSR-18 interfaces.

1.30.0

(fix): Temporarily revert PSR-7/17/18 HTTP interfaces back to hard Guzzle dependency. This restores the pre-1.27.0 behavior where the SDK requires Guzzle as a hard dependency. Users should expect this to be re-introduced as a breaking change in v2.0.0.

This change reverts the framework-agnostic HTTP client support introduced in v1.27.0, restoring Guzzle middleware-based retry logic and direct Guzzle dependency.


1.29.1

(fix): Fix wire tests for paginated endpoints. Previously, wire tests called paginated SDK methods without iterating the returned Pager, so no HTTP request was made and WireMock verification always failed with “Expected 1 requests, found 0”. The generated test now iterates the Pager to trigger the first page request.

1.29.0

(feat): Add support for generating interfaces for all SDK client classes. When generateClientInterfaces: true is configured, each client {ClientName} gets a corresponding {ClientName}Interface with public method signatures. Concrete clients declare implements {ClientName}Interface. This enables standard PHP mocking and DI patterns (PHPUnit::createMock(), Laravel/Symfony DI containers) without requiring concrete class dependencies.

1generators:
2 - name: fernapi/fern-php-sdk
3 config:
4 generateClientInterfaces: true

1.28.0

(feat): Add support for default request parameter values.

When useDefaultRequestParameterValues: true is configured in generators.yml, the SDK will generate default values for query parameters and headers that have defaults defined in the API schema. Parameters with defaults become optional in the constructor, falling back to their default value when omitted.

1generators:
2 - name: fernapi/fern-php-sdk
3 config:
4 useDefaultRequestParameterValues: true

1.27.0

(feat): Switch from Guzzle to PSR-7/17/18 HTTP interfaces; SDKs are now framework-agnostic and should work with any PSR-18 compliant HTTP client (Guzzle, Symfony HttpClient, etc.) The SDK uses php-http/discovery to automatically find an installed PSR-18 client at runtime. Retry logic is now implemented via a RetryDecoratingClient decorator instead of as Guzzle middleware. Existing Guzzle users should be unaffected as Guzzle implements PSR-18.


1.26.0

(feat): Add support for explicit nulls in PHP SDKs. Setter methods now mark properties as explicitly set, ensuring that null values are included in JSON serialization when intentionally set via setters. This distinguishes between omitting an optional property and explicitly setting it to null.


1.25.4

(fix): Fix wire tests to start and stop the mock server once for all tests instead of per test class. Previously, each test class would start and stop the WireMock container in setUpBeforeClass/tearDownAfterClass, causing the container to restart multiple times. Now uses a PHPUnit bootstrap file to manage the container lifecycle once for the entire test suite.


1.25.3

(fix): Fix wire test generation for file upload endpoints. When file parameters are required but no example value is provided, the generator now creates a default file using File::createFromString() instead of omitting the field, which caused TypeError when assigning null to non-nullable File properties.



1.25.1

(fix): Fix OAuth and InferredAuth token refresh to work on every request. Previously, tokens were fetched once during client initialization and stored statically in headers, causing authentication failures when tokens expired for long-lived client instances. Now the auth provider’s getToken()/getAuthHeaders() method is called on every request via a callback, properly refreshing tokens when needed.