Set up and pay Overtime
How Salsa decides who gets overtime, which hours count, how the rate is calculated, and how to read the result
Overtime is the premium an employer owes a non-exempt employee for hours worked beyond a legal threshold. In the United States the federal baseline is 1.5 times the regular rate of pay for hours over 40 in a workweek; some states add daily and double-time rules. Salsa calculates overtime automatically during every payroll run when the conditions on this page are met.
This page covers:
- Who gets overtime
- Which hours count
- Work weeks
- How the overtime rate and amount are calculated
- Jurisdiction rules
- Overlapping shifts
- Reading the result
- Opting out
RelatedOvertime is calculated from the daily hours you send through Paystream Payroll Elements. Split shift, spread of hours and wage parity are separate calculations described in Premium Pay.
Who gets overtime
Salsa calculates overtime for eligible workers. A worker is eligible in a payroll run when all of the following are true:
| Condition | How to check or set it |
|---|---|
| The worker's default work location is in a supported state or province (see Jurisdiction rules). | Worker work locations. |
The worker's classification is EMPLOYEE. Contractors never receive overtime. | Worker contract classification. |
The worker's contract has overtimeEligible: true. | Worker contract overtimeEligible. Until this is set the worker's capabilities report WorkerPaymentsReadinessMissingContractOvertimeEligibilityRequirement. |
The worker has daily hours in the period: hourly pay entries, timeWorked entries, or both (see Which hours count). | Paystream payload. |
| Automatic overtime is enabled for your partner account and the Overtime and Double overtime pay types exist. | Set up by Salsa during onboarding. See Opting out. |
Missing overtime is silentA worker who does not meet every condition is paid without overtime and no error or alert is raised. When overtime looks missing, check this list first.
Set overtime eligibility before the first payroll runA worker whose contract was created with
overtimeEligible: falseis never evaluated for overtime, and nothing on the payroll run flags it. If an employer then types overtime hours in by hand, Salsa stops calculating overtime for that worker in that run and the manual figure is used as-is. The fix is to correct the contract and recalculate, not to enter hours manually.
curl --location 'https://api.sandbox.salsa.dev/api/rest/v1/employers/${employerId}/workers/${workerId}/contracts' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer ${YOUR_API_TOKEN}' \
--data '{
"classification": "EMPLOYEE",
"overtimeEligible": true
}'Which hours count
Salsa builds a per-day record of hours worked for each worker and evaluates the overtime thresholds against it. Two kinds of Paystream entries feed it:
| Entry | Carries | Counts toward hours worked |
|---|---|---|
pay entry on an hourly pay type (rate × hours) | Money and hours | Yes, when the partner pay type has isIncludedInTimeWorked enabled. Hourly pay types are set up this way by default; pay types such as a daily flat rate or live-in rate can be configured not to count. |
timeWorked entry | Hours only | Yes, always. |
pay entry with a fixed amount (salary, commission, bonus, tips) | Money only | No. Send a timeWorked entry alongside it if the worker's hours should count. |
pay entry with items (piece rate) | Money and units | No. The amount counts toward the regular rate of pay, but the number of items does not tell Salsa how long the worker spent. Send a timeWorked entry for the hours. |
| Time off (vacation, sick, holiday) | Paid hours | No. Time off hours are paid but do not count toward overtime thresholds. |
curl --location --request POST 'https://api.sandbox.salsa.dev/api/rest/v1/paystream/payroll-elements' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer ${YOUR_API_TOKEN}' \
--data-raw '{
"data": {
"type": "PaystreamPayrollElementPeriodReplacementInput",
"employerId": "${YOUR_EMPLOYER_ID}",
"periodStartDate": "2026-07-01",
"periodEndDate": "2026-07-07",
"workers": [
{
"workerId": "${YOUR_WORKER_ID}",
"pay": [
{ "payReferenceId": "${YOUR_HOURLY_REFERENCE_ID}", "rate": "20.00", "hours": 10, "startDate": "2026-07-01", "endDate": "2026-07-01" },
{ "payReferenceId": "${YOUR_HOURLY_REFERENCE_ID}", "rate": "20.00", "hours": 9, "startDate": "2026-07-02", "endDate": "2026-07-02" },
{ "payReferenceId": "${YOUR_HOURLY_REFERENCE_ID}", "rate": "20.00", "startDateTime": "2026-07-03T08:00:00-05:00", "endDateTime": "2026-07-03T17:00:00-05:00" }
]
}
]
}
}'Send each block of time once
Hourly pay hours and timeWorked hours are added together per day. If you send an hourly pay entry for 8 hours and a timeWorked entry for the same 8 hours, Salsa counts 16 hours for that day. Use pay for time that is paid hourly, and timeWorked only for time that is not already carried by an hourly pay entry (salaried, commission-only, or piece-rate workers).
{
"workerId": "${YOUR_WORKER_ID}",
"pay": [
{
"payReferenceId": "${YOUR_SALARY_REFERENCE_ID}",
"rate": "100000.00",
"frequency": "YEARLY",
"startDate": "2026-07-29",
"endDate": "2026-08-11"
}
],
"timeWorked": [
{ "hours": 10, "startDate": "2026-07-29", "endDate": "2026-07-29" },
{ "hours": 10, "startDate": "2026-07-30", "endDate": "2026-07-30" },
{ "hours": 9, "startDate": "2026-07-31", "endDate": "2026-07-31" }
]
}One day or shorter
Only entries that cover one calendar day or less feed the daily record. You can send a whole day (startDate and endDate equal) or a shift (startDateTime and endDateTime). An entry that spans several days is still paid, but its hours are ignored when evaluating overtime thresholds: Salsa cannot tell which day each hour belongs to, and both the daily thresholds and the work-week grouping depend on knowing that. Send hours day by day, or as shifts.
Shifts, spans and the hours field
hours fieldFor shift entries you may send hours explicitly or let Salsa derive it from the span between startDateTime and endDateTime.
- Pay is calculated from the
hoursyou send, or from the span when you omithours. - Hours worked, and therefore overtime, are calculated from the span.
If the two differ, for example a scheduled 10 hours paid against a clock-in span of 10 hours 6 minutes, the worker is paid for 10 hours and overtime is evaluated on 10.1 hours. This also moves the regular rate of pay a few cents below the hourly rate, because earnings are divided by the longer span. Send hours equal to the span, or omit hours. If the span includes unpaid time, such as a meal break, send the shift as two entries around it rather than reducing hours, because the whole span still counts as hours worked.
Shifts that cross midnight
A shift is attributed in full to the calendar day on which it starts, in the time zone of its startDateTime. A shift from 22:00 on Tuesday to 02:00 on Wednesday adds 4 hours to Tuesday. Shifts are not split at midnight.
Travel, breaks and other paid time
Salsa does not know about break rules. If a break is unpaid, send the shift as two entries around it. Paid travel time between work sites counts as hours worked under federal rules; send it as its own entry on a pay type that counts toward time worked, or as timeWorked.
Work weeks
Overtime thresholds are evaluated per work week, a fixed, recurring seven-day period. The pay period is irrelevant to the threshold: a biweekly worker with 38 hours in week one and 44 hours in week two has 4 hours of overtime, not 2.
How Salsa decides when the work week starts
- If the worker's pay group has a work week, that is used.
- Otherwise the employer's default work week is used, if one exists.
- Otherwise Salsa assumes one: for semi-monthly and monthly pay groups the week starts Monday at 00:00; for weekly and biweekly pay groups it starts on the day of the week the pay period starts, at 00:00.
The default is right for most employers. Ask Salsa to configure a work week when the employer's week does not start where the pay period starts, when semi-monthly or monthly pay groups are used, or when you run off-cycle payroll runs that should count hours already paid in a confirmed run. Work weeks can be set per employer or per pay group. They are configured by Salsa on your behalf and are not exposed in the employer dashboard.
One work week per payroll runAll workers in a payroll run share one work week definition. If pay groups in the same run have different work weeks, the run raises an error alert. Changing the work week start day between two consecutive periods raises the alert
WORKER_OVERTIME_WORK_WEEK_ALIGNMENT_MISMATCHand skips overtime for the affected workers in that run, so plan changes at a period boundary.
When a work week spans two pay periods
Semi-monthly and monthly pay periods rarely end on a work week boundary. When the last week of a period is incomplete, Salsa pays overtime on the hours it has so far. In the next payroll run it looks back at the confirmed payment, re-evaluates the full week, and adds any difference as an overtime adjustment. Overtime already paid is never clawed back. The weekly breakdown in overtimeDetails shows the adjustment under previousPeriodAdjustment.
Off-cycle payroll runs
An off-cycle run combines its hours with other confirmed runs in the same work week, including the regular run and any other off-cycle run overlapping the period, provided Salsa has configured a work week for the employer or pay group so the week boundary is known. Hours added by hand in the payroll run UI are not assigned to a day, so they never count toward overtime thresholds; send them through Paystream instead.
How the overtime rate and amount are calculated
Regular rate of pay
Salsa computes a regular rate of pay for each work week:
regular rate of pay = eligible earnings in the week ÷ hours worked in the week
Eligible earnings include hourly pay, piece-rate pay, commissions, non-discretionary bonuses, service charges and, for salaried workers, the share of salary attributable to the week. Tips, reimbursements and premium pay lines (split shift, spread of hours, wage parity) are excluded. A fixed-amount entry whose dates span two work weeks is excluded from both.
For a worker with one hourly rate and no other pay, the regular rate equals the hourly rate. With several rates in the same week it is the weighted average; Salsa does not use the rate of the shift in which overtime was triggered.
Overtime is paid as a premium
Hours that qualify as overtime are already paid at straight time on the hourly line. Salsa adds a separate line for the premium: 0.5 × regular rate for overtime, 1.0 × regular rate for double overtime. The worker's gross pay is the same as paying 1.5× or 2× on a reduced hourly line; only the presentation differs.
Pay period: 7/1/26 – 7/7/26, weekly, 45 hours at $20
Pay type Hours Rate Amount
Hourly 45 $20.00 $900.00
Overtime 5 $10.00 (0.5×) $50.00
$950.00
Salsa pays the premium rather than reducing the hourly line because the premium is always well defined. When a worker has several hourly rates in the week, or both hourly pay and timeWorked entries, there is no single hourly line whose hours could be reduced without guessing which hours were the overtime ones. The premium approach also keeps the hourly line equal to the hours you sent, and it is how the federal regular-rate rules describe overtime for workers with more than one form of pay.
Some existing integrations use an earlier presentation in which the hourly line is reduced to 40 hours and overtime is shown at 1.5×. The gross pay is identical. Contact Salsa if you want to know which presentation your account uses.
Example: several rates and a bonus in one California day
A California worker on a weekly pay group works Monday 13 hours (5 hours at $15, 8 hours at $20) and Tuesday 3 hours at $25, and earns a $100 bonus on Monday.
| Step | Amount |
|---|---|
| Eligible earnings | 75 + 160 + 75 + 100 = $410 |
| Hours worked | 16 |
| Regular rate of pay | 410 ÷ 16 = $25.63 |
| Daily overtime (Monday hours 9 to 12) | 4 h × $25.63 × 0.5 = $51.25 |
| Double overtime (Monday hour 13) | 1 h × $25.63 × 1.0 = $25.63 |
| Gross | $486.88 |
Example: commission-only worker in California
A worker earns $3,000 in commission for the week and sends timeWorked of 12, 12, 12, 12 and 2 hours (50 hours).
| Step | Amount |
|---|---|
| Regular rate of pay | 3,000 ÷ 50 = $60.00 |
| Daily overtime (4 hours over 8 on four days) | 16 h × $60 × 0.5 = $480.00 |
| Weekly overtime | 50 − 40 = 10 h, minus 16 h already counted daily = 0 |
| Gross | $3,480.00 |
Daily overtime hours are subtracted from weekly overtime hours so no hour is paid twice.
Example: split shifts in Colorado
A Colorado worker on a weekly pay group earns $18 per hour and works Monday 10 hours, Tuesday 08:00–15:00 and 15:30–21:30 as two shifts, Wednesday 10 hours and Thursday 10 hours. Colorado pays overtime over 12 hours in a workday or over 40 in the week, and treats shifts separated by less than an hour as one continuous workday, so Tuesday's two shifts count as 13 hours.
| Step | Amount |
|---|---|
| Hours worked | 10 + 13 + 10 + 10 = 43 |
| Regular rate of pay | 774 ÷ 43 = $18.00 |
| Daily overtime (Tuesday hour 13) | 1 h × $18 × 0.5 = $9.00 |
| Weekly overtime | 43 − 40 = 3 h, minus 1 h already counted daily = 2 h × $18 × 0.5 = $18.00 |
| Gross | 774 + 9 + 18 = $801.00 |
Had the two Tuesday shifts been sent as a single 13-hour entry the result would be identical; sending them as shifts lets Salsa apply the continuous-workday rule when the gap is short and keep them separate when it is not.
Jurisdiction rules
The rules applied come from the worker's default work location. Salsa does not use Symmetry or any external service for overtime thresholds; they are maintained by Salsa.
United States
| Jurisdiction | Daily | Seventh consecutive day | Weekly |
|---|---|---|---|
| California | Hours 8–12 at 1.5×; over 12 at 2× | First 8 hours at 1.5×; over 8 at 2× | Over 40 at 1.5× |
| Colorado | Over 12 at 1.5× (shifts less than an hour apart count as one workday) | — | Over 40 at 1.5× |
| Alaska, Nevada | Over 8 at 1.5× | — | Over 40 at 1.5× |
| Kentucky | — | None applied. Kentucky requires 1.5× for all hours on the seventh day worked in a week that exceeds 40 hours; Salsa does not yet apply this rule. | Over 40 at 1.5× |
| Oregon | None applied. Oregon requires 1.5× after 10 hours in a day in manufacturing establishments; Salsa does not yet apply this rule. | — | Over 40 at 1.5× |
| Rhode Island | None applied. Rhode Island requires 1.5× for hours worked on Sundays and state holidays for most employees (retail employers may count those hours toward weekly overtime); Salsa does not yet apply this rule. | — | Over 40 at 1.5× |
| All other states and the District of Columbia | — | — | Over 40 at 1.5× (federal rule) |
| US territories | Not supported, no overtime is calculated |
Canada
| Province or territory | Daily | Weekly | Notes |
|---|---|---|---|
| Alberta | Over 8 at 1.5× | Over 44 at 1.5× | |
| British Columbia | Hours 8–12 at 1.5×; over 12 at 2× | Over 40 at 1.5× | Weekly rest rule approximated: when all seven days are worked, the shortest day's hours are paid at 1.5× |
| Saskatchewan, Manitoba, Northwest Territories, Nunavut, Yukon | Over 8 at 1.5× | Over 40 at 1.5× | |
| Ontario | — | Over 44 at 1.5× | |
| New Brunswick | — | Over 44 at 1.5× | Paid at 1.5× minimum wage; not paid when the regular rate already exceeds that |
| Newfoundland and Labrador | — | Over 40 at 1.5× | Same minimum-wage rule as New Brunswick |
| Nova Scotia, Prince Edward Island | — | Over 48 at 1.5× | |
| Quebec | Not supported, no overtime is calculated |
Canadian overtime for workers paid only by the hour is allocated per rate rather than blended. Statutory holiday overtime and overtime banking are not supported.
Overlapping shifts
If your platform can produce two entries for the same worker whose times overlap, for example a caregiver attending two clients at once or a visit logged twice, the behaviour depends on the pay type's allowOverlappingEntries setting.
- Not allowed (default): the whole Paystream batch is rejected with
Overlapping pay entry intervals found with referenceId: <ref> for worker: <id>. OverlappingtimeWorkedentries are always rejected withOverlapping time worked entry intervals found for worker: <id>. - Allowed: every entry is paid for its own
hours, but the overlapping spans are merged before counting hours worked, so a worker with entries totalling 48 hours whose merged time is 42 hours has 2 hours of overtime, not 8. Merging happens per pay type; overlaps between two different pay types are not merged and would count twice.
See Set up employer pay types for how this flag is inherited and the risks of splitting one pay type into several.
Reading the result
On the earnings record
Overtime appears as separate lines named after your Overtime and Double overtime pay types, with the overtime hours, the rate used and the amount. When a cross-period reconciliation applies, an additional flat line named <Overtime pay type> Adjustment carries the difference.
overtimeDetails on the worker payment
overtimeDetails on the worker paymentEvery worker payment that includes overtime carries an overtimeDetails object, available on Get worker payment, on the worker payment record, and through GraphQL on WorkerPayrollRunResult and Payslip. It lists only the work weeks that produced overtime.
The example below is trimmed to the fields relevant to this page; see the worker payment reference for the full schema.
{
"overtimeStrategy": "PREMIUM_ONLY",
"totalHoursWorked": 83.79,
"totalOvertime": "32.62",
"weeklyOvertimeDetails": [
{
"workWeekStart": "2026-08-16",
"workWeekEnd": "2026-08-22",
"totalHoursWorked": 44.66,
"totalOvertimeHours": 4.66,
"regularRateOfPay": "14.00",
"totalOvertime": "32.62",
"typeBreakdown": [
{
"typeId": "prtnrcomppol_...",
"typeName": "Overtime",
"multiplier": 1.5,
"overtimeHours": 4.66,
"overtimeRate": "7.00",
"amount": "32.62",
"previousPeriodAdjustment": "0"
}
],
"rateAllocations": [
{ "hourlyRate": "14.00", "rate": "14.00", "overtimeHours": 4.66, "amount": "32.62" }
]
}
]
}Use regularRateOfPay and totalHoursWorked per week to answer "why is the overtime rate not my hourly rate" questions: the rate is earnings divided by hours worked for that week.
Overtime report
Overtime report returns, as JSON or CSV, every payroll run with overtime for an employer within a pay-date range, broken down by worker, payroll run and work week.
Manual overrides
If an employer edits the Overtime line of a worker in the payroll run, Salsa stops calculating overtime for that worker in that run and uses the edited value. Editing the hourly line does not stop the calculation. Manually added overtime also adds to the worker's hours worked unless the hours are overridden too, so prefer fixing the input data and recalculating.
Opting out
- For one worker: set
overtimeEligible: falseon the contract. - For your whole integration: Salsa can disable automatic overtime for your partner account. Do this if your platform calculates overtime itself. You then send Overtime and Double overtime as ordinary
payentries against the corresponding pay types. Do not send your own overtime lines while automatic overtime is enabled.
Paystream validation errors related to hours
| Message | Cause |
|---|---|
Invalid date interval: expects either 'startDate' and 'endDate' or 'startDateTime' and 'endDateTime' to be set | Mixed or missing interval fields on an entry. |
Overlapping pay entry intervals found with referenceId: <ref> for worker: <id> | Two entries on the same pay type overlap and the pay type does not allow it. |
Overlapping time worked entry intervals found for worker: <id> | Two timeWorked entries overlap. |
Pay reference id '<ref>' has allowOverlappingEntries=true and requires both startDateTime and endDateTime | Overlap-enabled pay types need shift entries. |
Period replacement items must be within the replacement period (<start> to <end>) | An entry's dates fall outside the period being replaced. |
Overtime that is skipped because of eligibility, jurisdiction or multi-day entries does not produce an error. Check Who gets overtime.
Updated 2 days ago
