Skip to content

php - v0.18.0 - 2026-03-23 09:33:08

Choose a tag to compare

@github-actions github-actions released this 23 Mar 09:33
ea819a2

PHP SDK v0.18.0 Changelog

Release Date: March 2026


What's New

Version 0.18.0 is a significant catch-up release that restructures how CRM and Accounting company resources are accessed, introduces new Accounting and ATS capabilities, and refines several data models for consistency. This release contains seven breaking changes that affect enum values, class namespaces, method signatures, and constructor parameter ordering. All users upgrading from v0.17.x should review the migration checklist at the bottom of this document before upgrading.


Summary of Changes

Category Description Action Required
Breaking ExpensesFilterStatus enum values removed Update any code referencing PendingApproval, Approved, Rejected, Deleted, or Other
Breaking Companies class repurposed from CRM to Accounting Migrate CRM company calls to ApideckCompanies
Breaking CRM companies moved to ApideckCompanies class Update service accessor from $sdk->crm->companies (old Companies) to new ApideckCompanies
Breaking CrmCompaniesAllResponse accessor renamed Replace getCompaniesResponse with getCompaniesResponse1
Breaking JournalEntryLineItem type field now optional Update constructors and remove assumptions that type is always present
Breaking Consumers::list() signature changed Insert new $filter parameter as 2nd positional argument
Breaking HRIS companies type changed Update HRIS type references from ApideckCompanies to ApideckHrisCompanies
New Feature Refunds resource for Accounting No action required
New Feature ATS Jobs CRUD methods No action required
New Feature companyId parameter on Accounting requests No action required
New Feature New optional fields on many models No action required
New Feature LinkedEmployee model and TaxType enum No action required

Detailed Changes by API

Accounting

1. ExpensesFilterStatus Enum Values Removed

What changed: The following values have been removed from the ExpensesFilterStatus enum: PendingApproval, Approved, Rejected, Deleted, and Other.

Impact: Any code that filters expenses using these status values will fail at compile time or throw an error at runtime.

// BEFORE (v0.17.x) -- these values no longer exist
$filter = new ExpensesFilter(
    status: ExpensesFilterStatus::PendingApproval
);

$filter = new ExpensesFilter(
    status: ExpensesFilterStatus::Approved
);

$filter = new ExpensesFilter(
    status: ExpensesFilterStatus::Rejected
);

// AFTER (v0.18.0) -- use only the remaining supported status values
// Consult the SDK reference for the current set of valid enum values.
// Example with a supported value:
$filter = new ExpensesFilter(
    status: ExpensesFilterStatus::Draft
);

2. Companies Class Repurposed from CRM to Accounting

What changed: The Companies class previously represented the CRM Companies resource. It has been repurposed to serve the Accounting Companies resource. The create(), delete(), get(), and update() methods have been removed. The list() method now returns Accounting companies instead of CRM companies.

Impact: Any code that used Companies for CRM operations will break. The list() method still exists but returns a different data type.

// BEFORE (v0.17.x) -- Companies was the CRM resource
$response = $sdk->crm->companies->create(
    company: new CrmCompanyInput(name: 'Acme Corp')
);

$response = $sdk->crm->companies->get(id: 'company_123');
$response = $sdk->crm->companies->update(id: 'company_123', company: $updated);
$response = $sdk->crm->companies->delete(id: 'company_123');
$response = $sdk->crm->companies->list();

// AFTER (v0.18.0) -- Companies is now Accounting; CRM moved to ApideckCompanies
// Accounting companies (list only):
$response = $sdk->accounting->companies->list();

// CRM companies (full CRUD via new class):
$response = $sdk->crm->companies->create(
    company: new CrmCompanyInput(name: 'Acme Corp')
);
$response = $sdk->crm->companies->get(id: 'company_123');
$response = $sdk->crm->companies->update(id: 'company_123', company: $updated);
$response = $sdk->crm->companies->delete(id: 'company_123');
$response = $sdk->crm->companies->list();

3. CRM Companies Moved to ApideckCompanies Class

What changed: CRM company operations are now served by the new ApideckCompanies class, accessible via $sdk->crm->companies. The underlying class has changed, but the accessor path remains the same.

Impact: If your code type-hints or instanceof-checks the Companies class for CRM usage, you must update those references to ApideckCompanies.

// BEFORE (v0.17.x)
use Apideck\Unify\Models\Components\Companies;

function processCrm(Companies $companiesService): void {
    $result = $companiesService->list();
    // ...
}

// AFTER (v0.18.0)
use Apideck\Unify\Models\Components\ApideckCompanies;

function processCrm(ApideckCompanies $companiesService): void {
    $result = $companiesService->list();
    // ...
}

4. CrmCompaniesAllResponse Accessor Renamed

What changed: The getCompaniesResponse method on CrmCompaniesAllResponse has been renamed to getCompaniesResponse1.

Impact: Any code reading the response payload from a CRM companies list call must update the accessor name.

// BEFORE (v0.17.x)
$response = $sdk->crm->companies->list();
$companiesPayload = $response->getCompaniesResponse();

// AFTER (v0.18.0)
$response = $sdk->crm->companies->list();
$companiesPayload = $response->getCompaniesResponse1();

5. JournalEntryLineItemtype Field Now Optional

What changed: The type property on both JournalEntryLineItem and JournalEntryLineItemInput has changed from required (JournalEntryLineItemType) to optional (?JournalEntryLineItemType). The constructor parameter order has also changed as a result.

Impact: Code that passes type as a positional constructor argument may break due to reordering. Code that reads type without null-checking may throw.

// BEFORE (v0.17.x) -- type was required and positionally first
$lineItem = new JournalEntryLineItemInput(
    type: JournalEntryLineItemType::Debit,
    ledgerAccount: $account,
    totalAmount: 500.00
);

// Accessing type was always safe
$type = $lineItem->type; // JournalEntryLineItemType

// AFTER (v0.18.0) -- type is optional; use named parameters to avoid ordering issues
$lineItem = new JournalEntryLineItemInput(
    ledgerAccount: $account,
    totalAmount: 500.00,
    type: JournalEntryLineItemType::Debit  // now optional
);

// Always null-check when reading type
$type = $lineItem->type; // ?JournalEntryLineItemType
if ($type !== null) {
    // handle type
}

Recommendation: Always use named parameters when constructing JournalEntryLineItem and JournalEntryLineItemInput to insulate your code from future parameter reordering.


6. New Refunds Resource

What changed: A new Refunds resource is now available under the Accounting API, providing full access to refund records.

Impact: None -- this is additive. No migration required.

// List refunds
$response = $sdk->accounting->refunds->list();

// Get a specific refund
$response = $sdk->accounting->refunds->get(id: 'refund_456');

7. New Optional companyId Parameter on Accounting Request Models

What changed: Many Accounting request models now accept an optional companyId parameter, enabling multi-company accounting workflows.

Impact: None -- this is additive. Existing calls without companyId continue to work as before.

// Optionally scope requests to a specific company
$response = $sdk->accounting->invoices->list(
    companyId: 'company_789'
);

8. New Optional Fields on Models

What changed: Several models now include new optional fields:

  • bankAccount on applicable line item and transaction models
  • taxType on line items (uses the new TaxType enum)
  • employee on line items (uses the new LinkedEmployee model)

Impact: None -- these fields are optional and additive. Existing code is unaffected.

// Using new optional fields on a line item
$lineItem = new InvoiceLineItemInput(
    description: 'Consulting services',
    totalAmount: 1000.00,
    taxType: TaxType::Output,
    employee: new LinkedEmployee(id: 'emp_123', displayName: 'Jane Doe')
);

ATS (Applicant Tracking System)

9. New Jobs CRUD Methods

What changed: The ATS Jobs resource now supports create(), update(), and delete() operations in addition to the existing list() and get().

Impact: None -- this is additive. No migration required.

// Create a new job
$response = $sdk->ats->jobs->create(
    job: new AtsJobInput(
        title: 'Senior PHP Developer',
        description: 'Join our backend team...'
    )
);

// Update an existing job
$response = $sdk->ats->jobs->update(
    id: 'job_101',
    job: new AtsJobInput(title: 'Staff PHP Developer')
);

// Delete a job
$response = $sdk->ats->jobs->delete(id: 'job_101');

Vault (Consumer Management)

10. Consumers::list() Signature Changed

What changed: The Consumers::list() method now accepts a new $filter parameter as the 2nd positional argument. All subsequent positional arguments have shifted.

Impact: Any code calling Consumers::list() with positional arguments will break because the parameter order has changed.

// BEFORE (v0.17.x) -- positional call without filter
$response = $sdk->vault->consumers->list(
    'cursor_abc',  // cursor as 2nd argument
    20             // limit as 3rd argument
);

// AFTER (v0.18.0) -- filter is now the 2nd positional argument
// Option A: Use named parameters (recommended)
$response = $sdk->vault->consumers->list(
    cursor: 'cursor_abc',
    limit: 20
);

// Option B: Include filter in positional call
$response = $sdk->vault->consumers->list(
    null,          // app_id or first param
    new ConsumersFilter(email: 'jane@example.com'), // new filter param
    'cursor_abc',  // cursor shifted to 3rd
    20             // limit shifted to 4th
);

// Using the new filter capability
$response = $sdk->vault->consumers->list(
    filter: new ConsumersFilter(email: 'jane@example.com'),
    limit: 50
);

Recommendation: Switch to named parameters for all Consumers::list() calls to avoid breakage from future signature changes.


HRIS (Human Resources)

11. HRIS companies Type Changed

What changed: The HRIS companies accessor now returns ApideckHrisCompanies instead of ApideckCompanies. This disambiguates HRIS companies from CRM companies following the broader restructuring.

Impact: Any code that type-hints or performs instanceof checks on the HRIS companies service must update the reference.

// BEFORE (v0.17.x)
use Apideck\Unify\Models\Components\ApideckCompanies;

/** @var ApideckCompanies $hrisCompanies */
$hrisCompanies = $sdk->hris->companies;

// AFTER (v0.18.0)
use Apideck\Unify\Models\Components\ApideckHrisCompanies;

/** @var ApideckHrisCompanies $hrisCompanies */
$hrisCompanies = $sdk->hris->companies;
$response = $hrisCompanies->list();

Cross-Cutting

12. New LinkedEmployee Model and TaxType Enum

What changed: Two new shared types are available:

  • LinkedEmployee -- a lightweight reference to an employee, with id and displayName fields
  • TaxType -- an enum representing tax classification types

Additionally, the LinkedFinancialAccountAccountType enum now includes an Employee value.

Impact: None -- these are additive. They are available for use in models that reference employees or tax types.

use Apideck\Unify\Models\Components\LinkedEmployee;
use Apideck\Unify\Models\Components\TaxType;
use Apideck\Unify\Models\Components\LinkedFinancialAccountAccountType;

$employee = new LinkedEmployee(id: 'emp_456', displayName: 'John Smith');

$taxType = TaxType::Output;

$accountType = LinkedFinancialAccountAccountType::Employee;

Migration Checklist

Use this checklist to verify your upgrade from v0.17.x to v0.18.0 is complete.

Breaking Changes (must address before upgrading)

  • Expenses filter status: Search codebase for ExpensesFilterStatus::PendingApproval, ::Approved, ::Rejected, ::Deleted, and ::Other. Replace with supported values.
  • CRM Companies class: Replace any type-hints or instanceof checks referencing the old Companies class for CRM usage with ApideckCompanies.
  • CRM Companies accessor: Verify that $sdk->crm->companies calls still work as expected -- the underlying class has changed to ApideckCompanies, but the accessor path is the same.
  • Accounting Companies: If you previously used Companies::list() expecting CRM data, update to $sdk->crm->companies->list() for CRM or $sdk->accounting->companies->list() for Accounting.
  • CrmCompaniesAllResponse: Replace all calls to ->getCompaniesResponse() with ->getCompaniesResponse1().
  • JournalEntryLineItem constructors: Switch to named parameters. Add null-checks when reading the type property.
  • Consumers::list() calls: Add the new $filter parameter or switch to named parameters to avoid positional argument misalignment.
  • HRIS companies type: Replace ApideckCompanies type-hints with ApideckHrisCompanies for any HRIS company service references.

New Features (optional adoption)

  • Explore $sdk->accounting->refunds for refund management.
  • Explore ATS Jobs create(), update(), and delete() methods.
  • Consider using the new companyId parameter on Accounting requests for multi-company workflows.
  • Adopt LinkedEmployee, TaxType, and new optional model fields where applicable.

Verification

  • Run full test suite after upgrading to confirm no regressions.
  • Verify all Accounting, CRM, HRIS, ATS, and Vault integrations function correctly in staging.
  • Confirm serialization/deserialization of JournalEntryLineItem with optional type field works as expected.