GuidesAPI ReferenceChangelog
Log In
Guides

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:

{
  "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",
      "version": "19289df18e6e20f797de4a585ea5a91535c7ddf7",
      "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"
        }
      ]
    }
  ],
  "fixed_compensation_types": [
    {
      "name": "Bonus"
    },
    {
      "name": "Commission"
    },
    {
      "name": "Correction Payment"
    },
    {
      "name": "Cash Tips"
    },
    {
      "name": "Paycheck Tips"
    },
    {
      "name": "Reimbursement"
    }
  ]
}

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. To add a fixed compensation for an employee compensation, add a new object to the fixed_compensations array with a valid name from fixed_compensation_types and an amount. If the amount is 0.00 it will not be persisted and returned in the update response. You cannot add or remove hourly_compensations, only update the hours field. The types of hours included in the hourly_compensations array are based on the type of payroll and the employee's FLSA status.

🚧

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.

Common Questions

If we send you a lump sum of hours, can you calculate how the hours should be allocated between regular, overtime, and/or double overtime?

No, when sending hours to Gusto you will need to specify the allocation of hours between Regular Hours, Overtime, and Double Overtime. From there, Gusto will calculate the total gross wages for the employee based on hourly rate, overtime and double overtime rates.

Can we process payroll through the API?

No, given the sensitive nature of payroll, this should be done in Gusto to allow the user to review and confirm before processing.

Do we have access to form data, such as the W2 info or 941s?

Specific forms and their fields are not available in the API. However, the payrolls endpoint provides everything Gusto uses in our form calculations and you can pull this data to then calculate the form information you may need – be sure to consider benefits and time periods that may impact total taxable wages.

How do I set up a child-support garnishment in my Gusto demo account?

At this time we do not support child support garnishments in the demo environment since they require a valid Agency and CSE Case Number to set up. You will receive the following error message when attempting to set this up in demo: “Oh no! Something went wrong.”

How do I GET gross wage totals for paid time off (PTO)?

Our payroll endpoint will return a breakdown of PTO hours (vacation or sick) by employee for each payroll but not the total gross wages for total PTO in a given time period. However, this can be calculated using the number of hours returned for each time off type and the employees hourly rate. Our payrolls endpoint returns the raw payroll data, you just may need to set up some custom calculations on your end to get the data in the exact format you need.

How do I retrieve off-cycle and/or bonus payrolls?

The request GET /v1/companies/{company_uuid}/payrolls?processing_statuses=processed,unprocessed&payroll_types=off_cycle returns off-cycle payrolls, including bonus payrolls.