> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nmbr.co/llms.txt
> Use this file to discover all available pages before exploring further.

# API

> Product updates and announcements

<Update label="July 2026: Deprecating root-level data properties on bulk endpoints">
  ## Deprecating root-level data properties on bulk endpoints

  > 🚧 Breaking Change
  > Bulk endpoints will stop accepting data properties on the root of the request in a
  > future release. Data properties should be nested under a `data` key. The old format
  > continues to work for now but is deprecated.

  ### Background

  Bulk create and update endpoints accept two types of properties in the request body:

  * **Filter properties**: Properties used to select the entities to operate on
    (e.g. `payroll_id`, `pay_stubs`).
  * **Data properties**: Properties for the created or updated entities (e.g.
    `deduction_type`, `custom_amount`).

  When we first introduced bulk endpoints, both types of properties were placed on the
  root of the request body. However, some bulk endpoints need filter and data properties
  with the same name but different values. To support this, we're moving data properties
  into a nested `data` key.

  ### What's Changing

  Data properties should be nested under a `data` key in the request body. For example,
  instead of sending data properties on the root of the request:

  <Warning>Legacy request with data properties on root</Warning>

  ```
  POST /deduction_line_items/bulk/create

  {
      "payroll_id": "payrl_01JBC4F2XKMP7R9QHN3DSWV6YA",
      "pay_stubs": {
          "include": {
              "ids": [
                  "payst_01JBC4F8GT5YNWZ0CRHQ6DMXKE",
                  "payst_01JBC4FBMS3AP4VD7TXJW2HN9R"
              ]
          }
      },
      "deduction_type": "union_dues",
      "title": "Union Dues",
      "custom_amount": 50,
      "custom_hours": null
  }
  ```

  nest the data properties under a `data` key:

  <Check>Modern request with data properties nested under `data`</Check>

  ```
  POST /deduction_line_items/bulk/create

  {
      "payroll_id": "payrl_01JBC4F2XKMP7R9QHN3DSWV6YA",
      "pay_stubs": {
          "include": {
              "ids": [
                  "payst_01JBC4F8GT5YNWZ0CRHQ6DMXKE",
                  "payst_01JBC4FBMS3AP4VD7TXJW2HN9R"
              ]
          }
      },
      "data": {
          "deduction_type": "union_dues",
          "title": "Union Dues",
          "custom_amount": 50,
          "custom_hours": null
      }
  }
  ```

  ### Migrating to the `data` Key

  To help preexisting partners migrate their integrations, you can force either behavior by
  passing a `Prefer` header with the request:

  * To require data properties under `data`: `Prefer: deprecate_flat_bulk_shape=true`
  * To keep accepting data properties on the root: `Prefer: deprecate_flat_bulk_shape=false`

  When the `data` key is required, any data property sent on the root is rejected with a `422`,
  with one validation error per misplaced property.

  We recommend migrating as soon as possible by passing `Prefer: deprecate_flat_bulk_shape=true`
  on all bulk requests.

  <Note>
    Once your integration is fully migrated to the `data` key, contact Nmbr support to make this
    the default behavior for your partner. After that, you can remove the `Prefer` headers from
    your requests.
  </Note>

  ### Affected Endpoints

  Recurrence bulk endpoints:

  * `POST /allowances/bulk/create`
  * `POST /allowances/bulk/update`
  * `POST /deductions/bulk/create`
  * `POST /deductions/bulk/update`
  * `POST /earnings/bulk/create`
  * `POST /earnings/bulk/update`
  * `POST /employee_benefits/bulk/create`
  * `POST /employee_benefits/bulk/update`
  * `POST /employer_benefits/bulk/create`
  * `POST /employer_benefits/bulk/update`
  * `POST /reimbursements/bulk/create`
  * `POST /reimbursements/bulk/update`
  * `POST /pay_rates/bulk/create`
  * `POST /pay_rates/bulk/update`
  * `POST /overtime_rates/bulk/create`
  * `POST /overtime_rates/bulk/update`

  Line item bulk endpoints:

  * `POST /allowance_line_items/bulk/create`
  * `POST /allowance_line_items/bulk/update`
  * `POST /deduction_line_items/bulk/create`
  * `POST /deduction_line_items/bulk/update`
  * `POST /earning_line_items/bulk/create`
  * `POST /earning_line_items/bulk/update`
  * `POST /employee_benefit_line_items/bulk/create`
  * `POST /employee_benefit_line_items/bulk/update`
  * `POST /employer_benefit_line_items/bulk/create`
  * `POST /employer_benefit_line_items/bulk/update`
  * `POST /reimbursement_line_items/bulk/create`
  * `POST /reimbursement_line_items/bulk/update`

  Other bulk endpoints:

  * `POST /remittance_account_enrollments/bulk/create`
  * `POST /work_assignments/bulk/create`
  * `POST /work_assignments/bulk/update`

  ### What's Not Changing

  Filter properties (`payroll_id`, `pay_stubs`, etc.) remain on the root of the request
  body. Only data properties are moving into the `data` key.

  The old format with data properties on the root of the request continues to work for
  preexisting partners, but will be removed in a future release. The nested `data` shape is
  the default for new partners going forward.
</Update>

<Update label="July 2026: Deprecating the legacy percent field on benefits">
  ## Deprecating the legacy `percent` field on benefits

  > 🚧 Breaking Change
  > The `percent` field on employee and employer benefits will be removed in a future
  > release. Percentage-based benefits are represented with `amount` and an `amount_type` of
  > `percent`. The old `percent` field continues to work for now but is deprecated.

  ### Background

  A benefit's contribution can be either a fixed dollar amount or a percentage. Historically
  these were represented with two separate, mutually exclusive fields:

  * **`amount`**: The fixed dollar amount. Set on fixed benefits, `null` on percentage
    benefits.
  * **`percent`**: The percentage. Set on percentage benefits, `null` on fixed benefits.

  Having two fields where only one is ever populated made benefits awkward to work with:
  callers had to choose the right field and always handle a `null` for the other. It was also
  inconsistent with other recurrence types that support percentage values - deductions, for
  example, already use a single `amount` field paired with an `amount_type` discriminator.
  We're bringing benefits in line by replacing `percent` with the same `amount` +
  `amount_type` shape.

  ### What's Changing

  Percentage-based benefits are now represented with a single `amount` value and an
  `amount_type` of `percent`, instead of the separate `percent` field. Fixed benefits use the
  same `amount` value with an `amount_type` of `fixed`.

  Instead of sending a `percent` field when creating or updating a percentage-based benefit:

  <Warning>Legacy request using the `percent` field</Warning>

  ```
  POST /employee_benefits

  {
      "work_assignment_id": "wrkas_01JBC4F2XKMP7R9QHN3DSWV6YA",
      "employee_benefit_type": "pension_rrsp",
      "frequency": "per_pay_period",
      "effective_from": "2026-01-01",
      "percent": 5
  }
  ```

  send the value in `amount` with an `amount_type` of `percent`:

  <Check>Modern request using `amount` and `amount_type`</Check>

  ```
  POST /employee_benefits

  {
      "work_assignment_id": "wrkas_01JBC4F2XKMP7R9QHN3DSWV6YA",
      "employee_benefit_type": "pension_rrsp",
      "frequency": "per_pay_period",
      "effective_from": "2026-01-01",
      "amount": 5,
      "amount_type": "percent"
  }
  ```

  Fixed benefits set `amount_type` to `fixed`:

  ```
  {
      "amount": 100,
      "amount_type": "fixed"
  }
  ```

  Benefit responses change to match. Instead of returning both `amount` and `percent` with one
  always `null`:

  <Warning>Legacy response</Warning>

  ```
  {
      ...
      "amount": null,
      "percent": 5
  }
  ```

  responses return a single `amount` alongside `amount_type` and omit `percent`:

  <Check>Modern response</Check>

  ```
  {
      ...
      "amount": 5,
      "amount_type": "percent"
  }
  ```

  In the modern shape `amount` holds the value for **both** types: it is a dollar amount when
  `amount_type` is `fixed` and a percentage when `amount_type` is `percent`. Use `amount_type`
  to interpret it.

  `amount_type` itself is a new field introduced by this change; benefit responses did not
  previously return it. It now appears in both shapes, so partners who stay on the legacy shape
  will start receiving `amount_type` alongside the existing `amount` and `percent` fields. This
  is additive - no existing field is removed or changed for the legacy shape.

  ### Migrating to `amount` and `amount_type`

  To help preexisting partners migrate their integrations, you can force either shape by
  passing a `Prefer` header with the request:

  * To use the modern shape: `Prefer: deprecate_benefit_percent=true`
  * To use the legacy shape: `Prefer: deprecate_benefit_percent=false`

  The header controls both how the request body is interpreted and how the response is shaped.
  We recommend migrating as soon as possible by passing `Prefer: deprecate_benefit_percent=true`
  on all benefit requests.

  The modern shape is the default for new partners going forward. The legacy shape remains the
  default for preexisting partners until they migrate.

  <Note>
    Once your integration is fully migrated to the modern shape, contact Nmbr support to make it
    the default behavior for your partner. After that, you can remove the `Prefer` headers from
    your requests.
  </Note>

  ### Affected Endpoints

  The change applies to employee and employer benefit resources wherever they are created or
  updated:

  * `POST /employee_benefits`
  * `PUT /employee_benefits/:id`
  * `POST /employee_benefits/bulk/create`
  * `POST /employee_benefits/bulk/update`
  * `POST /employee_benefits/batch/upsert`
  * `POST /employer_benefits`
  * `PUT /employer_benefits/:id`
  * `POST /employer_benefits/bulk/create`
  * `POST /employer_benefits/bulk/update`
  * `POST /employer_benefits/batch/upsert`

  It also applies to the corresponding read endpoints (`GET /employee_benefits`,
  `GET /employee_benefits/:id`, `GET /employer_benefits`, `GET /employer_benefits/:id`) and to
  `employee_benefit` and `employer_benefit` fields expanded in other resources.

  ### What's Not Changing

  Benefit line items are unaffected: they never carried a `percent` field.
</Update>

<Update label="July 2026: Deprecating synchronous mode on bulk endpoints">
  ## Deprecating synchronous mode on bulk endpoints

  > 🚧 Breaking Change
  > Bulk endpoints will default to asynchronous mode for all partners in a future release.
  > Synchronous mode is deprecated.

  ### Background

  Bulk create, update, and delete endpoints currently support two modes of operation:

  **Synchronous mode** (deprecated):

  * Processes the operation synchronously
  * Returns HTTP 201 Created, HTTP 200 OK, or HTTP 204 No Content
  * Returns the created or updated models in the response body

  **Asynchronous mode**:

  * Returns HTTP 202 Accepted
  * Returns an [async task](https://docs.nmbr.co/api-reference/async-tasks/retrieve-an-async-task)
    in the response body
  * Processes the operation asynchronously
  * Returns the created or updated models via the async task result endpoint

  Synchronous mode is the current default for preexisting partners but will be deprecated
  in a future release. Asynchronous mode is the default for new partners going forward.

  For more details on asynchronous bulk operations, see the
  [Bulk and Batch Operations](https://docs.nmbr.co/api/bulk-and-batch-operations/bulk-line-item-operations)
  documentation.

  ### Migrating to Asynchronous Mode

  To help preexisting partners migrate their integrations, you can force either mode by
  passing a `Prefer` header with the request:

  * To force asynchronous mode: `Prefer: deprecate_sync_bulk=true`
  * To force synchronous mode: `Prefer: deprecate_sync_bulk=false`

  We recommend migrating to asynchronous mode as soon as possible by passing
  `Prefer: deprecate_sync_bulk=true` on all bulk requests.

  <Note>
    Once your integration is fully migrated to asynchronous mode, contact Nmbr support to
    make this the default behavior for your partner. After that, you can remove the
    `Prefer` headers from your requests.
  </Note>

  ### Affected Endpoints

  Recurrence bulk endpoints:

  * `POST /allowances/bulk/create`
  * `POST /allowances/bulk/update`
  * `POST /allowances/bulk/delete`
  * `POST /deductions/bulk/create`
  * `POST /deductions/bulk/update`
  * `POST /deductions/bulk/delete`
  * `POST /earnings/bulk/create`
  * `POST /earnings/bulk/update`
  * `POST /earnings/bulk/delete`
  * `POST /employee_benefits/bulk/create`
  * `POST /employee_benefits/bulk/update`
  * `POST /employee_benefits/bulk/delete`
  * `POST /employer_benefits/bulk/create`
  * `POST /employer_benefits/bulk/update`
  * `POST /employer_benefits/bulk/delete`
  * `POST /reimbursements/bulk/create`
  * `POST /reimbursements/bulk/update`
  * `POST /reimbursements/bulk/delete`
  * `POST /pay_rates/bulk/create`
  * `POST /pay_rates/bulk/update`
  * `POST /pay_rates/bulk/delete`
  * `POST /overtime_rates/bulk/create`
  * `POST /overtime_rates/bulk/update`
  * `POST /overtime_rates/bulk/delete`

  Line item bulk endpoints:

  * `POST /allowance_line_items/bulk/create`
  * `POST /allowance_line_items/bulk/update`
  * `POST /allowance_line_items/bulk/delete`
  * `POST /deduction_line_items/bulk/create`
  * `POST /deduction_line_items/bulk/update`
  * `POST /deduction_line_items/bulk/delete`
  * `POST /earning_line_items/bulk/create`
  * `POST /earning_line_items/bulk/update`
  * `POST /earning_line_items/bulk/delete`
  * `POST /employee_benefit_line_items/bulk/create`
  * `POST /employee_benefit_line_items/bulk/update`
  * `POST /employee_benefit_line_items/bulk/delete`
  * `POST /employer_benefit_line_items/bulk/create`
  * `POST /employer_benefit_line_items/bulk/update`
  * `POST /employer_benefit_line_items/bulk/delete`
  * `POST /reimbursement_line_items/bulk/create`
  * `POST /reimbursement_line_items/bulk/update`
  * `POST /reimbursement_line_items/bulk/delete`

  Other bulk endpoints:

  * `POST /remittance_account_enrollments/bulk/create`
  * `POST /remittance_account_enrollments/bulk/delete`
  * `POST /work_assignments/bulk/create`
  * `POST /work_assignments/bulk/update`
</Update>

<Update label="July 2026: Deprecating synchronous execution of batch endpoints">
  ## Deprecating synchronous execution of batch endpoints

  > 🚧 Breaking Change
  > Batch endpoints will execute asynchronously for all partners in a future release.
  > Synchronous execution is deprecated.

  ### Background

  Batch upsert and delete endpoints already return the asynchronous response shape (HTTP
  202 Accepted with an
  [async task](https://docs.nmbr.co/api-reference/async-tasks/retrieve-an-async-task) in
  the response body). However, for preexisting partners, the operation is currently
  executed synchronously before returning the response.

  In a future release, batch endpoints will execute asynchronously for all partners.
  Asynchronous execution is already the default for new partners going forward.

  ### Migrating to Asynchronous Execution

  To help preexisting partners migrate their integrations, you can force either mode by
  passing a `Prefer` header with the request:

  * To force asynchronous execution: `Prefer: deprecate_sync_batch=true`
  * To force synchronous execution: `Prefer: deprecate_sync_batch=false`

  We recommend migrating to asynchronous execution as soon as possible by passing
  `Prefer: deprecate_sync_batch=true` on all batch requests.

  <Note>
    Once your integration is fully migrated to asynchronous execution, contact Nmbr support
    to make this the default behavior for your partner. After that, you can remove the
    `Prefer` headers from your requests.
  </Note>

  ### Affected Endpoints

  Recurrence batch endpoints:

  * `POST /allowances/batch/upsert`
  * `POST /allowances/batch/delete`
  * `POST /deductions/batch/upsert`
  * `POST /deductions/batch/delete`
  * `POST /earnings/batch/upsert`
  * `POST /earnings/batch/delete`
  * `POST /employee_benefits/batch/upsert`
  * `POST /employee_benefits/batch/delete`
  * `POST /employer_benefits/batch/upsert`
  * `POST /employer_benefits/batch/delete`
  * `POST /reimbursements/batch/upsert`
  * `POST /reimbursements/batch/delete`
  * `POST /pay_rates/batch/upsert`
  * `POST /pay_rates/batch/delete`
  * `POST /overtime_rates/batch/upsert`
  * `POST /overtime_rates/batch/delete`

  Line item batch endpoints:

  * `POST /allowance_line_items/batch/upsert`
  * `POST /allowance_line_items/batch/delete`
  * `POST /deduction_line_items/batch/upsert`
  * `POST /deduction_line_items/batch/delete`
  * `POST /earning_line_items/batch/upsert`
  * `POST /earning_line_items/batch/delete`
  * `POST /employee_benefit_line_items/batch/upsert`
  * `POST /employee_benefit_line_items/batch/delete`
  * `POST /employer_benefit_line_items/batch/upsert`
  * `POST /employer_benefit_line_items/batch/delete`
  * `POST /reimbursement_line_items/batch/upsert`
  * `POST /reimbursement_line_items/batch/delete`

  Other batch endpoints:

  * `POST /contractors/batch/upsert`
  * `POST /contractors/batch/delete`
  * `POST /employees/batch/upsert`
  * `POST /employees/batch/delete`
  * `POST /forms/batch/upsert`
  * `POST /forms/batch/delete`
  * `POST /tax_properties/batch/upsert`
  * `POST /tax_properties/batch/delete`
  * `POST /vacation_pay_settings/batch/upsert`
  * `POST /vacation_pay_settings/batch/delete`
  * `POST /work_assignments/batch/upsert`
  * `POST /work_assignments/batch/delete`
</Update>

<Update label="March 2026">
  ## Fields and features being removed after May 15, 2026

  > 🚧 Breaking Change
  > Several fields and features will be removed after **May 15, 2026**. Most of these are older, legacy fields and features that were repaced with newer ones in 2025, but without a formal deprecation notice. Most partners will already be using the newer fields and features and will not need to make changes as a result. However, it's important to review each change to be sure.

  ### Removing `employer_ei_multiplier` from business entity resources

  We're removing the `employer_ei_multiplier` read-only field from business entity resources (`/business_entities`, `/business_entities/:id`, and `business_entity` fields expanded in other resources).

  We now support having multiple CRA RP account numbers within a single business entity. As part of that feature, we now support managing a reduced EI rate through tax properties on the relevant CRA remittance account. For more information, see the [EI Rate Reduction](https://docs.nmbr.co/guides/canada/ei-rate-reduction) documentation.

  ### Removing `tax_jurisdiction` from work assignment resources

  We're removing the `tax_jurisdiction` field from work assignment resources (`/work_assignments`, `/work_assignments/:id`, and `work_assignment` fields expanded in other resources).

  A work assignment may work in different tax jurisdictions in different pay periods. Having a single `tax_jurisdiction` value prevented tracking the tax jurisdiction over time or scheduling changes to it.

  Instead of setting `tax_jurisdiction`, manage a work assignment's Province of Employment (POE) through its `ca::province_of_employment` tax properties.

  ℹ️ We are **not** removing the read-only `current_tax_jurisdiction` field as part of these changes. This field returns the value of the work assignment's current `ca::province_of_employment` tax property for convenience.

  ### Removing `is_cpp_exempt` and `is_ei_exempt` from work assignment resources

  We're removing the `is_cpp_exempt`and `is_ei_exempt` fields from work assignment resources (`/work_assignments`, `/work_assignments/:id`, and `work_assignment` fields expanded in other resources).

  A work assignment may be CPP-exempt or EI-exempt in some pay periods but not others. Having single `is_cpp_exempt` and `is_ei_exempt` values prevented tracking or scheduling changes to CPP-exempt and EI-exempt status over time.

  Instead of setting `is_cpp_exempt` or `is_ei_exempt`, manage a work assignment's CPP-exempt and EI-exempt statuses through its `ca::cpp_exempt` and `ca::ei_exempt` tax properties.

  ℹ️ QPP- and QPIP-exempt status is already managed through tax properties.

  ### Removing  `employee_summary.deductions` and `employee_summary.deductions_ytd` from pay stub resources

  We're removing the `employee_summary.deductions` and `employee_summary.deductions_ytd` fields from pay stub resources (`/pay_stubs`, `/pay_stubs/:id`, and `pay_stub` fields expanded in other resources).

  These fields are poorly-named. Their names suggest they're the sum of deduction line items on the pay stub (or pay stubs year-to-date), but they're actually the sum of any line item subtracted from the employee's pay, i.e. deduction, employee benefit, and employee statutory withholding line items.

  You can get the same information from the `employee_summary.subtractions` and `employee_summary.subtractions_ytd` fields respectively.

  ### Removing support for creating forms identifying owner with `work_assignment_id`

  We're removing support for creating a form (`POST /forms`) using a `work_assignment_id` field to identify the owner of the form.

  When we first added support for forms, we only supported work assignment-level forms (e.g. TD1 and TP-1015.3-V), and so only ever needed `work_asignment_id`. Now that we support employee-level forms (e.g. T4 and ROE), we need different identifiers for different forms.

  Instead of sending a `work_assignment_id` on the request

  ```
  POST /forms

  {
    "work_assignment_id": "wrkas_...",
    ...
  }
  ```

  send the appropriate value in `owner_id`:

  ```
  POST /forms

  {
    "owner_id": "wrkas_...", // work assignment identifier for work assignment-level forms, etc
    ...
  }
  ```

  ### Removing `work_assignment` from form resources

  We're removing the `work_assignment` field from form resources (`/forms`, `/forms/:id`, and `form` fields expanded in other resources).

  Use the `owner` field to determine the owner of the form.

  ### Removing support for expanding all line items on a pay stub with `?expand=line_items`

  We're removing support for expanding all line items on a pay stub in a single `line_items` field using `/pay_stubs?expand=line_items` or `/pay_stub/:id?expand=line_items`.

  Each type of line item has a unique shape, and adding new types of line items could break consumers who aren't expecting their shapes. Additionally, some use cases only require certain types of line items, and returning all line items is unnecessarily expensive. Instead of using `expand=line_items` to expand the line items, use `expand=<type>_line_items,<type>_line_items,...` for each type of line item you want returned.

  ### Removing `t4_code` from allowance type resources

  We're removing the `t4_code` field from allowance type resources (`/allowance_types`, `/allowance_types/:id`, and `allowance_type` fields expanded in other resources).

  Where an allowance is reported on a T4 isn't a simple 1:1 mapping. This field was always previously returned with the value `null`. The `form_mappings` field contains more nuanced information about how types map to forms.

  ### Removing `is_taxable`, `is_insurable`, and `is_pensionable` from allowance type resources

  We're removing the `is_taxable`, `is_insurable`, and `is_pensionable` fields from allowance type resources (`/allowance_types`, `/allowance_types/:id`, and `allowance_type` fields expanded in other resources).

  Whether or not an allowance type is taxable, insurable, or pensionable isn't a simple boolean value; it varies by jurisdiction. We've replaced these fields with a new [Line Item Type Features](https://docs.nmbr.co/guides/payroll-fundamentals/line-item-type-features) system that will return more nuanced information about line item types in each jurisdiction we support.

  ### Removing `t4_code` from deduction type resources

  We're removing the `t4_code` field from deduction type resources (`/deduction_types`, `/deduction_types/:id`, and `deduction_type` fields expanded in other resources).

  Where a deduction is reported on a T4 isn't a simple 1:1 mapping. This field was always previously returned with the value `null`. The `form_mappings` field contains more nuanced information about how types map to forms.

  ### Removing `t4_code` from reimbursement type resources

  We're removing the `t4_code` field from reimbursement type resources (`/reimbursement_types`, `/reimbursement_types/:id`, and `reimbursement_type` fields expanded in other resources).

  Where a reimbursement is reported on a T4 isn't a simple 1:1 mapping. This field was always previously returned with the value `null`. The `form_mappings` field contains more nuanced information about how types map to forms.

  ### Removing the `is_taxable`, `is_insurable`, and `is_pensionable` from reimbursement type resources

  We're removing the `is_taxable`, `is_insurable`, and `is_pensionable` fields from reimbursement type resources (`/reimbursement_types`, `/reimbursement_types/:id`, and `reimbursement_type` fields expanded in other resources).

  Whether or not a reimbursement type is taxable, insurable, or pensionable isn't a simple boolean value; it varies by jurisdiction. We've replaced these fields with a new [Line Item Type Features](https://docs.nmbr.co/guides/payroll-fundamentals/line-item-type-features) system that will return more nuanced information about line item types in each jurisdiction we support.

  ### Removing journal entry line item report

  We're removing the journal entry *line item* report (`POST /reports/journal-entry-line-item`).

  It has been replaced by the [Journal Entry Report](https://docs.nmbr.co/api-reference/reports/create-payroll-register-report).

  ### Removing amount\_override from line item resources

  We're removing the `amount_override` field from all line item resources:

  * `/allowance_line_items/:id`
  * `/deduction_line_items/:id`
  * `/earning_line_items/:id`
  * `/employer_statutory_withholding_line_items/:id`
  * `/reimbursement_line_items/:id`
  * `/statutory_withholding_line_items/:id`

  These fields were for backward-compatibility during the transition from `amount` and `amount_override` to `managed_amount`, `custom_amount`, and `amount` in early 2025.

  Use the `custom_amount` field instead.
</Update>

<Update label="January 2026">
  ## name Read-Only amount and hours Properties on Line Items

  > 🚧 Breaking Change
  > The `amount` and `hours` properties on Line Items will be read-only as of **March 1, 2026**.

  ## Read-Only `amount` and `hours` Properties on Line items

  ### Introduction

  In Nmbr, each type of line item has 3 "amount" properties:

  * `managed_amount`: The managed amount for the line item. The value is either calculated by the system (e.g. statutory holiday pay or vacation pay payout) or configured on the line item's recurrence (e.g. a recurring allowance's `amount`). This property is read-only.

  * `custom_amount`: The custom amount for the line item.

  * `amount`: The final amount for the line item. This is the amount that will be paid, deducted, withheld, etc. The value will be `custom_amount`, if set, and `managed_amount` otherwise.

  Similarly, the earning line item type has 3 "hours" properties:

  * `managed_hours`: The managed hours for the line item. This amount is the default number of hours on the line item's Pay Rate. This property is read-only.

  * `custom_hours`: The custom hours for the line item. `custom_hours` can be used to prorate the dollar `amount` on salary line items with a Pay Rate.

  * `hours`: The final hours for the line item. The value will be `custom_hours`, if set, and `managed_hours` otherwise.

  Currently, the `amount` and `hours` properties are read/write. If you create or update a line item with an `amount` or `hours` value, the line item's `custom_amount` or `custom_hours` values will be set.

  ### What's Changing

  On March 1, 2026 we will be changing the `amount` and `hours` properties to be read-only. If you create or update a line item with `amount` or `hours` values, these values will be ignored.

  If your application sends `amount` or `hours` properties in requests to create or update line items, you will need to rename `amount` to `custom_amount` and `hours` to `custom_hours` in requests.

  For example, if you make the following request to create an earning line item

  `POST /earning_line_items`

  ```
  {
      ...
      "amount": 500,
      "hours": 10,
      ...
  }
  ```

  you would need to rename the properties as follows

  `POST /earning_line_items`

  ```
  {
      ...
      "custom_amount": 500,
      "custom_hours": 10,
      ...
  }
  ```

  ### What's Not Changing

  We will continue sending the computed `amount` and `hours` values in responses. Your application can continue to rely on these values.

  `GET /earning_line_items/ernli_01KBG99GP45784S1PVZTAGFE6X`

  ```
  {
      ...
      "managed_amount": 1000,
      "managed_hours": 20,
      ...
      "custom_amount": 500,
      "custom_hours": 10,
      ...
      "amount": 500,           // computed from managed_amount and custom_amount
      "hours": 10,             // computed from managed_hours and custom_hours
      ...
  }
  ```
</Update>

<Update label="September 2025">
  ## name Property Required on Business Presets

  > 🚧 Breaking Change
  > The `name` property on Business Presets will be required as of **November 15th, 2025**.

  ## `name` Property Required on Business Presets

  Business Presets currently require a value for *either* the `title` property or the `name` property.

  * `title` is copied to recurrences (pay rates, allowances, employee and employer benefits, deductions, and reimbursements) and line items, and used as their `title`.

  * `name` is used to identify the preset in the component or portal, or when grouping line items by preset on pay stubs or reports. If a Business Preset doesn't have a `name`, we currently fall back on `title`.

  We will be making the `name` property required as of November 15th, 2025 and removing the logic that currently falls back to `title`. In order to create new Business Presets, you will need to supply a value for `name`.

  The `title` property will continue to be optional.

  ## Business Entity-level templates deprecated

  > 🚧 **Breaking Change**
  > Business Entity-level templates for Allowances, Benefits, Deductions, and Reimbursements have been deprecated and will be removed on **November 15, 2025**. Please migrate to the new [Business Presets](https://docs.nmbr.co/docs/presets) feature. Legacy endpoints will continue to function until this date but will not receive updates or bug fixes.

  ## Deprecation of Business Entity-Level Templates for Allowances, Benefits, Deductions, and Reimbursements

  Nmbr previously supported defining templates for Allowances, Benefits, Deductions, and Reimbursements at the Business Entity level. As part of improving our API and providing a more consistent experience, we are replacing this feature with the new [Business Presets](https://docs.nmbr.co/docs/presets) feature, which supports a larger set of use cases with fewer endpoints.

  ## Deprecated Endpoints

  The following endpoints are now deprecated and have been replaced by the new Business Presets endpoints:

  * `/business_entity_allowances`
  * `/business_entity_benefits`
  * `/business_entity_deductions`
  * `/business_entity_reimbursements`

  # Migration

  ## Data

  You do NOT need to perform a data migration from legacy templates to Business Presets.

  When Business Presets were released, legacy templates were migrated to Business Presets of the appropriate `type`. For example, every legacy template for Allowances was migrated to a Business Preset of type `allowance`.

  To maintain backward compatibility, the APIs for these features were changed to manage Business Presets of the appropriate `type`. For example, creating/updating/deleting a Business Preset of type `allowance` will *appear* to create/update/delete a legacy template for Allowances, and vice versa. However, behind the scenes there is actually only one record in the Nmbr system: the Business Preset.

  During this migration, the ULIDs for legacy templates were retained as the ULID for the corresponding Business Preset, so partners will **not** need to store two ULID values (legacy template ULID and Business Preset ULID) or map between them.

  ## API

  You **DO** need to perform a code migration to change any code that is currently calling the legacy template APIs to instead call the Business Presets APIs.

  ### Allowances

  Change any code calling the `/business_entity_allowances` endpoints with the property `"allowance_type": "T"` to instead call the corresponding `/business_presets` endpoints with the properties `"type": "allowance"` and `"subtype": "T"`.

  For example, if you're working with taxable meals allowances, `"allowance_type": "meals_taxable"` will become `"type": "allowance"` and `"subtype": "meals_taxable"`.

  As mentioned in the data section above, you can continue to use the ULIDs for legacy templates.

  \| Action | Old Endpoint | New Endpoint |
  ||||
  \| | `name` | New required property. All Business Presets must have a name. The name is used when listing Business Presets and when grouping line items by Business Preset. |
  \| | `type` | New required property. For allowances, the type is always `allowance`. |
  \| `allowance_type` | `subtype` | Renamed. |
  \| `business_entity_id` | `business_entity_id` | Unchanged. |
  \| `title` | `title` | Unchanged. |

  ### Benefits

  Since Business Presets were released, Benefits were split into separate Employer Benefits and Employee Benefits.

  For Employer Benefits, change any code calling the `/business_entity_benefits` endpoints with the property `"benefit_type": "T"` to instead call the corresponding `/business_presets` endpoints with the properties `"type": "employer_benefit"` and `"subtype": "T"`.

  \| Action | Old Endpoint | New Endpoint |
  ||||
  \| Create | `POST /business_entity_benefits` with body `{ "benefit_type": "T", ... }` | `POST /business_presets` with body `{ "type": "employee_benefit", "subtype": "T", ... }` |
  \| List | `GET /business_entity_benefits` | `GET /business_presets?type=employee_benefit` |
  \| Retrieve | `GET /business_entity_benefits/:ulid` | `GET /business_presets/:ulid` |
  \| Update | `PUT /business_entity_benefits/:ulid` | `PUT /business_presets/:ulid` |
  \| Delete | `DELETE /business_entity_benefits/:ulid` | `DELETE /business_presets/:ulid` |

  The legacy benefit template properties map to the Business Presets properties as follows:

  \| Old Property | New Property | Notes |
  ||||
  \| Create | `POST /business_entity_deductions` with body `{ "deduction_type": "T", ... }` | `POST /business_presets` with body `{ "type": "deduction", "subtype": "T", ... }` |
  \| List | `GET /business_entity_deductions` | `GET /business_presets?type=deduction` |
  \| Retrieve | `GET /business_entity_deductions/:ulid` | `GET /business_presets/:ulid` |
  \| Update | `PUT /business_entity_deductions/:ulid` | `PUT /business_presets/:ulid` |
  \| Delete | `DELETE /business_entity_deductions/:ulid` | `DELETE /business_presets/:ulid` |

  The legacy deduction template properties map to the Business Presets properties as follows:

  \| Old Property | New Property | Notes |
  ||||
  \| Create | `POST /business_entity_reimbursements` with body `{ "reimbursement_type": "T", ... }` | `POST /business_presets` with body `{ "type": "reimbursement", "subtype": "T", ... }` |
  \| List | `GET /business_entity_reimbursements` | `GET /business_presets?type=reimbursement` |
  \| Retrieve | `GET /business_entity_reimbursements/:ulid` | `GET /business_presets/:ulid` |
  \| Update | `PUT /business_entity_reimbursements/:ulid` | `PUT /business_presets/:ulid` |
  \| Delete | `DELETE /business_entity_reimbursements/:ulid` | `DELETE /business_presets/:ulid` |

  The legacy reimbursement template properties map to the Business Presets properties as follows:

  \| Old Property | New Property | Notes |
  ||---|
  \| | `name` | New required property. All Business Presets must have a name. The name is used when listing Business Presets and when grouping line items by Business Preset. |
  \| | `type` | New required property. For reimbursements, the type is always `reimbursement`. |
  \| `deduction_type` | `subtype` | Renamed. |
  \| `business_entity_id` | `business_entity_id` | Unchanged. |
  \| `title` | `title` | Unchanged. |

  ## Deprecation of Legacy Benefits API

  > 🚧 **Breaking Change**\
  > The legacy Benefits API has been deprecated and will be removed on **August 31, 2025**.\
  > Please use the new Benefits API endpoints for all benefit-related operations. Legacy endpoints will continue to function until this date but will not receive updates or bug fixes.

  ## Deprecation of Legacy Benefits API

  As part of improving our API and providing a more consistent experience, we are deprecating the legacy Benefits endpoints. We have split the functionality into two distinct sets of API endpoints: one for employers and one for employees. This allows us to better align the Benefits functionality with our existing API structure.

  All existing data has been migrated to the new endpoints, and you can continue to access your employee and employer benefits data without interruption. All existing Benefit and Benefit Line Item ULIDs have been preserved on the corresponding Employee Benefit and Employee Benefit Line Item records.

  More information can be found in the [Configuring Benefits documentation](/guides/payroll-fundamentals/configuring-benefits).

  As well as providing a more consistent API experience, these changes are required to offer improved functionality for reporting and GL code mapping.

  ## Legacy Benefits API Deprecation

  The following endpoints are now deprecated and have been replaced by the new Employee and Employer Benefits API endpoints:

  * `/benefits` → replaced by:
    * `/employee_benefits`
    * `/employer_benefits`

  * `/benefit_line_items` → replaced by:
    * `/employee_benefit_line_items`
    * `/employer_benefit_line_items`

  * `/benefit_types` → replaced by:
    * `/employee_benefit_types`
    * `/employer_benefit_types`

  ## Benefit Types

  Previously, a single `benefit_type` was used to categorize benefits. This did not correctly represent benefits as they are used in the real world. Some benefits are contributed to by both the employer and employee, while others are only contributed to by one party. This ambiguity made accurate reporting and accounting more difficult.

  To address this, we have introduced two new benefit types: `employee_benefit_type` and `employer_benefit_type`. The two benefit types now contain different values, reflecting the distinct contributions made by employees and employers. For example, `pension_rrsp` may appear in both `employee_benefit_type` and `employer_benefit_type`, whereas `gift_near_cash` will only appear in `employer_benefit_type`.

  These changes not only provide a more consistent API experience but also enable improved reporting and GL code mapping.
</Update>

<Update label="May 2025">
  ## Updates to Line Item Type Filters

  > 🚧 **Breaking Change**
  > Type filters in Line Item listing endpoints have been replaced with `include_types`.
  > The deprecated filters listed below will be removed on **June 30, 2025**.

  ## Renamed Type Filters for Line Item Listings

  The following query parameters have been renamed to `include_types` for consistency across line item listing endpoints:

  * `allowance_type` → `include_types` ([Allowances](https://docs.nmbr.co/reference/allowance-line-items-index))
  * `benefit_type` → `include_types` ([Benefits](https://docs.nmbr.co/reference/benefit-line-items-index))
  * `deduction_type` → `include_types` ([Deductions](https://docs.nmbr.co/reference/deduction-line-items-index))
  * `earning_type` → `include_types` ([Earnings](https://docs.nmbr.co/reference/earning-line-items-index))
  * `employer_statutory_withholding_type` → `include_types` ([Employer Statutory Withholdings](https://docs.nmbr.co/reference/employer-statutory-withholding-line-items-index))
  * `reimbursement_type` → `include_types` ([Reimbursements](https://docs.nmbr.co/reference/reimbursement-line-items-index))
  * `statutory_withholding_type` → `include_types` ([Statutory Withholdings](https://docs.nmbr.co/reference/statutory-withholding-line-items-index))

  ## New Filtering Options

  All line item listing endpoints now support both:

  * **`include_types`**: Return only items matching one or more specified types.
    *Example*: Retrieve only `wage` and `overtime` earnings.

  * **`exclude_types`**: Exclude items of one or more specified types from the results.
    *Example*: Omit `union_dues` from deduction results.

  ***

  These changes promote consistency and improve filtering flexibility across the API.
</Update>

<Update label="April 2025">
  ## Additional Validation on Date Fields

  > 🚧 Breaking Change
  > Additional validation will be performed on date fields as of **May 1st, 2025**.

  ## Additional Validation on Date Fields

  Our API accepts and returns date-related fields following the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) standard:

  * `date` fields are formatted `YYYY-MM-DD` without a time component (e.g. `2023-01-01`)
  * `date-time` fields are formatted `YYYY-MM-DDThh:mm:ss.sssZ` (e.g. `2023-01-01T06:30:00.000000Z`)

  However, some endpoints are not currently validating the format of some `date` fields, and are accepting the `date-time` format or other formats.

  We will be introducing validation on these fields beginning May 1, 2025, and accepting only the `date` format after that.

  The following key fields have been identified as changing:

  * When creating or updating [employees](https://docs.nmbr.co/reference/employees-store), the `date_of_birth` field must be formatted `YYYY-MM-DD`.

  * When creating or updating [allowances](https://docs.nmbr.co/reference/allowances-store), [benefits](https://docs.nmbr.co/reference/benefits-store), [deductions](https://docs.nmbr.co/reference/deductions-store), [reimbursements](https://docs.nmbr.co/reference/reimbursements-store), or [pay rates](https://docs.nmbr.co/reference/pay-rates-store), the `effective_from` and `effective_to` fields must be formatted `YYYY-MM-DD`.

  * When creating or updating [pay schedules](https://docs.nmbr.co/reference/pay-schedules-store), the `anchor_pay_date` and `anchor_end_of_pay_period` fields must be formatted `YYYY-MM-DD`.

  * When [terminating work assignments](https://docs.nmbr.co/reference/work-assignments-terminate), the `effective_date` field must be formatted `YYYY-MM-DD`.

  * When filtering reports by pay date, the `pay_date_from` and `pay_date_to` fields must be formatted `YYYY-MM-DD`.

  However, this change will apply to **all** fields documented as `date` in our documentation. Please ensure that `date` fields are properly formatted.

  ## amount Required on Reimbursements

  > 🚧 Breaking Change
  > `amount` field required on reimbursements as of **May 30th, 2025**.

  ## `amount` Required on Reimbursements

  When [creating reimbursements](https://docs.nmbr.co/reference/reimbursements-store), the `amount` field is not currently a required field.

  We will be making the `amount` field a required field beginning May 30, 2025, and requiring a value for the field after that.

  Please ensure the `amount` field is supplied when creating reimbursements.
</Update>

<Update label="March 2025">
  ## Deprecating Vacation Pay on Pay Rates

  > 🚧 Deprecation Notice
  > Vacation Pay on Pay Rates is being deprecated and will be removed on **May 15th, 2025**.

  ## Deprecating Vacation Pay on Pay Rates

  As part of improvements to functionality for Vacation Pay, we have deprecated the Vacation Pay attributes on the Pay Rate entity.

  * `vacation_pay_percentage` - this attribute is deprecated and has been removed.
  * `vacation_pay_method` - this attribute is deprecated and has been removed.

  These changes will take effect on May 15th, 2025.

  ## Migrating to Vacation Pay Settings

  To manage the vacation pay percentage and payout methods for a Work Assignment, you can use the `vacation_pay_settings` endpoint. This entity will allow you to set the percentage, the effective dates, and method of vacation pay for a specific Work Assignment.

  All eligible earning line items will have vacation pay calculated based on the active Vacation Pay Setting and the Province of Employment for the Work Assignment.

  To read more, please see the [Vacation Pay Guide](https://docs.nmbr.co/docs/vacation-pay).
</Update>

<Update label="July 2024">
  ## Standardizing Historical Payroll Terminology

  We've standardized on the term "historical payroll" for payrolls run with a different provider in the current calendar year. To create a historical payroll, a post request should use the `type: historical`. View [docs](https://docs.nmbr.co/docs/historical-payroll).
</Update>

<Update label="May 2024">
  ## Updates to Future PayStub Line Items

  **Enhanced Line Item Generation:** We’ve refined the generation process for recurring line items on future Pay Stubs. Now, line items for recurring Earnings, Benefits, Reimbursements, Allowances, and Deductions will automatically populate once the preceding payroll changes status to paid. This ensures that your upcoming Pay Stubs reflect the most current and accurate information.

  ## Changes to Validation on Pay Rates

  **Required `expected_hours_per_week` Field**: To improve the accuracy of Statutory Withholdings for off-cycle Payrolls, the `expected_hours_per_week field` is now mandatory when creating a new Pay Rate. This update helps minimizing discrepancies and potential errors in payroll processing.
</Update>
