GuidesAPI ReferenceChangelog
Log In

Updating Payrolls

Payrolls can contain an overwhelming amount of information, but the basics of updating information should be a pain-free process.

We automatically pre-generate scheduled regular payrolls based on the company’s pay schedule and corresponding pay periods. Pay periods are the foundation of payroll. Compensation, time & attendance, taxes, and expense reports all rely on when they happened.

1. Retrieve Upcoming Payroll

Upcoming regular payrolls can be retrieved using the GET companies/{company_uuid}/payrolls?processing_statuses=unprocessed endpoint. The next upcoming payroll will be the earliest unprocessed payroll. By default, the payrolls#index endpoint will return only processed payrolls so make sure to add the processing_statuses=unprocessed query parameter. It's recommended to use the optional query parameters start_date & end_date to narrow the response in order to avoid potential timeouts.

The example cURL below is filtering to show unprocessed payrolls between 2021-02-01 and 2021-03-01. To see all query values review our API Reference.

curl --request GET \
     --url 'https://api.gusto-demo.com/v1/companies/company_id/payrolls?processing_statuses=unprocessed&payroll_types=regular&start_date=2021-02-01&end_date=2021-03-31' \
     --header 'accept: application/json' \
     --header 'authorization: Bearer <<COMPANY_API_TOKEN>>'

This query will return an JSON array of payroll objects:

[
  {
    "payroll_deadline": "2021-02-18T20:00:00Z",
    "check_date": "2021-02-22",
    "processed": false,
    "processed_date": null,
    "calculated_at": null,
    "payroll_uuid": "b50e611d-8f3d-4f24-b001-46675f7b5777",
    "company_uuid": "6bf7807c-a5a0-4f4d-b2e7-3fbb4b2299fb",
    "pay_period": {
      "start_date": "2021-02-01",
      "end_date": "2021-02-15",
      "pay_schedule_uuid": "00ebc4a4-ec88-4435-8f45-c505bb63e501"
    }
  },
  {
    "payroll_deadline": "2021-03-01T20:00:00Z",
    "check_date": "2021-03-05",
    "processed": false,
    "processed_date": null,
    "calculated_at": null,
    "payroll_uuid": "79598603-2975-40fc-9b18-a6cf835a4744",
    "company_uuid": "6bf7807c-a5a0-4f4d-b2e7-3fbb4b2299fb",
    "pay_period": {
      "start_date": "2021-02-15",
      "end_date": "2021-02-28",
      "pay_schedule_uuid": "00ebc4a4-ec88-4435-8f45-c505bb63e501"
    }
  }
]

2. Prepare the Payroll

Before updating a payroll, it needs to be prepared using the PUT companies/{company_uuid}/payrolls/{payroll_uuid}/prepare endpoint. This endpoint will return the version and the employee_compensations data you need to update the payroll.

You can update Regular Hours, Overtime, and Double overtime for Salaried Nonexempt employees, but only Regular Hours can be updated for Exempt employees since they are not eligible for overtime.

curl --request PUT \
     --url https://api.gusto-demo.com/v1/companies/{company_uuid}/payrolls/{payroll_uuid}/prepare \
     --header 'accept: application/json' \
     --header 'authorization: Bearer <<COMPANY_API_TOKEN>>' \
     --header 'content-type: application/json'

Here is a sample response from the prepare endpoint:

[
  {
    "version": "19289df18e6e20f797de4a585ea5a91535c7ddf7",
    "payroll_deadline": "2021-02-18T20:00:00Z",
    "check_date": "2021-02-22",
    "processed": false,
    "processed_date": null,
    "calculated_at": null,
    "off_cycle": false,
    "payroll_uuid": "b50e611d-8f3d-4f24-b001-46675f7b5777",
    "company_uuid": "6bf7807c-a5a0-4f4d-b2e7-3fbb4b2299fb",
    "pay_period": {
      "start_date": "2021-02-01",
      "end_date": "2021-02-15",
      "pay_schedule_uuid": "00ebc4a4-ec88-4435-8f45-c505bb63e501"
    },
    "payroll_status_meta": {
        "cancellable": false,
        "expected_check_date": "2021-02-22",
        "initial_check_date": "2021-02-22",
        "expected_debit_time": "2021-02-18T23:00:00Z",
        "payroll_late": false,
        "initial_debit_cutoff_time": "2021-02-18T23:00:00Z"
    },
    "employee_compensations": [
      {
        "employee_uuid": "187412e1-3dbe-491a-bb2f-2f40323a7067",
        "excluded": false,
        "gross_pay": "2791.25",
        "net_pay": "1953.31",
        "payment_method": "Direct Deposit",
        "fixed_compensations": [
          {
            "name": "Bonus",
            "amount": "100.00",
            "job_uuid": "94e0d15e-9ed2-4077-98f6-64554f242ba5"
          },
          {
            "name": "Reimbursement",
            "amount": "100.00",
            "job_uuid": "91bc3b43-ded0-4ee7-98fe-215499e909ba"
          }
        ],
        "hourly_compensations": [
          {
            "name": "Regular Hours",
            "hours": "10.000",
            "job_uuid": "bd378298-3e0c-4145-904a-baadf8a91fa3",
            "compensation_multiplier": 1
          },
          {
            "name": "Overtime",
            "hours": "0.000",
            "job_uuid": "9d3760f0-d1f9-4700-8817-0fe2dce5cf23",
            "compensation_multiplier": 1.5
          },
          {
            "name": "Double overtime",
            "hours": "0.000",
            "job_uuid": "b5eef9a9-4a87-4649-a80d-14878c05f44e",
            "compensation_multiplier": 2
          }
        ],
        "paid_time_off": [
          {
            "name": "Vacation Hours",
            "hours": "20.000"
          },
          {
            "name": "Sick Hours",
            "hours": "0.000"
          },
          {
            "name": "Holiday Hours",
            "hours": "0.000"
          }
        ]
      }
    ]
  }
]

3. Update the Payroll

Next you can update the payroll with the new employee_compensation data using the PUT companies/{company_uuid}/payrolls/{payroll_uuid} endpoint, passing in the version and updated employee_compensations parameters from the prepare endpoint.

🚧

Avoid Overwriting Data

Unless you are certain that you want to overwrite the data returned via the API, you should only add to it.

In our example, the employee already has 10 hours of Regular Hours and 20 hours of Vacation Hours. In order to add 5 hours to each, 15 hours and 25 hours, respectively, must be passed in order to maintain the hours existing prior to your update.

curl --request PUT \
     --url https://api.gusto-demo.com/v1/companies/{company_uuid}/payrolls/{payroll_uuid} \
     --header 'accept: application/json' \
     --header 'authorization: Bearer <<COMPANY_API_TOKEN>>' \
     --header 'content-type: application/json' \
     --data '
{
     "version": "19289df18e6e20f797de4a585ea5a91535c7ddf7",
     "employee_compensations": [
          {
               "employee_uuid": "187412e1-3dbe-491a-bb2f-2f40323a7067",
               "hourly_compensations": [
                    {
                         "name": "Regular Hours",
                         "hours": "15.000",
                         "job_id": 1,
                         "job_uuid": "91bc3b43-ded0-4ee7-98fe-215499e909ba"
                    }
               ],
               "paid_time_off": [
                    {
                         "name": "Vacation Hours",
                         "hours": "25.000"
                    }
               ]
          }
     ]
}
'
const fetch = require('node-fetch');

const url = 'https://api.gusto-demo.com/v1/companies/{company_uuid}/payrolls/2021-02-01/2021-02-15';
const options = {
  method: 'PUT',
  headers: {
    accept: 'application/json',
    'content-type': 'application/json',
    authorization: 'Bearer <<COMPANY_API_TOKEN>>'
  },
  body: JSON.stringify({
    version: '19289df18e6e20f797de4a585ea5a91535c7ddf7',
    employee_compensations: [
      {
        employee_uuid: '187412e1-3dbe-491a-bb2f-2f40323a7067',
        hourly_compensations: [
          {
            name: 'Regular Hours',
            hours: '15.000',
            job_id: 1,
            job_uuid: '91bc3b43-ded0-4ee7-98fe-215499e909ba'
          }
        ],
        paid_time_off: [
          {name: 'Vacation Hours', hours: '25.000'}
        ]
      }
    ]
  })
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error('error:' + err));

The update endpoint will return the same response shape as prepare, with the data reflecting your changes.

Conflicts

If information has changed since you last prepared the payroll, the version will have changed and you will receive a 409 Conflict response code. This means that you will need to re-prepare the payroll data for that pay period and resubmit your updates.

Do not simply copy over the new version and resubmit, as you'll likely be overwriting information that the user, an internal Gusto process, or another 3rd party application has added or changed. This can lead to incorrect pay, miscalculated taxes, and upset users.