Pairing employees
When assigning schedules to employees it is important to consider which employees are paired together and, just as importantly, which employees are not paired together.
There are four categories to consider:
-
Required pairings.
-
Preferred pairings.
-
Unpreferred pairings.
-
Prohibited pairings.
Required pairings are employees who must be assigned to shifts together. Reasons for required pairings include:
-
A trainer needs to train a new employee.
-
Complementary skills that are both required on a shift.
Preferred pairings represent pairings that are preferred but not absolutely necessary, in that work can still continue without the pairing. Reasons for preferred pairings include:
-
The employees live together and like to travel to work together.
-
The employees enjoy working together when possible.
-
Managers have noticed the employees are an effective team.
Unpreferred pairings represent pairings that aren’t ideal, but that can still be made when necessary. Reasons for unpreferred pairings include:
-
Managers have noticed the employees aren’t productive when working together.
-
The employees live together and have shared caring responsibilities, for instance, a couple with young children, who prefer not to work at the same time so one of them is always available to take care of the children.
-
An employee has stated a preference not to work with another employee when possible.
Prohibited pairings represent pairings that are not allowed. Reasons for prohibited pairings include:
-
Conflict of interests; some companies have policies against family members working together.
-
Legal or HR issues that prevent employees from being paired on the same shift.
This guide explains how to manage pairing employees with the following examples:
Prerequisites
To run the examples in this guide, you need to authenticate with a valid API key:
-
Log in to Timefold Platform: app.timefold.ai
-
From the Dashboard, click your username, and from the drop-down menu select API Keys.
-
Copy the default API key.
In the examples, replace <API_KEY>
with the API Key you just copied.
1. Required pairings
When two employees are required to work on the same shift, for instance, if Beth is training Ann, they must be assigned to the same shift.
Employee required pairings are defined by adding requiredPairings
to the employee.
{
"employees": [
{
"id": "Ann",
"requiredPairings": [
{
"pairedEmployee": "Beth"
}
]
},
{
"id": "Beth"
}
]
}
pairedEmployee
includes the ID of the employee to be paired.
Beth needs to train Ann, but Beth can still be assigned shifts without Ann. Ann must be trained before she can work independently. If there are more employees available than shifts that need to be covered, Ann might not be assigned a shift, however, Beth could still be assigned a shift as she can train Ann or complete her normal duties. |
In the following example, two people are scheduled for the morning shift, two more people are scheduled for the afternoon shift. Ann and Beth are required to work together.
-
Input
-
Output
Try this example in Timefold Platform by saving this JSON into a file called sample.json and make the following API call:
|
curl -X POST -H "Content-type: application/json" -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/employee-scheduling/v1/schedules [email protected]
{
"config": {
"run": {
"name": "Required pairing example"
}
},
"modelInput": {
"contracts": [
{
"id": "fullTimeContract",
"periodRules": [
{
"id": "Max8HoursPerDayFullTime",
"period": "DAY",
"minutesWorkedMax": 480
}
]
}
],
"employees": [
{
"id": "Ann",
"contracts": [
"fullTimeContract"
],
"requiredPairings": [
{
"pairedEmployee": "Beth"
}
]
},
{
"id": "Beth",
"contracts": [
"fullTimeContract"
]
},
{
"id": "Carl",
"contracts": [
"fullTimeContract"
]
},
{
"id": "Dan",
"contracts": [
"fullTimeContract"
]
}
],
"shifts": [
{
"id": "Mon morning 1",
"start": "2027-02-01T06:00:00Z",
"end": "2027-02-01T14:00:00Z"
},
{
"id": "Mon morning 2",
"start": "2027-02-01T06:00:00Z",
"end": "2027-02-01T14:00:00Z"
},
{
"id": "Mon afternoon 1",
"start": "2027-02-01T14:00:00Z",
"end": "2027-02-01T22:00:00Z"
},
{
"id": "Mon afternoon 2",
"start": "2027-02-01T14:00:00Z",
"end": "2027-02-01T22:00:00Z"
}
]
}
}
To request the solution, locate the 'ID' from the response to the post operation and append it to the following API call: |
curl -X GET -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/employee-scheduling/v1/schedules/<ID>
{
"run": {
"id": "ID",
"name": "Required pairing example",
"submitDateTime": "2024-10-16T06:58:16.183859431Z",
"startDateTime": "2024-10-16T06:58:23.392237953Z",
"completeDateTime": "2024-10-16T07:03:23.763120279Z",
"solverStatus": "SOLVING_COMPLETED",
"score": "0hard/0medium/0soft",
"tags": null,
"validationResult": {
"summary": "OK"
}
},
"modelOutput": {
"shifts": [
{
"id": "Mon morning 1",
"employee": "Beth"
},
{
"id": "Mon morning 2",
"employee": "Ann"
},
{
"id": "Mon afternoon 1",
"employee": "Carl"
},
{
"id": "Mon afternoon 2",
"employee": "Dan"
}
]
},
"kpis": {
"assignedShifts": 4,
"unassignedShifts": 0,
"workingTimeFairnessPercentage": 0.0,
"disruptionPercentage": 0.0
}
}
modelOutput
contains the employee shift schedule with both Ann and Beth assigned to the morning shift.
Required pairing rules can be filtered with tags to limit the scope of the rule. See Filtering pairings with tags for more information. |
2. Preferred pairings
When two employees prefer to work on the same shift, for instance, Beth and Carl travel to work together and prefer to be assigned shifts at the same time to simplify their travel arrangements, they can state a preference to work together.
Employee preferred pairings are defined by adding preferredPairings
to the employee.
{
"employees": [
{
"id": "Beth",
"preferredPairings": [
{
"pairedEmployee": "Carl"
}
]
},
{
"id": "Carl"
}
]
}
pairedEmployee
includes the ID of the employee to be paired.
Assigning employees together based on Learn about the hard, medium, and soft constraints in Employee Shift Scheduling. |
In the following example, Beth and Carl prefer to be assigned to the same shifts so they can travel to work together.
preferredPairings
can be one-way or mutual.
A one-way preferredPairings
is when one employee prefers to work with another employee, but the employee they prefer to work with has no corresponding preference.
A mutual preferredPairings
is when both employees state a preference to work with each other.
When mutual preferredPairings
are met, a soft constraint score is added for both employees, whereas for a one-way preference,
the soft constraint score will only be added for one employee.
Learn about the hard, medium, and soft constraints in Employee Shift Scheduling model. |
-
Input
-
Output
Try this example in Timefold Platform by saving this JSON into a file called sample.json and make the following API call:
|
curl -X POST -H "Content-type: application/json" -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/employee-scheduling/v1/schedules [email protected]
{
"config": {
"run": {
"name": "Preferred pairing example"
}
},
"modelInput": {
"contracts": [
{
"id": "fullTimeContract",
"periodRules": [
{
"id": "Max8HoursPerDayFullTime",
"period": "DAY",
"minutesWorkedMax": 480
}
]
}
],
"employees": [
{
"id": "Ann",
"contracts": [
"fullTimeContract"
]
},
{
"id": "Beth",
"contracts": [
"fullTimeContract"
],
"preferredPairings": [
{
"pairedEmployee": "Carl"
}
]
},
{
"id": "Carl",
"contracts": [
"fullTimeContract"
],
"preferredPairings": [
{
"pairedEmployee": "Beth"
}
]
},
{
"id": "Dan",
"contracts": [
"fullTimeContract"
]
}
],
"shifts": [
{
"id": "Mon morning 1",
"start": "2027-02-01T06:00:00Z",
"end": "2027-02-01T14:00:00Z"
},
{
"id": "Mon morning 2",
"start": "2027-02-01T06:00:00Z",
"end": "2027-02-01T14:00:00Z"
},
{
"id": "Mon afternoon 1",
"start": "2027-02-01T14:00:00Z",
"end": "2027-02-01T22:00:00Z"
},
{
"id": "Mon afternoon 2",
"start": "2027-02-01T14:00:00Z",
"end": "2027-02-01T22:00:00Z"
}
]
}
}
To request the solution, locate the 'ID' from the response to the post operation and append it to the following API call: |
curl -X GET -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/employee-scheduling/v1/schedules/<ID>
{
"run": {
"id": "ID",
"name": "Preferred pairing example",
"submitDateTime": "2024-10-18T06:07:25.018181969Z",
"startDateTime": "2024-10-18T06:07:29.339183825Z",
"completeDateTime": "2024-10-18T06:12:29.527910197Z",
"solverStatus": "SOLVING_COMPLETED",
"score": "0hard/0medium/1920soft",
"tags": null,
"validationResult": {
"summary": "OK"
}
},
"modelOutput": {
"shifts": [
{
"id": "Mon morning 1",
"employee": "Carl"
},
{
"id": "Mon morning 2",
"employee": "Beth"
},
{
"id": "Mon afternoon 1",
"employee": "Ann"
},
{
"id": "Mon afternoon 2",
"employee": "Dan"
}
]
},
"kpis": {
"assignedShifts": 4,
"unassignedShifts": 0,
"workingTimeFairnessPercentage": 0.0,
"disruptionPercentage": 0.0
}
}
modelOutput
contains the employee shift schedule with Beth and Carl assigned to shifts at the same time.
Preferred pairing rules can be filtered with tags to limit the scope of the rule. See Filtering pairings with tags for more information. |
3. Unpreferred pairings
When two employees prefer not to be scheduled on the same shift, for instance, Carl and Dan are brothers and have shared caring responsibilities for an elderly relative, they can state a preference work at different times so one of them is always available.
Employee unpreferred pairings are defined by adding unpreferredPairings
to the employee.
{
"employees": [
{
"id": "Carl",
"unpreferredPairings": [
{
"pairedEmployee": "Dan"
}
]
},
{
"id": "Dan"
}
]
}
unpairedEmployee
includes the ID of the employee to be paired.
Learn about the hard, medium, and soft constraints in Employee Shift Scheduling model. |
In the following example, Carl and Dan prefer to be assigned to shifts at different times so that one of them is always available to care for an elderly relative.
UnpreferredPairings
can be one-way or mutual.
A one-way UnpreferredPairings
is when one employee prefers not to work with another employee, but the employee they prefer not to work with has no corresponding UnpreferredPairings
.
A mutual UnpreferredPairings
is when both employees state a preference not to work with each other.
When mutual UnpreferredPairings
are met, a soft constraint score is added for both employees, whereas for a one-way preference,
the soft constraint score will only be added for one employee.
-
Input
-
Output
Try this example in Timefold Platform by saving this JSON into a file called sample.json and make the following API call:
|
curl -X POST -H "Content-type: application/json" -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/employee-scheduling/v1/schedules [email protected]
{
"config": {
"run": {
"name": "Unpreferred pairing example"
}
},
"modelInput": {
"contracts": [
{
"id": "fullTimeContract",
"periodRules": [
{
"id": "Max8HoursPerDayFullTime",
"period": "DAY",
"minutesWorkedMax": 480
}
]
}
],
"employees": [
{
"id": "Ann",
"contracts": [
"fullTimeContract"
]
},
{
"id": "Beth",
"contracts": [
"fullTimeContract"
]
},
{
"id": "Carl",
"contracts": [
"fullTimeContract"
],
"unpreferredPairings": [
{
"pairedEmployee": "Dan"
}
]
},
{
"id": "Dan",
"contracts": [
"fullTimeContract"
],
"unpreferredPairings": [
{
"pairedEmployee": "Carl"
}
]
}
],
"shifts": [
{
"id": "Mon morning 1",
"start": "2027-02-01T06:00:00Z",
"end": "2027-02-01T14:00:00Z"
},
{
"id": "Mon morning 2",
"start": "2027-02-01T06:00:00Z",
"end": "2027-02-01T14:00:00Z"
},
{
"id": "Mon afternoon 1",
"start": "2027-02-01T14:00:00Z",
"end": "2027-02-01T22:00:00Z"
},
{
"id": "Mon afternoon 2",
"start": "2027-02-01T14:00:00Z",
"end": "2027-02-01T22:00:00Z"
}
]
}
}
To request the solution, locate the 'ID' from the response to the post operation and append it to the following API call: |
curl -X GET -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/employee-scheduling/v1/schedules/<ID>
{
"run": {
"id": "ID",
"name": "Unpreferred pairing example",
"submitDateTime": "2024-10-18T06:21:12.479700439Z",
"startDateTime": "2024-10-18T06:21:17.363156368Z",
"completeDateTime": "2024-10-18T06:26:17.592881051Z",
"solverStatus": "SOLVING_COMPLETED",
"score": "0hard/0medium/0soft",
"tags": null,
"validationResult": {
"summary": "OK"
}
},
"modelOutput": {
"shifts": [
{
"id": "Mon morning 1",
"employee": "Carl"
},
{
"id": "Mon morning 2",
"employee": "Beth"
},
{
"id": "Mon afternoon 1",
"employee": "Ann"
},
{
"id": "Mon afternoon 2",
"employee": "Dan"
}
]
},
"kpis": {
"assignedShifts": 4,
"unassignedShifts": 0,
"workingTimeFairnessPercentage": 0.0,
"disruptionPercentage": 0.0
}
}
modelOutput
contains the employee shift schedule with Carl and Dan assigned to different shifts.
Unpreferred pairing rules can be filtered with tags to limit the scope of the rule. See Filtering pairings with tags for more information. |
4. Prohibited pairings
When two employees must not work on the same shift, for instance, if Beth and Dan are related and the company has a conflict of interests policy against family members working together, they can be prohibited from being paired.
Employee prohibited pairings are defined by adding prohibitedPairings
to the employee.
{
"employees": [
{
"id": "Ann",
"prohibitedPairings": [
{
"pairedEmployee": "Beth"
}
]
},
{
"id": "Beth"
}
]
}
pairedEmployee
includes the ID of the employee to be paired.
In the following example, Dan and Beth are related and must be assigned to different shifts.
-
Input
-
Output
Try this example in Timefold Platform by saving this JSON into a file called sample.json and make the following API call:
|
curl -X POST -H "Content-type: application/json" -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/employee-scheduling/v1/schedules [email protected]
{
"config": {
"run": {
"name": "Prohibited pairing example"
}
},
"modelInput": {
"contracts": [
{
"id": "fullTimeContract",
"periodRules": [
{
"id": "Max8HoursPerDayFullTime",
"period": "DAY",
"minutesWorkedMax": 480
}
]
}
],
"employees": [
{
"id": "Ann",
"contracts": [
"fullTimeContract"
]
},
{
"id": "Beth",
"contracts": [
"fullTimeContract"
]
},
{
"id": "Carl",
"contracts": [
"fullTimeContract"
]
},
{
"id": "Dan",
"contracts": [
"fullTimeContract"
],
"prohibitedPairings": [
{
"pairedEmployee": "Beth"
}
]
}
],
"shifts": [
{
"id": "Mon morning 1",
"start": "2027-02-01T06:00:00Z",
"end": "2027-02-01T14:00:00Z"
},
{
"id": "Mon morning 2",
"start": "2027-02-01T06:00:00Z",
"end": "2027-02-01T14:00:00Z"
},
{
"id": "Mon afternoon 1",
"start": "2027-02-01T14:00:00Z",
"end": "2027-02-01T22:00:00Z"
},
{
"id": "Mon afternoon 2",
"start": "2027-02-01T14:00:00Z",
"end": "2027-02-01T22:00:00Z"
}
]
}
}
To request the solution, locate the 'ID' from the response to the post operation and append it to the following API call: |
curl -X GET -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/employee-scheduling/v1/schedules/<ID>
{
"run": {
"id": "ID",
"name": "Prohibited pairing example",
"submitDateTime": "2024-10-16T09:40:26.218622765Z",
"startDateTime": "2024-10-16T09:40:30.741835093Z",
"completeDateTime": "2024-10-16T09:45:31.131026483Z",
"solverStatus": "SOLVING_COMPLETED",
"score": "0hard/0medium/0soft",
"tags": null,
"validationResult": {
"summary": "OK"
}
},
"modelOutput": {
"shifts": [
{
"id": "Mon morning 1",
"employee": "Ann"
},
{
"id": "Mon morning 2",
"employee": "Beth"
},
{
"id": "Mon afternoon 1",
"employee": "Carl"
},
{
"id": "Mon afternoon 2",
"employee": "Dan"
}
]
},
"kpis": {
"assignedShifts": 4,
"unassignedShifts": 0,
"workingTimeFairnessPercentage": 0.0,
"disruptionPercentage": 0.0
}
}
modelOutput
contains the employee shift schedule with Dan and Beth assigned to different shifts.
Prohibited pairing rules can be filtered with tags to limit the scope of the rule. See Filtering pairings with tags for more information. |
5. Conflicting Pairings
When adding pairings be careful to watch for conflicting pairings.
Conflicting pairings can occur in the following ways:
-
Dan prefers to work with Carl, but Carl prefers not to work with Dan.
-
Ann is required to work with Beth, but Beth is prohibited from working with Ann.
In the case of conflicting preferredPairings
and unpreferredPairings
, the employees might be paired together on a shift.
If this occurs, a positive soft constraint score will be added for the preferred pairing and a negative soft constraint score will be added for the failed unpreferred pairing, resulting in no score difference.
In the case of conflicting requiredPairings
and prohibitedPairings
, the employee with the required pairing for an employee with a corresponding prohibited pairing with them, will not be assigned a shift.
For instance, if Ann has a required pairing with Beth, and Beth has a prohibited pairing with Ann, Beth can be assigned a shift without Ann, but Ann cannot be assigned a shift without Beth, resulting in Beth being assigned shifts, and Ann not being assigned shifts.
6. Filtering pairings with tags
Pairing rules can be filtered with tags so that they only apply to specific shifts if employees only need to be paired in specific scenarios.
Tags can identify requirements for shifts including:
-
The shift time: "morning", "afternoon", "night".
-
The shift location: "central location", "eastern location".
-
Shifts in a specific department: "department A", "department B".
Using tags, can filter the pairing rules so that only apply to shifts with corresponding tags.
To limit the scope of a pairing rule, add onlyForShiftTags
to the pairing rule and include the shift tags the rule should be applied to.
{
"employees": [
{
"id": "Ann",
"preferredPairings": [
{
"pairedEmployee": "Dan",
"onlyForShiftTags": [
"afternoon"
]
}
]
}
],
"shifts": [
{
"id": "Mon afternoon 1",
"start": "2027-02-01T14:00:00Z",
"end": "2027-02-01T22:00:00Z",
"tags": [
"afternoon"
]
}
]
}
In the following example, Ann and Dan prefer to be paired but only on afternoon shifts. They might still be paired on other shifts, but Timefold is incentivized to pair them on afternoon shifts.
-
Input
-
Output
Try this example in Timefold Platform by saving this JSON into a file called sample.json and make the following API call:
|
curl -X POST -H "Content-type: application/json" -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/employee-scheduling/v1/schedules [email protected]
{
"config": {
"run": {
"name": "Preferred pairing example with tags"
}
},
"modelInput": {
"contracts": [
{
"id": "fullTimeContract",
"periodRules": [
{
"id": "Max8HoursPerDayFullTime",
"period": "DAY",
"minutesWorkedMax": 480
}
]
}
],
"employees": [
{
"id": "Ann",
"contracts": [
"fullTimeContract"
],
"preferredPairings": [
{
"pairedEmployee": "Dan",
"onlyForShiftTags": [
"afternoon"
]
}
]
},
{
"id": "Beth",
"contracts": [
"fullTimeContract"
]
},
{
"id": "Carl",
"contracts": [
"fullTimeContract"
]
},
{
"id": "Dan",
"contracts": [
"fullTimeContract"
]
}
],
"shifts": [
{
"id": "Mon morning 1",
"start": "2027-02-01T06:00:00Z",
"end": "2027-02-01T14:00:00Z",
"tags": [
"morning"
]
},
{
"id": "Mon morning 2",
"start": "2027-02-01T06:00:00Z",
"end": "2027-02-01T14:00:00Z",
"tags": [
"morning"
]
},
{
"id": "Mon afternoon 1",
"start": "2027-02-01T14:00:00Z",
"end": "2027-02-01T22:00:00Z",
"tags": [
"afternoon"
]
},
{
"id": "Mon afternoon 2",
"start": "2027-02-01T14:00:00Z",
"end": "2027-02-01T22:00:00Z",
"tags": [
"afternoon"
]
}
]
}
}
To request the solution, locate the 'ID' from the response to the post operation and append it to the following API call: |
curl -X GET -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/employee-scheduling/v1/schedules/<ID>
{
"run": {
"id": "ID",
"name": "Preferred pairing example with tags",
"submitDateTime": "2024-10-17T02:32:40.431242707Z",
"startDateTime": "2024-10-17T02:32:45.045987051Z",
"completeDateTime": "2024-10-17T02:37:45.360431728Z",
"solverStatus": "SOLVING_COMPLETED",
"score": "0hard/0medium/960soft",
"tags": null,
"validationResult": {
"summary": "OK"
}
},
"modelOutput": {
"shifts": [
{
"id": "Mon morning 1",
"employee": "Carl"
},
{
"id": "Mon morning 2",
"employee": "Beth"
},
{
"id": "Mon afternoon 1",
"employee": "Ann"
},
{
"id": "Mon afternoon 2",
"employee": "Dan"
}
]
},
"kpis": {
"assignedShifts": 4,
"unassignedShifts": 0,
"workingTimeFairnessPercentage": 0.0,
"disruptionPercentage": 0.0
}
}
modelOutput
contains the employee shift schedule with Ann and Dan scheduled together on the afternoon shift.
Next
-
Understand the constraints of the Employee Shift Scheduling model.
-
See the full API spec or try the online API.
-
Manage schedules with Timezones and Daylight Saving Time (DST) changes.
-
Manage Employee availability.