Guide to the Leave Accrual API

The Leave Accrual API covers the two building blocks of paid time off at Everee: leave policies, which decide who accrues leave and how, and leave types, which are the categories of leave being accrued, like vacation, sick leave or jury duty. This guide explains what each one is, how they work together, and how to use the endpoints, including enrolling workers and managing their balances.

GroupEndpoints
Leave policiesList, get, create, update, and delete or archive a leave policy
EnrollmentsList a policy's enrollments, get an enrollment, enroll workers, unenroll workers, list workers with no policy, and list a worker's enrollments
Worker leaveGet and set a worker's balances, and get and update their award rules
Leave typesList, create, and delete or archive a leave type

The older List leave policies (deprecated) and Get accrued leave balances (deprecated) endpoints still work, but new integrations should use the endpoints above.

How policies and leave types fit together

A leave type is a category of leave. Every leave type pays out under its own pay code, so leave hours of that type show up as earnings on a worker's pay stub.

A leave policy is a set of rules for earning leave. A policy accrues one or more leave types, and workers are enrolled in it. A company can have several policies at once, but a worker is actively enrolled in only one at a time.

Leave policy "Michigan PTO"           Leave types
├── accrues ───────────────────────►  Vacation   → pay code TIME_OFF_TYPE_VACATION
└── accrues ───────────────────────►  Sick       → pay code TIME_OFF_TYPE_SICK

The same leave type can be accrued by more than one policy, and a policy can accrue more than one leave type. Each leave type in a policy shows the payCode it pays out under, which is null for unpaid leave.

A worker's balances are tracked per leave type of the policy they're enrolled in. See Get a worker's leave balances.

Leave policyLeave type
What it isRules for who accrues leave, and howA category of leave, like "Jury Duty"
Identified byidleaveTypeName (no ID). Worker leave endpoints use its pay code
Pays out underThe pay codes of the leave types it accruesIts own pay code
Set up throughThis API, or the Everee admin appThis API, or the Everee admin app

Leave policies

A policy has a name, an optional description, a periodAlignmentMethod, and its leave types. It's either active or archived. Policies created through the API are active at once and take effect today. There are no drafts.

Three kinds of leave type in a policy

Each leave type in a policy is earned in one of three ways, and each has its own list:

ListHow it's earnedPays out?
accruedLeaveTypesA little at a time as workers work. For example, 1 hour for every 30 hours workedYes, under the leave type's pay code
frontLoadedLeaveTypesA lump of hours granted at the start of each period (year, quarter or month)Yes
unpaidFrontLoadedLeaveTypesThe same, for unpaid leaveNo. Unpaid leave has no pay code, so payCode is null

To create a policy, send at least one leave type, and use each leave type only once across the three lists. Leave types are referenced by leaveTypeName, and they have to exist already. Unknown names return a 422 that lists them.

Eligibility

Every leave type has two waiting periods, eligibleAfterEmployedDays and eligibleAfterWorkedHours. A worker starts earning the leave once both are met. Use 0 for both to start straight away.

Award rules

An award rule says how much leave a worker gets, and what limits apply. Every leave type has a baseAwardRule, which applies to a new worker.

For an accrued leave type, the rule sets accrualRatioEarnedHours, the hours earned for every accrualRatioWorkedHours hours worked. For a front-loaded one, it sets frontLoadedHours, the hours granted each period. Rules can also have these optional limits:

LimitWhat it does
maxAnnualAccrualHoursThe most a worker can accrue in a year (accrued types only)
maxBalanceHoursThe most a worker can hold at once (accrued types only)
maxRollOverHoursThe most that carries over into the next year or period
maxNegativeBalanceHoursHow far below zero a balance can go

A limit is on when you include it and off when you leave it out. Leave out a limit and it's left out of responses too.

Tenure tiers

To give long-serving workers more, add tenureAwardRules. Each tier starts at an employedYears value, like 3, and replaces the base rule for workers who've reached it.

  • Tier values are totals, not increases. If the base is 1 hour per 30 hours and the 3-year tier is 1.5, workers at 3 years earn 1.5.
  • A field you leave out of a tier carries over from the tier before it.
  • employedYears must be at least 1 and can't repeat.
  • A tier can only use limits that the base rule uses.
  • Values can't go down as tenure goes up.

Responses always show every field on every tier.

Front-loaded periods

frontLoadedPeriodType is YEAR, QUARTER or MONTH, and sets how often the hours are granted. periodAlignmentMethod is set on the policy and decides when a period starts:

  • CALENDAR starts periods on calendar boundaries, like January 1. A worker's first grant can be prorated for the time left in the period. Set initialFrontLoadedBalanceProrated to choose. It's required for these policies.
  • HIRE_DATE starts each worker's periods on their hire anniversary. These policies support only YEAR, and don't use proration.

Changing and removing a policy

You can change only a policy's name and description through the API. A policy's leave types and award rules can't be edited after it's created. To change them for one worker, use Update a worker's leave award rules.

Deleting a policy removes it if nothing has used it, and archives it otherwise, the same way leave types work. Either way the response is 204. A policy that still has active enrollments can't be removed and returns 409, so unenroll its workers first. Policy names must be unique, ignoring case.

Pay codes

When you create a policy that includes a leave type with no pay code, the pay code is created for you, using the same naming as for leave types, described below. The request returns 409 if that pay code would clash with an existing one, or with a system default's.

Enrollments

A worker earns leave under a policy only while they're enrolled in it. An enrollment ties one worker to one policy for a stretch of time, with a startDate and an optional endDate, and a status:

StatusMeaning
ACTIVEIn effect today
UPCOMINGStarts after today
ENDEDOver

A worker can be actively enrolled in one policy at a time. Enrollment lists show ACTIVE and UPCOMING enrollments unless you pass status.

Workers are identified by their externalWorkerId if you set one, or by Everee's workerId.

  • Enroll workers takes up to 200 workers. Enrollments start tomorrow, and any enrollment in another policy ends today, so a worker moves between policies with no gap. Workers already active in the policy aren't changed.
  • Unenroll workers takes up to 200 enrollmentIds. An active enrollment ends today, and an upcoming one is cancelled. This doesn't move a worker to another policy.
  • List workers with no policy shows current and upcoming employees who need one.

Both write endpoints are all-or-nothing. If anything in the request is wrong, such as an unknown ID, a contractor, or an enrollment that's already ended, nothing changes and the 400 names every problem. Contractors can't be enrolled.

Worker balances and award rules

These endpoints work on one worker's active enrollment. They return 404 if the worker isn't actively enrolled in a policy. Here a leave type is identified by its pay code, like TIME_OFF_TYPE_VACATION, rather than its name.

Balances. Get a worker's leave balances returns one balance per leave type, in hours. Set a worker's leave balance sets a balance to a target. The difference is recorded as a manual adjustment, so history is kept. Unlimited leave types have no balance.

Award rules. Get a worker's leave award rules returns what's in effect for the worker today: their tenure tier of the policy, with any changes for them applied. Update a worker's leave award rules changes these for one worker without touching the policy. It works as a replacement, so send every leave type, even unchanged ones. The values you send are the worker's values at their current tenure tier. A limit is required if the policy uses it and rejected if it doesn't, and a value can't be lower than the amount the policy adds for the worker's tenure.

Leave types

Leave types are identified by name

Leave types don't have an ID. A leave type is identified by its leaveTypeName, which you use in the path to delete it. Names are matched ignoring case, so "jury duty" and "Jury Duty" are the same leave type. Remember to URL-encode names with spaces.

When you create a leave type, its name is tidied up first: leading and trailing spaces are removed, and any run of spaces is collapsed into one. After that it must be from 3 to 100 characters. When you pass state, the " (XX)" suffix is added to the name and counts toward the limit, so the name you send can be at most 95 characters.

System default types

Everee provides some leave types to every company. They're returned by the list endpoint with systemDefault set to true. You can't create a leave type with the same name as a system default type, and you can't delete one.

State-specific leave types

Some states require sick leave that accrues only on wages earned in that state. To create one, pass state with a two-letter state code. The type is named after the base name and the state: creating "Sick" with state WI gives a leave type named "Sick (WI)", which you use in the path to delete it. Its pay code is built the same way, with the state added: TIME_OFF_TYPE_SICK_WI.

A state-specific leave type accrues only on wages that fall in its state. A leave type created without a state applies to all states, as before. List responses include state on every leave type, null for the ones that apply to all states.

Because the state is added to the name for you:

  • Don't include the state in leaveTypeName when you pass state. "Sick (WI)" with state WI is rejected with a 400.
  • A name ending in a state code in parentheses, like "Sick (WI)", can't be used without state either.
  • Creating "Sick" with state WI when a leave type named "Sick (WI)" already exists returns a 409.

State-specific leave types aren't available to every company yet. Passing state for a company without access returns a 400.

Pay codes

Creating a leave type also creates a pay code for it, so the response always includes a payCode. This is the pay code's apiKey, which is built from the name: TIME_OFF_TYPE_ followed by the name's letters and digits in upper case. "Jury Duty" gets TIME_OFF_TYPE_JURYDUTY. This is the same payCode a policy shows for the leave type, and you can use it to pay leave hours of this type.

Because the pay code is built from the name, two different names can produce the same pay code, like "Jury Duty" and "Jury-Duty". The second is rejected with a 409, as is a name whose pay code label matches an existing pay code.

payCode can be null on a system default type if the company doesn't have a pay code set up for it yet.

Pay stubs

alwaysVisibleOnPaystub controls whether the leave type appears on pay stubs when the worker has no leave hours of that type on the stub. It's required when you create a leave type.

Deleting and archiving

DELETE removes a leave type if it's safe to, and archives it otherwise. It returns 204 in both cases. Archiving keeps the history of a leave type that's been used.

A leave type is archived instead of deleted if any of these use it:

  • a leave policy
  • a worker's leave request
  • a leave balance transaction
  • earnings paid under its pay code

Archived leave types are left out of the list. An archived type's name can be used again: if you create a leave type with the name of one you archived, it reuses the archived type's pay code.

Deleting a leave type that's already archived, or one that doesn't exist, returns 404. Deleting a system default type returns 403.

Typical workflow

To set up leave for a company from scratch:

  1. List leave types to see what exists, including the system defaults.
  2. Create a leave type for any category that's missing, like "Jury Duty".
  3. Create a leave policy that accrues those types. Keep the policy's id.
  4. List workers with no policy, then enroll them. You can also pass the id as timeOffPolicyId when you create employee profiles.
  5. Read balances with Get a worker's leave balances, or load starting balances with Set a worker's leave balance.

Errors

StatusCause
400An enroll or unenroll request names a worker or enrollment that can't be used, state was passed for a company without state-specific leave types, or leaveTypeName ends in a state code like "(WI)"
403You tried to delete a system default leave type
404The policy, enrollment, worker or leave type wasn't found. For worker leave endpoints, it also means the worker has no active enrollment
409A name is already in use, a pay code clashes with an existing one, or you tried to remove a policy that has active enrollments
422The request failed validation: for example a blank or too-long name, a leave type that doesn't exist, award rules that break the tier rules, or a worker's award rules that don't list every leave type