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

# Importing Hours

> Updating hours worked for individual employees or contractors

## Updating hours worked

The Nmbr API surfaces an endpoint that can be used to import hours for many employees at once.

### Supported Earning Types

The supported earning line item types are:

* `wage` (multiple require a `pay_rate_id` and/or `earned_on`)
* `salary` (multiple require a `pay_rate_id` and/or `earned_on`)
* `overtime` (multiple require an `overtime_rate_id`, `rate_multiplier`, and/or `earned_on`)
* `vacation_pay` (multiple require a `pay_rate_id` and/or `earned_on`)

### Simple Scenario

In this simple scenario, each employee has been configured with a single Pay Rate. To run payroll accurately, you will be required to update the hours for each Earning Line Item generated from the Pay Rates.

To cut down on API calls, use the `POST /payrolls/{payroll}/hours` endpoint to import hours for multiple employees at once.

```bash theme={null}
curl --request POST \
     --url https://sandbox.nmbr.co/services/payroll/payrolls/<payroll_id>/hours \
     --header 'Authorization: Bearer <access_token>' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '{ 
          "data": [
            {
              "work_assignment_id": "wrk_001",
              "wage": [
                {
                  "hours": 10
                }
              ]
            },
            {
              "work_assignment_id": "wrk_002",
              "wage": [
                {
                  "hours": 15
                }
              ]
            }
          ]
     }'
```

### A More Complex Scenario

In some cases, employees may have multiple Pay Rates and Overtime Rates, resulting in many Earning Line Items.

In order for the system to know which hours correspond with each Earning Line Item, the API requires you to provide either a `pay_rate_id`, `overtime_rate_id`, or `rate_multiplier`, depending on the type of earning.

```bash theme={null}
curl --request POST \
     --url https://sandbox.nmbr.co/services/payroll/payrolls/<payroll_id>/hours \
     --header 'Authorization: Bearer <access_token>' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '{ 
          "data": [
            {
              "work_assignment_id": "wrk_001",
              "salary": [
                {
                  "pay_rate_id": "pay_000",
                  "hours": 40
                }
              ],
              "wage": [
                {
                  "pay_rate_id": "pay_001",
                  "hours": 10
                },
                {
                  "pay_rate_id": "pay_002",
                  "hours": 15
                }
              ],
              "overtime": [
                {
                  "rate_multiplier": 1.5,
                  "hours": 3
                },
                {
                  "rate_multiplier": 2,
                  "hours": 6
                },
                {
                  "overtime_rate_id": "ovr_001",
                  "hours": 1
                }
              ],
              "vacation_pay": [
                {
                  "pay_rate_id": "pay_001",
                  "hours": 5
                }
              ]
            }
          ]
     }'
```

### Tracking Hours by Date

If you track hours per day (or any other date granularity within the payroll period), you can attach an `earned_on` date to each entry. This is supported on every earning type.

The `earned_on` value:

* Must be a date that falls within the payroll's pay period.
* Is part of the entry's scoping key, so you can submit multiple entries against the same `pay_rate_id` (or `overtime_rate_id` / `rate_multiplier`) as long as their `earned_on` dates differ.

```bash theme={null}
curl --request POST \
     --url https://sandbox.nmbr.co/services/payroll/payrolls/<payroll_id>/hours \
     --header 'Authorization: Bearer <access_token>' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '{ 
          "data": [
            {
              "work_assignment_id": "wrk_001",
              "wage": [
                {
                  "pay_rate_id": "pay_001",
                  "hours": 8,
                  "earned_on": "2026-04-13"
                },
                {
                  "pay_rate_id": "pay_001",
                  "hours": 8,
                  "earned_on": "2026-04-14"
                },
                {
                  "pay_rate_id": "pay_001",
                  "hours": 6,
                  "earned_on": "2026-04-15"
                }
              ],
              "overtime": [
                {
                  "rate_multiplier": 1.5,
                  "hours": 2,
                  "earned_on": "2026-04-15"
                }
              ]
            }
          ]
     }'
```

### Targeting a Business Preset

When you import hours for distinct configured workflows that share an earning type and rate, include `business_preset_id` on each earning entry. The preset identifies which line item to update or create.

The preset must belong to the payroll's business entity, have the `earning` type, and match the entry's earning type when the preset has a subtype.

```bash theme={null}
curl --request POST \
     --url https://sandbox.nmbr.co/services/payroll/payrolls/<payroll_id>/hours \
     --header 'Authorization: Bearer <access_token>' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '{
          "data": [
            {
              "work_assignment_id": "<work_assignment_id>",
              "vacation_pay": [
                {
                  "pay_rate_id": "<pay_rate_id>",
                  "business_preset_id": "<first_business_preset_id>",
                  "hours": 8
                },
                {
                  "pay_rate_id": "<pay_rate_id>",
                  "business_preset_id": "<second_business_preset_id>",
                  "hours": 4
                }
              ]
            }
          ]
     }'
```

The preset is part of the matching key. Re-send the same earning type, rate, date, and preset to update the same line item. Use a different compatible preset to keep the line items separate. Requests without `business_preset_id` keep their existing matching behaviour.

See [Presets](/guides/advanced/presets) to create and manage Business Presets.
