Create a Pay Rule
A pay rule is a set of instructions on when and how an employee will get paid.
For example, Overtime will trigger after 40 hours of work and pay 1.5x the employees regular rate.
This instructs how to bulk create pay rules.
URL and Payload
URL
curl --location --request POST 'https://{install}.{geo}.deputy.com/api/management/v2/compliance/contract'Sample - Period Overtime
{
"contractId": 478,
"payRules": [
{
"title": "Period Overtime",
"value": 0,
"remunerationBy": "REMUNERATION_BY_BASE",
"remunerationType": "REMUNERATION_TYPE_HOURLY",
"isExported": true,
"payrollCategory": "Period Overtime",
"payPortionRule": "PAY_PORTION_RULE_EXACT",
"rateType": "RATE_TYPE_OVERTIME",
"comment": "",
"operationalUnitIds": [],
"calculationRuleId": "CR_2o8zodUwPV3ersSk2zilRq3r",
"calculationTypeId": "2QUX932Ur7RBvNUsPQwH2TkBnps",
"filter": {
"customFieldAnswers": [],
"recurrenceRule": "DTSTART:20220101T000000Z\nDTEND:20220102T000000Z\nRRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR,SA,SU",
"shiftSchedulingType": "UNSPECIFIED",
"shiftStartTimeRange": "",
"shiftEndTimeRange": "",
"rRulePublicHolidayInclusion": "PH_INCLUSION_UNSPECIFIED",
"particularDate": "",
"applyOncePerDay": false,
"areaNames": []
},
"localContext": "{\"payFrom\":\"0\",\"resetClause\":\"PER_DAY\",\"overtimePeriodRule\":null,\"periodOvertimeThreshold\":null,\"dailyOrdinaryMaxThresholdSeconds\":\"0\"}",
"rateTag": "",
"payConfig": {
"roundUpHours": false
},
"levelIds": [],
"levelAssnType": 1
}
]
}Sample - Generic
{
"contractId": "<integer>",
"payRules": [
{
"id": "<long>",
"title": "<string>",
"value": "<double>",
"remunerationBy": "REMUNERATION_BY_UNKNOWN",
"remunerationType": "REMUNERATION_TYPE_UNKNOWN",
"isExported": "<boolean>",
"payrollCategory": "<string>",
"payPortionRule": "PAY_PORTION_RULE_UNKNOWN",
"rateType": "RATE_TYPE_UNKNOWN",
"comment": "<string>",
"operationalUnitIds": [
"<long>",
"<long>"
],
"calculationRuleId": "<string>",
"calculationTypeId": "<string>",
"filter": {
"customFieldAnswers": [
{
"identifier": "<string>",
"system": "UNSPECIFIED",
"configs": [
{
"operation": "<string>",
"values": [
"<string>",
"<string>"
]
},
{
"operation": "<string>",
"values": [
"<string>",
"<string>"
]
}
],
"type": "TYPE_UNSPECIFIED"
},
{
"identifier": "<string>",
"system": "UNSPECIFIED",
"configs": [
{
"operation": "<string>",
"values": [
"<string>",
"<string>"
]
},
{
"operation": "<string>",
"values": [
"<string>",
"<string>"
]
}
],
"type": "TYPE_UNSPECIFIED"
}
],
"recurrenceRule": "<string>",
"shiftSchedulingType": "UNSPECIFIED",
"shiftStartTimeRange": "<string>",
"shiftEndTimeRange": "<string>",
"rRulePublicHolidayInclusion": "PH_INCLUSION_UNSPECIFIED",
"particularDate": "<string>",
"applyOncePerDay": "<boolean>",
"areaNames": [
"<string>",
"<string>"
]
},
"localContext": "<string>",
"rateTag": "<string>",
"payConfig": {
"roundUpHours": "<boolean>"
},
"levelIds": [
"<long>",
"<long>"
],
"levelAssnType": "<long>"
},
{
"id": "<long>",
"title": "<string>",
"value": "<double>",
"remunerationBy": "REMUNERATION_BY_UNKNOWN",
"remunerationType": "REMUNERATION_TYPE_UNKNOWN",
"isExported": "<boolean>",
"payrollCategory": "<string>",
"payPortionRule": "PAY_PORTION_RULE_UNKNOWN",
"rateType": "RATE_TYPE_UNKNOWN",
"comment": "<string>",
"operationalUnitIds": [
"<long>",
"<long>"
],
"calculationRuleId": "<string>",
"calculationTypeId": "<string>",
"filter": {
"customFieldAnswers": [
{
"identifier": "<string>",
"system": "UNSPECIFIED",
"configs": [
{
"operation": "<string>",
"values": [
"<string>",
"<string>"
]
},
{
"operation": "<string>",
"values": [
"<string>",
"<string>"
]
}
],
"type": "TYPE_UNSPECIFIED"
},
{
"identifier": "<string>",
"system": "UNSPECIFIED",
"configs": [
{
"operation": "<string>",
"values": [
"<string>",
"<string>"
]
},
{
"operation": "<string>",
"values": [
"<string>",
"<string>"
]
}
],
"type": "TYPE_UNSPECIFIED"
}
],
"recurrenceRule": "<string>",
"shiftSchedulingType": "UNSPECIFIED",
"shiftStartTimeRange": "<string>",
"shiftEndTimeRange": "<string>",
"rRulePublicHolidayInclusion": "PH_INCLUSION_UNSPECIFIED",
"particularDate": "<string>",
"applyOncePerDay": "<boolean>",
"areaNames": [
"<string>",
"<string>"
]
},
"localContext": "<string>",
"rateTag": "<string>",
"payConfig": {
"roundUpHours": "<boolean>"
},
"levelIds": [
"<long>",
"<long>"
],
"levelAssnType": "<long>"
}
]
}
Response
{
"success": "<boolean>",
"error": "<string>"
}Data Elements
| Data Element | Mandatory | Info |
|---|---|---|
| contract_id | Yes | Pay Rate to assign the pay rule to |
Data Elements - Pay Rules
| Data Element | Mandatory | Info |
|---|---|---|
| id | No | Pay Rule unique identifier |
| title | Yes | Name of the Pay Rule |
| Value | Yes | Value of payment (Eg. 1.5 for multiplier, or 20 for $20) |
| remunerationBy | Yes | REMUNERATION_BY_BASE = Base Payment REMUNERATION_BY_SHIFT_LOADING= Shift Loading |
| remunerationType | Yes | REMUNERATION_TYPE_HOURLY REMUNERATION_TYPE_MULTIPLIER REMUNERATION_TYPE_UNIT |
| isExported | Yes | Should this be exportable to payroll |
| payrollCategory | Yes | Payroll Export Code |
| payPortionRule | Yes | This determines whether this pay rule should override other rules that may have been applied in the shift. "PAY_PORTION_RULE_EXACT", "PAY_PORTION_RULE_FULL" |
| rateType | No | "RATE_TYPE_UNKNOWN", "RATE_TYPE_ORDINARY", "RATE_TYPE_OVERTIME", "RATE_TYPE_PENALTY", "RATE_TYPE_NON_PAYABLE" |
| rateTag | No | Custom for reporting |
| comment | No | Not used |
| operationalUnitIds | No | Areas to assign to the pay rule. Will only trigger in these areas |
| calculationRuleId | Yes | Unique KSUID identifier for the rule |
| calculationTypeId | Yes | Identifier for the calculation type. See below |
| roundUpHours | Yes | round to nearest integer. Loadings only. |
Data Elements - Pay Rule Filters
| Data Element | Mandatory | Info |
|---|---|---|
| recurrenceRule | Yes | Eg. "DTSTART:20220101T000000Z\nDTEND:20220102T000000Z\nRRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR,SA,SU", Sets the Days and Time filter |
| shiftStartTimeRange | Yes | Time Employee must clock in by |
| shiftEndTimeRange | Yes | Time must clock out by |
| rRulePublicHolidayInclusion | Yes | "PH_INCLUSION_UNSPECIFIED", "PH_ONLY", "NON_PH_ONLY |
| particularDate | Yes | If only applies on a specific date |
| applyOncePerDay | Yes | Should this loading only appear once per day |
| areaNames | Yes | Only appears. when timesheet area matches this name |
| shiftSchedulingType | Yes | "UNSPECIFIED", (both) "SCHEDULED_ONLY", "UNSCHEDULED_ONLY" |
Custom Field Answers
| Data Element | Mandatory | Info |
|---|---|---|
| identifier | No | api name of custom field |
| system | Yes | Type of custom field TIMESHEET", "EMPLOYEE", "ROSTER" |
| operation | eq | |
| values | Permitted values to match | |
| type | Type of custom field |
Custom Field Sample:###
"filter": {
"customFieldAnswers": [
{
"identifier": "mealbreaks",
"system": "TIMESHEET",
"configs": [
{
"operation": "eq",
"values": [
"true"
]
}
],
"type": "TYPE_BOOL_NO_COMMENT"
}Calculation Types and Local Context
Local Context is dependent on the type of pay rule being configured (eg. Daily Overtime, Period Overtime, Shift Loading). These are the individual parameters unique to this that makes it configurable.
To find out the parameters for local and shared context per calculation type, use the following call:
URL
curl --location --request GET 'https://{install}.{geo}.deputy.com/api/management/v2/compliance/calculation-types?includeGlobal=true&country=US'Response
{
"success": true,
"data": [
{
"id": "2QUX94TMEN3fRELiypnfM1eRsbw",
"title": "Ordinary Rate",
"country": "global",
"description": "Pays for regular time worked",
"category": "ORDINARY",
"localContextList": [],
"supportedRuleTypes": [
"BASE"
],
"systemContextList": [],
"sharedContextList": []
},
{
"id": "2PfZHcTYFb93Q5LGvF4u9Zwy86o",
"title": "Daily Overtime",
"country": "global",
"description": "Pays based on the number of hours worked in a day",
"category": "OVERTIME",
"localContextList": [
"RuleThresholdSeconds",
"ResetClause",
"IncludeTimeOnlyWithinFilter"
],
"supportedRuleTypes": [
"BASE"
],
"systemContextList": [
"MidnightSplit",
"DailyOrdinaryTimeTotalSeconds",
"OvertimeTotalSecondsForDay"
],
"sharedContextList": []
},
{
"id": "2eEZHcBU5Ku3Q5LGTA0u9Zwy8d1",
"title": "Daily Overtime Allowance",
"country": "global",
"description": "Pays an additional allowance on top of the regular rate after a number of hours worked in a day",
"category": "OVERTIME",
"localContextList": [
"RuleThresholdSeconds",
"ResetClause",
"IncludeTimeOnlyWithinFilter"
],
"supportedRuleTypes": [
"SHIFT_LOADING"
],
"systemContextList": [
"MidnightSplit",
"DailyOrdinaryTimeTotalSeconds",
"OvertimeTotalSecondsForDay"
],
"sharedContextList": []
},
{
"id": "2Ia2MOPCu0n5V7hTpXoTQHH3l1o",
"title": "Outside Scheduled Hours",
"country": "global",
"description": "Pays if time is worked before or after a scheduled shift",
"category": "OVERTIME",
"localContextList": [
"RuleThresholdSeconds",
"OutsideScheduleType"
],
"supportedRuleTypes": [
"BASE",
"SHIFT_LOADING"
],
"systemContextList": [
"ScheduledRoster"
],
"sharedContextList": []
},
{
"id": "2QUX932Ur7RBvNUsPQwH2TkBnps",
"title": "Period Overtime",
"country": "global",
"description": "Pays based on the number of hours worked in a period",
"category": "OVERTIME",
"localContextList": [
"OvertimePeriodRule",
"PeriodOvertimeThreshold",
"PayFrom",
"DailyOrdinaryMaxThresholdSeconds",
"ResetClause"
],
"supportedRuleTypes": [
"BASE"
],
"systemContextList": [
"MidnightSplit",
"WorkPeriodEndTime",
"PeriodOvertimeThreshold",
"PeriodOrdinaryTimeTotalSeconds",
"DailyOrdinaryTimeTotalSeconds",
"OvertimeTotalSecondsForDay",
"UseRollingPeriod",
"RollingPeriodWorkedTimeTotalSeconds",
"RollingPeriodStartTime",
"RollingPeriodEndTime"
],
"sharedContextList": [
"OvertimePeriodRule",
"PeriodOvertimeThreshold",
"UseRollingPeriod",
"RollingPeriodLengthSeconds"
]
},
{
"id": "2QWmCa6iRwK3cIvLNullQeYAH1y",
"title": "Consecutive Days Worked",
"country": "global",
"description": "Pays if a shift is worked for consecutive days in a period",
"category": "PENALTY",
"localContextList": [
"RuleThresholdSeconds",
"ConsecutiveDaysWorkedThreshold"
],
"supportedRuleTypes": [
"BASE"
],
"systemContextList": [
"ConsecutiveDaysWorked",
"DailyOrdinaryTimeTotalSeconds"
],
"sharedContextList": [
"ResetConsecutiveDaysEveryWorkWeek"
]
},
{
"id": "2kIPz67md81ifCzywm7BPoZebkq",
"title": "Delayed Break",
"country": "global",
"description": "Used to pay when an employee was not able to take a break by a given point in their shift",
"category": "PENALTY",
"localContextList": [
"RuleThresholdSeconds",
"BreakType",
"BreakLengthSeconds"
],
"supportedRuleTypes": [
"BASE",
"SHIFT_LOADING"
],
"systemContextList": [],
"sharedContextList": []
},
{
"id": "2keiy7SQqJ2Xevg7VVlQuk9JHhN",
"title": "Minimum Gap After Overtime",
"country": "global",
"description": "Pay a premium if an employee has worked overtime on their previous shift and has not had a long enough gap between shifts",
"category": "PENALTY",
"localContextList": [
"RuleThresholdSeconds",
"MinShiftGapThresholdSeconds",
"PreviousShiftDayCorrelation"
],
"supportedRuleTypes": [
"BASE"
],
"systemContextList": [
"PreviousShift",
"MidnightSplit",
"IsPreviousShiftInOvertime"
],
"sharedContextList": []
},
{
"id": "2ZnN8HKQwM8Dxavb653Xt1MM7AK",
"title": "Minimum Shift Engagement",
"country": "global",
"description": "Pays to top up pay to a minimum amount of hours",
"category": "PENALTY",
"localContextList": [
"RuleThresholdSeconds"
],
"supportedRuleTypes": [
"SHIFT_LOADING"
],
"systemContextList": [
"CombineConsecutiveShifts",
"ConsecutiveShiftsTotalSeconds",
"IsLastConsecutiveShift"
],
"sharedContextList": [
"CombineConsecutiveShifts",
"GapBetweenConsecutiveShiftsThresholdSeconds"
]
},
{
"id": "2IkOp0505Hu5J843pXoTm0Vlp5f",
"title": "Non Automated Allowance",
"country": "global",
"description": "Never automatically calculated. Can be used for manual overrides on timesheet approval.",
"category": "PENALTY",
"localContextList": [],
"supportedRuleTypes": [
"SHIFT_LOADING"
],
"systemContextList": [],
"sharedContextList": []
},
{
"id": "2a2NqV7hTJOoPQryocCho15ReaL",
"title": "Pay Alongside",
"country": "global",
"description": "Pays based on other pay rules calculated on a timesheet",
"category": "PENALTY",
"localContextList": [
"CrIds"
],
"supportedRuleTypes": [
"SHIFT_LOADING"
],
"systemContextList": [],
"sharedContextList": []
},
{
"id": "2QUX94DDhQyXxlA6oVvPpk1r5gN",
"title": "Public Holiday",
"country": "global",
"description": "Pays for time worked on a public holiday",
"category": "PENALTY",
"localContextList": [
"PayPortionRule"
],
"supportedRuleTypes": [
"BASE"
],
"systemContextList": [
"IsShiftOnPublicHoliday"
],
"sharedContextList": []
},
{
"id": "2TmsUJ5r9v11j05UBjqS2bDwGPC",
"title": "Reporting Time",
"country": "global",
"description": "Pays a premium to workers who are scheduled but are sent home early",
"category": "PENALTY",
"localContextList": [
"RuleThresholdSeconds"
],
"supportedRuleTypes": [
"SHIFT_LOADING"
],
"systemContextList": [
"ScheduledRoster"
],
"sharedContextList": []
},
{
"id": "2QWUhkErASppHCWTmKtUe5a2qDz",
"title": "Rest Between Shifts",
"country": "global",
"description": "Pays if there is insufficient rest between two shifts on separate workdays",
"category": "PENALTY",
"localContextList": [
"PayPortionRule",
"RestBetweenShiftsThresholdSeconds",
"AllowShiftsOnTheSameDay",
"PreviousShiftDayCorrelation"
],
"supportedRuleTypes": [
"BASE",
"SHIFT_LOADING"
],
"systemContextList": [
"PreviousShift",
"MidnightSplit"
],
"sharedContextList": []
},
{
"id": "2I324oi05Hu5vtvTpXoTm0Vby4e",
"title": "Shift Allowance",
"country": "global",
"description": "Pays a single unit per shift. Used for allowances, shift differentials and premiums",
"category": "PENALTY",
"localContextList": [],
"supportedRuleTypes": [
"SHIFT_LOADING"
],
"systemContextList": [],
"sharedContextList": []
},
{
"id": "2Ia21oiCu0n5vtvTpXoTQHHby3d",
"title": "Shift Loading",
"country": "global",
"description": "Pays for all hours worked. Used as a template for shift differentials and premiums",
"category": "PENALTY",
"localContextList": [
"ReturnTimeType"
],
"supportedRuleTypes": [
"BASE",
"SHIFT_LOADING"
],
"systemContextList": [],
"sharedContextList": []
},
{
"id": "2RDHQOxdqqbnmDX7mLxKoPburYi",
"title": "Split Shift",
"country": "global",
"description": "Pays if the workday is split into two or mo",
"category": "PENALTY",
"localContextList": [
"UseProrataCalculation",
"MinShiftGapThresholdSeconds",
"MaxShiftGapThresholdSeconds",
"ShiftLengthThresholdSeconds"
],
"supportedRuleTypes": [
"SHIFT_LOADING"
],
"systemContextList": [
"PreviousShift"
],
"sharedContextList": []
},
{
"id": "2Pcwlzzfey5p7XqGF4keQxVWXG3",
"title": "Spread of Hours",
"country": "global",
"description": "Pays based on the time between the start of the first shift and end of the last shift in a workday",
"category": "PENALTY",
"localContextList": [
"RuleThresholdSeconds"
],
"supportedRuleTypes": [
"SHIFT_LOADING"
],
"systemContextList": [
"FirstShiftForDay",
"IsLastShiftForDay"
],
"sharedContextList": []
},
{
"id": "2keNgCu0nG2Xevg21Vl04k9JH96",
"title": "Timesheet Field Payment",
"country": "global",
"description": "This calculation type will return the number of hours/units specified in the relevant numerical timesheet custom field.",
"category": "PENALTY",
"localContextList": [
"TimesheetNumericField"
],
"supportedRuleTypes": [
"SHIFT_LOADING"
],
"systemContextList": [],
"sharedContextList": []
}
]
}Next Steps
TO DO: Level Management once released.
More deets on local context.
Note that some will fail if shared settings are not configured in employment contract config.
Updated 11 months ago