Payroll Preview and Approval
Creating, previewing, and approving payrolls.
At the core of Check API is the flow for payroll processing: creating payrolls, adding payees and earnings, and previewing and approving payrolls.
As of version 2025-01-01
, Check API supports payroll processing for payrolls with up to 1,500 payees (payroll items and contractor payments) by previewing payrolls asynchronously, while payrolls with up to 500 payees can be processed synchronously.
This guide will walk through the steps and the different options available based on your needs and the size of employers that you support.
Should you build against synchronous or asynchronous payroll preview?
The answer to this question depends on the size of employers that you expect to support now and into the future.
If you expect to never exceed 500 payees on a given payroll, then the synchronous preview path offers a simpler and more straightforward path to processing payrolls for your customers.
However, if you think it's a possibility that you will support employers with more than 500 payees on a given payroll in the future, then it is recommended to integrate with asynchronous preview from the outset. This will ensure that your integration with Payroll API is already built for scale, and you will not need to change your integration when you have a large employer attempt to process payroll in the future.
Create a payroll
We’ll begin by creating a payroll object. The payroll object defines a pay period, which is the timespan in which wages were earned, and a payday, which is the date on which the payment for those wages will be made.
Example Request to Create a Payroll:
curl -X POST 'https://sandbox.checkhq.com/payrolls' -d '{
"company": "com_1234567890abcdef",
"period_start": "2024-12-01",
"period_end": "2024-12-06",
"payday": "2024-12-13"
}'
Ensure that the payday
aligns with valid paydays for direct deposits. If you wish for Check to validate this for you, you can use a pay schedule to automate the calculation of pay periods and paydays. By creating a pay schedule and associating it with the payroll, Check will automatically validate the payday
, period_start
, and period_end
dates, as well as apply the pay_frequency
from the pay schedule.
Add payroll items and/or contractor payments
In addition to creating a payroll, you also need to create payroll items, which include the various earning amounts, hours, and workplaces for each employee during the pay period of the payroll, as well as contractor payments, which include payments made to contractors.
You can create payroll items in bulk by making a POST
request to the /payroll_items
endpoint with an array of payroll item objects, and similarly for /contractor_payments
.
Example Request to Create Payroll Items:
curl -X POST 'https://sandbox.checkhq.com/payroll_items' -d '[
{
"payroll": "pay_1234567890abcdef",
"employee": "emp_1234567890abcdef",
"earnings": [
{
"type": "hourly",
"workplace": "wrk_1234567890abcdef",
"amount": "390.00",
"hours": 40
}
],
"reimbursements": [
{
"amount": "50.00",
"description": "Travel expenses"
}
]
},
{
"payroll": "pay_1234567890abcdef",
"employee": "emp_1234567890abcdef",
"earnings": [
{
"type": "salary",
"workplace": "wrk_0987654321fedcba",
"amount": "1500.00"
}
]
}
]'
Example Request to Create Contractor Payments:
curl -X POST 'https://sandbox.checkhq.com/contractor_payments' -d '[
{
"payroll": "pay_1234567890abcdef",
"contractor": "ctr_XyZ1234567890abc",
"payment_method": "manual",
"amount": "500.00",
"reimbursement_amount": "75.00"
},
{
"payroll": "pay_1234567890abcdef",
"contractor": "ctr_LmNoPqRsTuVwXyZ123",
"payment_method": "direct_deposit",
"amount": "800.00"
}
]'
Alternatively, you can create the payroll items and contractor payments in the same request as creating the payroll, by using the optional include_items
and include_contractor_payments
flags. These flags can only be set to true
if the payroll has 500 or fewer payroll items and contractor payments.
Example Request to Create a Payroll with include_items
and include_contractor_payments
curl -X POST 'https://sandbox.checkhq.com/payrolls?include_items=true&include_contractor_payments=true' -d '{
"company": "com_1234567890abcdef",
"period_start": "2024-12-01",
"period_end": "2024-12-06",
"payday": "2024-12-13",
"items": [
{
"employee": "emp1234567890abcdef",
"earnings": [
{
"type": "hourly",
"workplace": "wrk_1234567890abcdef",
"amount": "390.00",
"hours": 40
}
]
}
],
"contractor_payments": [
{
"contractor": "ctr_LmNoPqRsTuVwXyZ123",
"payment_method": "direct_deposit",
"amount": "800.00"
}
]
}'
The include_items
and include_contractor_payments
flags are also available on the GET /payrolls/:id
and PATCH /payrolls/:id
, and POST /payrolls/:id/preview
endpoints, if you wish to view and/or update payroll items and contractor payments directly from the payroll object.
Preview the payroll
After creating the payroll and adding all of the relevant payroll items and contractor payments, you are ready to calculate tax, benefit, deduction, and net pay amounts from the gross earnings provided. This is referred to as “previewing” the payroll.
Example Preview Payroll Request:
curl -X POST '<https://sandbox.checkhq.com/payrolls/><PAYROLL_ID>/preview'
By default, previewing a payroll is a synchronous operation, and is limited to payrolls with 500 or fewer payroll items and contractor payments. If you wish to see the calculated payroll items and contractor payments as part of the response to the preview request, you can do so by setting the include_items
and include_contractor_payments
flags.
If you have more than 500 payroll items and contractor payments, you will need to preview your payroll asynchronously. This is set using the async=true
flag. This will process the preview request in the background and the payroll object will be updated once the calculation is completed.
Example Asynchronous Preview Payroll Request:
curl -X POST 'https://sandbox.checkhq.com/payrolls/<PAYROLL_ID>/preview?async=true'
The preview
property on the payroll object is where you can view the current status of the payroll preview calculation, as well as a timestamp of when the most recent payroll preview was initiated. When the preview calculation is completed, the status will be updated to succeeded
and a webhook event will be created (more on this below, under "Fetch calculation results").
Example Preview Property on Payroll Object:
{
"id": "pay_1234567890abcdef",
"company": "com_1234567890abcdef",
"period_start": "2024-12-01",
"period_end": "2024-12-06",
"payday": "2024-12-13"
"preview": {
"status": "calculating", // Or "succeeded" or "failed"
"started_at": "2019-06-28T00:00:00.000000Z"
},
"approval_deadline": "2019-07-02T00:00:00.000000Z",
"approved_at": null,
"payday": "2019-07-05",
"status": "paid",
"type": "regular",
...
}
If the payroll object or any related payroll items or contractor payments are modified after a preview is initiated, the preview will be invalidated and the preview
will be reset to null
, which indicates that the preview is no longer valid and the payroll needs to be re-previewed.
Fetch calculation results
If you previewed a payroll asynchronously, then you will need to poll the GET /payrolls/:id
endpoint until the payroll has a preview.status
of succeeded
to view the completed calculation results.
Example Get Payroll Request:
curl -X GET 'https://sandbox.checkhq.com/payrolls/><PAYROLL_ID>'
Alternatively, a Payroll Webhook Event will also be created with event type updated
once the payroll status changes, so you could also listen for this event to identify when the calculation results are complete and ready to view.
Example Payroll Updated Webhook Event:
{
"event": "updated",
"data": {
"id": "pay_1234567890abcdef",
"company": "com_1234567890abcdef",
"period_start": "2024-12-01",
"period_end": "2024-12-06",
"payday": "2024-12-13",
"preview": {
"status": "succeeded",
"started_at": "2019-06-28T00:00:00.000000Z"
},
"approval_deadline": "2019-07-02T00:00:00.000000Z",
"approved_at": "2019-06-29T18:26:56.848920Z",
"payday": "2019-07-05",
"status": "paid",
"type": "regular",
... // remainder of payroll data
}
Note: In order to receive updated
payroll webhook events, you need to ensure your default API version is set to 2025-01-01
or later.
Approve the payroll
Once the payroll has been reviewed and is accurate, you can approve it, which marks the most recent preview calculations as final and transitions the payroll into a pending
status.
Example Approve Payroll Request:
curl -X POST 'https://sandbox.checkhq.com/payrolls/><PAYROLL_ID>/approve'
A payroll can only be approved if it has a preview.status
of succeeded
; i.e., after a successful preview request was completed.
After approval, modifications to the payroll are restricted. If changes are necessary, the payroll must be reopened before it can be modified.
Updated 14 days ago