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:

📘

Related

Overtime 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:

ConditionHow 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 silent

A 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 run

A worker whose contract was created with overtimeEligible: false is 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:

EntryCarriesCounts toward hours worked
pay entry on an hourly pay type (rate × hours)Money and hoursYes, 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 entryHours onlyYes, always.
pay entry with a fixed amount (salary, commission, bonus, tips)Money onlyNo. Send a timeWorked entry alongside it if the worker's hours should count.
pay entry with items (piece rate)Money and unitsNo. 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 hoursNo. 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

For shift entries you may send hours explicitly or let Salsa derive it from the span between startDateTime and endDateTime.

  • Pay is calculated from the hours you send, or from the span when you omit hours.
  • 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

  1. If the worker's pay group has a work week, that is used.
  2. Otherwise the employer's default work week is used, if one exists.
  3. 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 run

All 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_MISMATCH and 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.

StepAmount
Eligible earnings75 + 160 + 75 + 100 = $410
Hours worked16
Regular rate of pay410 ÷ 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).

StepAmount
Regular rate of pay3,000 ÷ 50 = $60.00
Daily overtime (4 hours over 8 on four days)16 h × $60 × 0.5 = $480.00
Weekly overtime50 − 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.

StepAmount
Hours worked10 + 13 + 10 + 10 = 43
Regular rate of pay774 ÷ 43 = $18.00
Daily overtime (Tuesday hour 13)1 h × $18 × 0.5 = $9.00
Weekly overtime43 − 40 = 3 h, minus 1 h already counted daily = 2 h × $18 × 0.5 = $18.00
Gross774 + 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

JurisdictionDailySeventh consecutive dayWeekly
CaliforniaHours 8–12 at 1.5×; over 12 at 2×First 8 hours at 1.5×; over 8 at 2×Over 40 at 1.5×
ColoradoOver 12 at 1.5× (shifts less than an hour apart count as one workday)—Over 40 at 1.5×
Alaska, NevadaOver 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×
OregonNone 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 IslandNone 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 territoriesNot supported, no overtime is calculated

Canada

Province or territoryDailyWeeklyNotes
AlbertaOver 8 at 1.5×Over 44 at 1.5×
British ColumbiaHours 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, YukonOver 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×
QuebecNot 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>. Overlapping timeWorked entries are always rejected with Overlapping 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

Every 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: false on 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 pay entries against the corresponding pay types. Do not send your own overtime lines while automatic overtime is enabled.

Paystream validation errors related to hours

MessageCause
Invalid date interval: expects either 'startDate' and 'endDate' or 'startDateTime' and 'endDateTime' to be setMixed 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 endDateTimeOverlap-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.


Did this page help you?