Accrual Policies
Learn how to set up and manage a PTO or Sick Time Policy for your workers
Intro
Offering a a PTO or sick time policy is a good way to attract a great workforce and can be critical for employer compliance. Managing these policies, however, involves proper accrual rates, PTO usages, capping PTO balances, rollovers, etc.
In Zeal, Accrual Policies represent policies that can be accrued by and assigned to workers. These Accrual Policies, when attached to a worker, contain an accrual balance that is automatically tracked and updated by Zeal based on the worker's shifts as well as their specific Accrual Policy specifications.
In this guide
- What an accrual policy is
- How to set up a standard policy
- How to add employees to a policy
- How to track usages that affect the balance (e.g. PTO usage)
- How to handle more complex rules
What is an accrual policy?
An accrual policy is simply a set of rules that define how employees accrue hours for various perks such as PTO or sick leave. The basic rules generally state the rate of accrual and the number of hours that must be worked before that rate is accrued (e.g. an employee earns 5 hours for every 80 hours worked). The policy may also include more complicated rules such as annual caps, wait periods, and rollover rules.
Managing a standard PTO policy
Letโs start with a basic accrual policy. Weโll define a PTO policy where employees accrue 5 hours off for every 80 hours worked.
Step 1: Create the policy
To create an Accrual Policy, utilize the Create Accrual Policy or POST /accrualPolicy
endpoint. The endpoint requires the following body parameters:
companyID
: Zeal Company IDpolicy_code
: Custom code you must assign for the policy. This is the unique identifier for the policypolicy_type
: Type of the accrual policy (accepts: pto, sick_leave, or custom).
Note: The accrual policy type has no effects on other parameters other than classification of the accrual policy. Therefore, apto
policy type does not differ from asick_leave
type other than in classification.
Other parameters:
As mentioned in the Accrual Policy object reference, the POST endpoint accepts other body parameters to further specify the Accrual Policy being created:
attribute | type | description |
---|---|---|
policy_name | string | Custom name that can be assigned for the policy |
policy_effective_date | YYYY-MM-DD | The effective start date of the policy |
accrual_rate_hours | float | The rate at which employees will accrue hours |
accrual_period_hours | float | The number of hours employees need to work to accrue accrual_rate_hours |
immediate_balance | float | The immediate hour balance the employee would receive |
include_doubletime | boolean | Include if double-time work is eligible for hour accrual |
include_overtime | boolean | Include if overtime work is eligible for hour accrual |
accrual_waiting_period | float | The number of hours the employees need to work before they are eligible to begin accruing time for policy |
accrual_cap | float | Max hours an employee can accrue in one year until the rollover date |
rollover_cap | float | Max hours an employee can rollover from one year to the next year, on a specified rollover date |
rollover_date | float | Required if the user passes a value for rollover_cap or accrual_cap |
Letโs create a PTO policy with an accrual rate of 5 hours for every 80 hours worked. We will setaccrual_rate_hours
at 5
and accrual_period_hours
to 80
.
curl --request POST \
--url https://api.zeal.com/accrualPolicy \
--header 'Authorization: Bearer {{TEST_API_KEY}}' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"companyID": "{{companyID}}",
"policy_code": "PTO-01",
"policy_type": "pto",
"accrual_rate_hours": "5",
"accrual_period_hours": "80",
"include_doubletime": false,
"include_overtime": false,
}
'
This will return an Accrual Policy object:
{
"companyID": "e9a3c22ea5276a1ea82dba27ca6e1a2ea",
"policy_code": "PTO-01",
"policy_type": "pto",
"policy_name": null,
"policy_effective_date": "2023-03-01",
"accrual_rate_hours": 5,
"accrual_period_hours": 80,
"immediate_balance": 0,
"include_doubletime": false,
"include_overtime": false,
"accrual_waiting_period": 0,
"accrual_cap": 0,
"rollover_cap": 0,
"rollover_date": null,
"policy_status": "live"
}
Step 2: Add employees
With the policy created, next we add our employees to the policy.
Add/remove employees to accrual policy
curl --request POST \
--url https://api.zeal.com/accrualPolicyEmployees \
--header 'Authorization: Bearer {{TEST_API_KEY}}' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"add_employees": [
"{{firstEmployeeID}}",
"{{secondEmployeeID}",
"{{thirdEmployeeID}"
],
"companyID": "{{companyID}}",
"policy_code": "PTO-01"
}
'
All the employees added will now automatically begin accruing hours based on the payroll hours submitted.
Step 3: Get accrual balance
We can get the balance of an employee at any time.
curl --request GET \
--url 'https://api.zeal.com/accrualBalance?companyID={{companyID}}&employeeID={{employeeID}}' \
--header 'Authorization: Bearer {{TEST_API_KEY}}' \
--header 'accept: application/json'
This will give us a response detailing the policy and the hours the employee has under that policy.
{
"success": true,
"data": {
"companyID": "{{companyID}}",
"accrualPolicies": [
{
"policy_code": "PTO-01",
"employeeID": "{{employeeID}}",
"policy_type": "pto",
"accrual_balance": 20,
"accrual_rate_unit": "hours",
"policy_status": "live"
}
]
}
}
Step 4: Apply accrual usage
When an employee requests off and completes it, we can apply usage, which affects the employee's balance. Let's say our employee takes 16 hours off (from their previous balance of 20hrs).
curl --request PATCH \
--url https://api.zeal.com/accrualPolicy/{{policyCode}}/usage \
--header 'Authorization: Bearer {{TEST_API_KEY}}' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"employees": [
{
"employeeID": "66c7738bbabb2213d7628c02",
"start_date": "2024-12-10",
"end_date": "2024-12-12",
"amount": 16
}
],
"companyID": "{{companyID}}"
}
'
Now the employee's balance is updated to 4 hours of PTO. They continue to accrue hours automatically as they work. The next time the employee completes a PTO request, we simply repeat step 4.
Here are a few important notes:
- The accrual policy that you are referencing as a path parameter (using policyCode) in this request must have a valid
policy_effective_date
. - The employee must already be added to the accrual policy in order for you to assign usage for this employee and under this accrual policy.
- Zeal finds an employee check for this employee with the reporting period that encapsulates the
start_date
of the usage object.- For example, if an employee check was created for Jim with reporting period January 6th - January 13th and an accrual usage was set with
start_date
January 8th andend_date
January 15th, (Jan 8th-Jan 15th), then Zeal will attach the usage to this check because thestart_date
falls within the reporting period of that check. - If there is no existing check for this employee with a reporting period that encapsulates the
start_date
, then you will get an error (No check for given date range
)
- For example, if an employee check was created for Jim with reporting period January 6th - January 13th and an accrual usage was set with
- Usage will also show on the paystub of an existing employee check with a reporting period that encompasses the
start_date
of the usage object. - It is possible for the accrual balance to be negative for an employee, if using usage.
Corrections to Usage
In case you misapplied usage, you can make a similar call to adjust the usage and balance.
Let's say instead of using 16 hours, this worker actually only used 14 hours. You can apply a correction of 2 hours, reducing the employee's usage within the same date range used above:
curl --request PATCH \
--url https://api.zeal.com/accrualPolicy/{{policyCode}}/usage \
--header 'Authorization: Bearer {{TEST_API_KEY}}' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"employees": [
{
"employeeID": "66c7738bbabb2213d7628c02",
"start_date": "2024-12-10",
"end_date": "2024-12-12",
"correction": true,
"amount": 2
}
],
"companyID": "{{companyID}}"
}
'
After this request is applied, the total usage for the employee within the specified date range would be calculated to 14 (instead of 16 previously).
Handling more complex cases
Many accrual policies have additional rules such as annual caps, waiting periods, and rollovers. Thankfully, Zeal's system manages these complexities with ease.
Setting an annual cap
It's common to set a cap on the number of hours that can be accrued in one year. If you have such a policy in place, all you have to do is tell Zeal the cap, and the system will stop adding to an employee's balance once they've hit the annual limit. Let's update our policy with an accrual_cap
set to 100
hours.
curl --request PATCH \
--url https://api.zeal.com/accrualPolicy \
--header 'Authorization: Bearer {{TEST_API_KEY}}' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"companyID": "{{companyID}}",
"policy_code": "PTO-01",
"accrual_cap": 100
}
'
Now our employee's are only able to accrue up to 100 hours of PTO within a calendar year. At midnight on the first day of the year, the cap resets and employees resume accruing hours.
Setting a waiting period
Many policies define a waiting period, or cliff, that an employee must meet before they can begin accruing hours. This is generally used to prevent new hires from immediately taking time off. Let's update our policy with a accrual_waiting_period
of 160
hours.
curl --request PATCH \
--url https://api.zeal.com/accrualPolicy \
--header 'Authorization: Bearer {{TEST_API_KEY}}' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"companyID": "{{companyID}}",
"policy_code": "PTO-01",
"accrual_waiting_period": 160
}
'
Now our employees must work 160 hours before they are able to begin accruing PTO.
Setting rollover rules
Rollover rules define how many hours an employee can keep, or rollover, into the next year. These rules generally set a cap on hours and a date that the rollover happens. On the given date, any hours an employee has accrued above the cap are forfeited. This encourages employees to use their time off for rest and recuperation. Let's update our policy with a rollover_cap
of 60
hours and the rollover_date
of 01-01
(Jan. 1st).
curl --request PATCH \
--url https://api.zeal.com/accrualPolicy \
--header 'Authorization: Bearer {{TEST_API_KEY}}' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"companyID": "{{companyID}}",
"policy_code": "PTO-01",
"rollover_cap": 60,
"rollover_date": "01-01"
}
'
Now with our rollover rules in place, employees can only carry up to 60 hours of PTO into the next calendar year. Note: many policies set the rollover date to the first day of the year, but you can set the date to whatever works for your policy.
Recap
- An accrual policy is simply a set of rules that define how employees accrue hours for various perks such as PTO or sick leave
- Managing accruals with Zeal generally involves 4 steps: create an accrual policy, add employees to the policy, query for accrual balances, apply usage when employees take time off
- Zeal's system accounts for complex rules such as annual caps, waiting periods, and rollovers
Updated about 11 hours ago