Changelog

This page contains a log of notable changes to the API and webhooks, to help you understand what has changed and how it might affect your integrations. You can also subscribe to these changes via the RSS feed.

For a full changelog including all changes, please see the Apollo Studio changelog.

2026-10-16

High Impact Changes

Client relation owner queries and Owner.owned

Owners now work the same way on a supplier company’s client relation (CompanySupplier) and a staffing agency’s client link (SupplierClient). Three changes can break existing queries:

  • clientRelationAgencyOwners is removed. Use clientRelationCounterpartOwners instead: for a CompanySupplier ID it takes the same arguments and returns the same Owner rows.
  • Owner.owned is now nullable. It is null when the viewer is not a party to the record: the client or supplier company for a CompanySupplier, or the staffing agency or managing company for a SupplierClient.
  • Ownable is now an interface with id, owners and viewerCanManageOwners, rather than a union. Selections on ... on CompanySupplier and ... on SupplierClient keep working; regenerate your GraphQL types.

Before:

query AgencyOwners($client: ID!) {
  clientRelationAgencyOwners(client: $client, first: 25) {
    data {
      id
      owned {
        ... on SupplierClient { id }
      }
    }
  }
}

After:

query AgencyOwners($client: ID!) {
  clientRelationCounterpartOwners(client: $client, first: 25) {
    data {
      id
      owned {
        ... on SupplierClient { id }
      }
    }
  }
}

Handle owned being null.

Medium Impact Changes

Client relation owners for staffing agency links, and updateOwners

  • clientRelationOwners now also takes a SupplierClient ID, listing the agency’s own owners on that link. An ID that matches no relation visible to the viewer returns an empty list rather than an error.
  • clientRelationCounterpartOwners on a managed SupplierClient returns the people the managing company assigned to its own relation with the client, and nothing on a direct link.
  • updateCompanySupplierOwners is deprecated. Use updateOwners, which takes either relation ID as ownable and applies the same rules.

Before:

mutation Owners($id: ID!, $owners: [OwnerInput!]!) {
  updateCompanySupplierOwners(input: { id: $id, owners: $owners }) {
    id
  }
}

After:

mutation Owners($id: ID!, $owners: [OwnerInput!]!) {
  updateOwners(input: { ownable: $id, owners: $owners }) {
    id
  }
}

Low Impact Changes

Experimental staffing agency owner fields

New, experimental fields for staffing agencies to manage who looks after each client. They may change without a deprecation period while the feature is being built.

  • SupplierClient gains owners, viewerCanManageOwners, workersCount and firstHireStartedAt.
  • The ClientRelation interface gains hiresCount(status:), workersCount and firstHireStartedAt.
  • Recruiter gains teamMembersAndOwners(search:): the agency’s owner and accepted members, readable only by the agency itself.

2026-10-12

High Impact Changes

Client queries for supplier companies renamed

The queries a supplier company (a company that supplies workers to clients, such as an MSP) uses to read its clients have been renamed to match the client relation API, and the old names are removed from the API. Staffing agencies use the new staffingAgencyClients query instead.

  • supplierClients is now companyClients. It takes the same arguments and returns the same CompanySupplier rows.
  • supplierClient(id:) is replaced by clientRelation(id:), which returns the ClientRelation interface. Select CompanySupplier fields in a ... on CompanySupplier fragment.
  • ClientRelationOrderByColumn and ClientRelationOrderByClauseInput are now CompanyClientOrderByColumn and CompanyClientOrderByClauseInput. The enum values are unchanged.

Before:

query Client($id: ID!) {
  supplierClient(id: $id) {
    id
    paymentTerm
  }
}

After:

query Client($id: ID!) {
  clientRelation(id: $id) {
    id
    ... on CompanySupplier {
      paymentTerm
    }
  }
}

Medium Impact Changes

SupplierClient hire counts and staffing agency relation

Two fields on SupplierClient changed what they return:

  • hiresCount counts the staffing agency’s own copy of each hire placed through the link. On a link through an MSP, that is the copy under the MSP rather than the hire at the client, so the count can differ from before. It also takes an optional status argument to count only hires in the given statuses.
  • companyRecruiter is null unless the viewer belongs to the link’s managing company.

Low Impact Changes

Experimental staffing agency client API

New, experimental fields for staffing agencies to read the end clients they work for. They may change without a deprecation period while the feature is being built.

  • staffingAgencyClients lists the viewer’s staffing agency links, one per client and managing company, direct or through an MSP. It filters by accounts, search, isDirect, clientRegions and createdAtDateRange, and sorts by CLIENT_NAME, RELATION, CLIENT_SINCE or PLACEMENTS.
  • clientRelation(id:) returns one relation for either a CompanySupplier or a SupplierClient ID.
  • The ClientRelation interface (id, client, createdAt) is implemented by CompanySupplier and SupplierClient. CompanySupplier gains a client field for it.
  • SupplierClient gains managingCompany, isDirect and managingCompanyContacts. The last returns the people at the MSP who look after the client, and is empty on a direct link.
  • clientRelationRegions returns the markets and regions of the viewer’s clients.

2026-10-11

Documentation Changes

Corrected hire webhook event triggers and hire status

The webhook reference now matches what the platform sends. No payload or behaviour changed.

  • Contract Accepted: contractAccepted fires for the first acceptance, for each accepted contract change (on the effective date for a future-dated change), and when a hire is terminated early.
  • Hire Updated: hireUpdated does not fire when a worker accepts a job offer or a contract change.
  • Hire Terminated: hireStatus is normally active, because the hire runs until its new end date. No webhook is sent when the status later changes to terminated.

The worksome-cli repository is public

The CLI page no longer says the repository is private. Anyone can download the release binaries or build from source.

2026-09-28

Low Impact Changes

New classificationAccepted webhook event

A new classificationAccepted webhook event is sent when a company accepts a worker classification on a hire. The payload contains the worker object and a classification object (id, accountId, hireId, status and result.outcome).

result.outcome is INDEPENDENT, EMPLOYEE or UNKNOWN, values of the ClassificationResult enum, the same values Classification.result.outcome returns in the API.

Subscribe to classificationAccepted to receive it; webhooks subscribed to all events receive it automatically. See Classification Accepted for the full payload.

2026-09-22

Low Impact Changes

Deprecation of column field on invoices query

The InvoicesOrderByColumn enum has been renamed to InvoiceOrderByColumn for consistency with other singular enum naming.

The column field on the QueryInvoicesOrderByOrderByClause has been marked as deprecated, use field instead.

Before:

query Invoices {
    invoices(orderBy: [{
        column: DATE,
        order: DESC
    }]) {
        data { id }
    }
}

After:

query Invoices {
    invoices(orderBy: [{
        field: DATE,
        order: DESC
    }]) {
        data { id }
    }
}

2026-04-22

Medium Impact Changes

Deprecation of recruiter fee fields

The recruiterFee field on both the Hire and CompanyRecruiter types has been deprecated. It only supports percentage-based fees and returns null for any other fee basis (hourly, daily, weekly, monthly).

Please migrate to the fees field, which returns the full set of fees associated with the hire or recruiter relationship and supports every fee basis.

Before:

query Hire($id: ID!) {
  hire(id: $id) {
    recruiterFee
  }
}

After:

query Hire($id: ID!) {
  hire(id: $id) {
    fees {
      id
      formattedRate
    }
  }
}

2026-04-18

Documentation Changes

New Integration Guide: Timesheet Integration

A new integration guide is available for clients who collect timesheet data in an external system and want to automate timesheet and payment request creation in Worksome. See Timesheet Integration.

A JSON Schema for the timesheet registration payload is published at /schemas/timesheet-registration.json for payload validation and client code generation.

2026-03-15

Documentation Changes

Expanded API documentation

The developer documentation has been significantly expanded with new guides and reference pages:

  • GraphQL reference — Auto-generated pages for queries, mutations, objects, enums, scalars, unions, interfaces, and input objects, with example queries.
  • Guides — New pages on pagination and filtering, error handling, and rate limiting.
  • Webhooks — Dedicated event reference pages with full payload examples for all webhook events, plus a guide on handling webhooks.
  • Integrations — Documentation for the CLI, PHP SDK, MCP Server, Zapier, and AI agent integration options.
  • AI-friendly docs — Published llms.txt and llms-full.txt for loading documentation directly into LLM context windows.

2026-01-15

Medium Impact Changes

New createDraftHire mutation

A new createDraftHire mutation has been added to the public API for creating draft hires for trusted contacts. Draft hires must be completed in the Worksome UI before they become active.

Example mutation:

mutation CreateDraftHire($input: HireInput!) {
  createDraftHire(input: $input) {
    id
    activeStatus
  }
}

Example variables:

{
  "input": {
    "company": "Q29tcGFueTox",
    "trustedContact": "V29ya2VyOjE=",
    "name": "Backend contractor",
    "description": "Build integrations with our partner APIs",
    "startDate": "2024-10-01",
    "endDate": "2024-12-31",
    "includeStandardContract": true,
    "locationPreference": {"preference": "REMOTE_ONLY"},
    "rateType": "FIXED",
    "rate": 12000
  }
}

Deprecation of hire mutation

The hire mutation has been deprecated in favor of createDraftHire for creating draft hires via the public API. Please migrate to createDraftHire for all new integrations.

HireInput customFieldValues clarification

The customFieldValues field on HireInput now includes clarified documentation: passing an empty array [] will skip custom field syncing entirely. If you have required custom fields configured, you must provide values for them or validation will fail.

2025-06-03

Low Impact Changes

Webhook hire status field

A new hireStatus field has been added to all hire-related webhook payloads within the contract object. This field provides a consistent way to track hire status across all webhook events.

The field is included in the following webhook events:

  • contractAccepted
  • hireCancelled
  • hireEnded
  • hireTerminated
  • hireUpdated

Possible values include: draft, offered, ready, active, ended, cancelled, and terminated.

Example payload structure:

{
    "event": "hireUpdated",
    "data": {
        "contract": {
            "id": "Q29udHJhY3Q6MTIzNA==",
            "hireStatus": "active",
            ...
        },
        "worker": { ... }
    }
}

This is a non-breaking change - existing webhook consumers will continue to work without modification, and the existing contract.status field remains unchanged.

2024-09-02

View the full changelog for this date on Apollo Studio.

Low Impact Changes

Job payment schemes

The Job.paymentScheme field and related arguments have been deprecated as part of our platform simplification efforts and were removed from the API on 29 September 2024.

No direct replacement is planned.

2024-08-29

View the full changelog for this date on Apollo Studio.

Low Impact Changes

Payment request type

All references to bills have been removed from the API.

2024-02-27

View the full changelog for this date on Apollo Studio.

Medium Impact Changes

Hire date properties

The dateStart and dateEnd fields have been deprecated.

Please migrate to the new startDate and endDate fields as soon as possible.

2024-02-12

View the full changelog for this date on Apollo Studio.

Medium Impact Changes

Payment request type

The Bill type has been renamed to PaymentRequest, and corresponding references to bills are now deprecated and were removed from the API on 29 August 2024.

Please migrate any uses of the following in your integrations:

  • bill should be renamed to paymentRequest
  • bills should be renamed to paymentRequests