Docs
  • Solver
  • Models
    • Field Service Routing
    • Employee Shift Scheduling
    • Pick-up and Delivery Routing
  • Platform
Try models
  • Employee Shift Scheduling
  • Shift service constraints
  • Shift assignments
  • Employee selection
  • latest
    • latest
    • 1.22.x

Employee Shift Scheduling

    • Introduction
    • Getting started: Hello world
    • User guide
      • Terminology
      • Use case guide
      • Planning AI concepts
      • Integration
      • Constraints
      • Understanding the API
      • Demo datasets
      • Input datasets
        • Model configuration
        • Model input
        • Planning window
      • Planning window
      • Time zones and Daylight Saving Time (DST)
      • Tags and tag types
      • Input validation
      • Output datasets
        • Metadata
        • Model output
        • Input metrics
        • Key performance indicators (KPIs)
      • Metrics and optimization goals
      • Score analysis
      • Visualizations
    • Employee resource constraints
      • Employee contracts
      • Employee availability
      • Employee priority
      • Pairing employees
      • Shift travel and locations
      • Shift Breaks
      • Employee activation
      • Work limits
        • Minutes worked per period
        • Minutes worked in a rolling window
        • Minutes logged per period
        • Days worked per period
        • Days worked in a rolling window
        • Consecutive days worked
        • Shifts worked per period
        • Shifts worked in a rolling window
        • Weekend minutes worked per period
        • Weekends worked per period
        • Weekends worked in a rolling window
        • Consecutive weekends worked
      • Time off
        • Days off per period
        • Consecutive days off per period
        • Consecutive days off in a rolling window
        • Consecutive minutes off in a rolling window
        • Shifts to avoid close to day off requests
        • Consecutive weekends off per period
      • Shift rotations and patterns
        • Shift rotations
        • Single day shift sequence patterns
        • Minimize gaps between shifts
        • Multi-day shift sequence patterns
        • Daily shift pairings
        • Overlapping shifts
        • Shift start times differences
        • Minutes between shifts
      • Shift type diversity
        • Shift tag types
        • Shift types worked per period
        • Unique tags per period
      • Fairness
        • Balance time worked
        • Balance shift count
    • Shift service constraints
      • Alternative shifts
      • Cost management
        • Cost groups
        • Employee rates
      • Demand-based scheduling
      • Mandatory and optional shifts
      • Skills and risk factors
      • Shift assignments
        • Shift selection
        • Employee selection
    • Manual intervention
    • Recommendations
    • Real-time planning
    • Real-time planning (preview)
    • Scenarios
      • Configuring labor law compliance
      • Configuring employee well-being
    • Changelog
    • Upgrade to the latest version
    • Feature requests

Employee selection

There are also times when specific employees are preferred for specific shifts, while other employees might be unpreferred or prohibited from being assigned specific shifts.

This guide explains how to assign the correct employees to shifts:

  • 1. Preferred Employee
  • 2. Unpreferred Employee
  • 3. Prohibited Employee

1. Preferred Employee

When specific employees are preferred for a specific shift, this preference is added to the shift’s preferredEmployees:

{
  "id": "Mon 1",
  "start": "2027-02-01T09:00:00Z",
  "end": "2027-02-01T17:00:00Z",
  "preferredEmployees": ["Ann"]
}

The Preferred employee assigned soft constraint is invoked when a preferred employee is assigned to a shift, adding a soft reward to the dataset score.

If a preferred employee cannot be assigned, the shift will be assigned to another employee.

Every soft constraint has a weight that can be configured to change the relative importance of the constraint compared to other constraints.

Learn about constraint weights.

This rule is more likely to be satisfied for employees with a higher employee priority. See Employee priority for more details.

In the following example, Ann is the preferred employee for two shifts. She is assigned one of the shifts where she is preferred employee and a soft reward is added to the dataset score. The other shifts are assigned to other employees.

preferred 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": "Preferred employee"
    }
  },
  "modelInput": {
    "employees": [
      {
        "id": "Ann"
      },
      {
        "id": "Beth"
      },
      {
        "id": "Carl"
      }
    ],
    "shifts": [
      {
        "id": "Mon 1",
        "start": "2027-02-01T09:00:00Z",
        "end": "2027-02-01T17:00:00Z",
        "preferredEmployees": ["Ann"]
      },
      {
        "id": "Mon 2",
        "start": "2027-02-01T09:00:00Z",
        "end": "2027-02-01T17:00:00Z",
        "preferredEmployees": ["Ann"]
      },
      {
        "id": "Mon 3",
        "start": "2027-02-01T09:00:00Z",
        "end": "2027-02-01T17: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>
{
  "metadata": {
    "id": "ID",
    "name": "Preferred employee",
    "submitDateTime": "2025-04-30T06:16:28.418040846Z",
    "startDateTime": "2025-04-30T06:16:39.981929771Z",
    "activeDateTime": "2025-04-30T06:16:40.143585558Z",
    "completeDateTime": "2025-04-30T06:21:41.061626428Z",
    "shutdownDateTime": "2025-04-30T06:21:41.330402481Z",
    "solverStatus": "SOLVING_COMPLETED",
    "score": "0hard/0medium/960soft",
    "tags": [
      "system.profile:default"
    ],
    "validationResult": {
      "summary": "OK"
    }
  },
  "modelOutput": {
    "shifts": [
      {
        "id": "Mon 1",
        "employee": "Ann"
      },
      {
        "id": "Mon 2",
        "employee": "Beth"
      },
      {
        "id": "Mon 3",
        "employee": "Carl"
      }
    ]
  },
  "inputMetrics": {
    "employees": 3,
    "shifts": 3,
    "pinnedShifts": 0
  },
  "kpis": {
    "assignedShifts": 3,
    "unassignedShifts": 0,
    "workingTimeFairnessPercentage": null,
    "disruptionPercentage": 0.0,
    "averageDurationOfEmployeesPreferencesMet": null,
    "minimumDurationOfPreferencesMetAcrossEmployees": null,
    "averageDurationOfEmployeesUnpreferencesViolated": null,
    "maximumDurationOfUnpreferencesViolatedAcrossEmployees": null,
    "activatedEmployees": 3,
    "assignedMandatoryShifts": 3,
    "assignedOptionalShifts": 0,
    "assignedShiftGroups": null,
    "unassignedShiftGroups": null,
    "travelDistance": 0
  }
}

2. Unpreferred Employee

When specific employees are not preferred for a specific shift, this preference is added to the shift’s unpreferredEmployees:

{
  "id": "Mon 1",
  "start": "2027-02-01T09:00:00Z",
  "end": "2027-02-01T17:00:00Z",
  "unpreferredEmployees": ["Beth"]
}

The Unpreferred employee assigned soft constraint is invoked when an unpreferred employee is assigned to a shift, adding a soft penalty to the dataset score. Timefold is incentivized to use solutions with the best score.

Every soft constraint has a weight that can be configured to change the relative importance of the constraint compared to other constraints.

Learn about constraint weights.

This rule is more likely to be satisfied for employees with a higher employee priority. See Employee priority for more details.

In the following example, Beth is an unpreferred employee for all three shifts. Beth is assigned one of the shifts and a soft penalty is added to the dataset score.

unpreferred 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 employee"
    }
  },
  "modelInput": {
    "employees": [
      {
        "id": "Ann"
      },
      {
        "id": "Beth"
      },
      {
        "id": "Carl"
      }
    ],
    "shifts": [
      {
        "id": "Mon 1",
        "start": "2027-02-01T09:00:00Z",
        "end": "2027-02-01T17:00:00Z",
        "unpreferredEmployees": ["Beth"]
      },
      {
        "id": "Mon 2",
        "start": "2027-02-01T09:00:00Z",
        "end": "2027-02-01T17:00:00Z",
        "unpreferredEmployees": ["Beth"]
      },
      {
        "id": "Mon 3",
        "start": "2027-02-01T09:00:00Z",
        "end": "2027-02-01T17:00:00Z",
        "unpreferredEmployees": ["Beth"]
      }
    ]
  }
}
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>
{
  "metadata": {
    "id": "ID",
    "name": "Unpreferred employee",
    "submitDateTime": "2025-04-30T06:50:59.215676663Z",
    "startDateTime": "2025-04-30T06:51:16.863976097Z",
    "activeDateTime": "2025-04-30T06:51:17.011331875Z",
    "completeDateTime": "2025-04-30T06:56:17.833607342Z",
    "shutdownDateTime": "2025-04-30T06:56:18.091323158Z",
    "solverStatus": "SOLVING_COMPLETED",
    "score": "0hard/0medium/-960soft",
    "tags": [
      "system.profile:default"
    ],
    "validationResult": {
      "summary": "OK"
    }
  },
  "modelOutput": {
    "shifts": [
      {
        "id": "Mon 1",
        "employee": "Ann"
      },
      {
        "id": "Mon 2",
        "employee": "Carl"
      },
      {
        "id": "Mon 3",
        "employee": "Beth"
      }
    ]
  },
  "inputMetrics": {
    "employees": 3,
    "shifts": 3,
    "pinnedShifts": 0
  },
  "kpis": {
    "assignedShifts": 3,
    "unassignedShifts": 0,
    "workingTimeFairnessPercentage": null,
    "disruptionPercentage": 0.0,
    "averageDurationOfEmployeesPreferencesMet": null,
    "minimumDurationOfPreferencesMetAcrossEmployees": null,
    "averageDurationOfEmployeesUnpreferencesViolated": null,
    "maximumDurationOfUnpreferencesViolatedAcrossEmployees": null,
    "activatedEmployees": 3,
    "assignedMandatoryShifts": 3,
    "assignedOptionalShifts": 0,
    "assignedShiftGroups": null,
    "unassignedShiftGroups": null,
    "travelDistance": 0
  }
}

3. Prohibited Employee

When specific employees are prohibited for a specific shift, this preference is added to the shift’s prohibitedEmployees:

{
  "id": "Mon 1",
  "start": "2027-02-01T09:00:00Z",
  "end": "2027-02-01T17:00:00Z",
  "prohibitedEmployees": ["Carl"]
}

The Prohibited employee assigned hard constraint is invoked, which makes sure employees are not assigned to shifts where they are listed in prohibitedEmployee.

Shifts will be left unassigned if only a prohibited employee is available.

In the following example, there are three employees and three shifts. Carl is listed as a prohibited employee on all three shifts and is not assigned a shift.

prohibited 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": "Prohibited employee"
    }
  },
  "modelInput": {
    "employees": [
      {
        "id": "Ann"
      },
      {
        "id": "Beth"
      },
      {
        "id": "Carl"
      }
    ],
    "shifts": [
      {
        "id": "Mon 1",
        "start": "2027-02-01T09:00:00Z",
        "end": "2027-02-01T17:00:00Z",
        "prohibitedEmployees": ["Carl"]
      },
      {
        "id": "Mon 2",
        "start": "2027-02-01T09:00:00Z",
        "end": "2027-02-01T17:00:00Z",
        "prohibitedEmployees": ["Carl"]
      },
      {
        "id": "Mon 3",
        "start": "2027-02-01T09:00:00Z",
        "end": "2027-02-01T17:00:00Z",
        "prohibitedEmployees": ["Carl"]
      }
    ]
  }
}
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>
{
  "metadata": {
    "id": "ID",
    "name": "Prohibited employee",
    "submitDateTime": "2025-04-30T07:23:07.956004888Z",
    "startDateTime": "2025-04-30T07:23:19.755127437Z",
    "activeDateTime": "2025-04-30T07:23:19.948102534Z",
    "completeDateTime": "2025-04-30T07:28:20.858819064Z",
    "shutdownDateTime": "2025-04-30T07:28:21.169653541Z",
    "solverStatus": "SOLVING_COMPLETED",
    "score": "0hard/-1medium/0soft",
    "tags": [
      "system.profile:default"
    ],
    "validationResult": {
      "summary": "OK"
    }
  },
  "modelOutput": {
    "shifts": [
      {
        "id": "Mon 1",
        "employee": "Ann"
      },
      {
        "id": "Mon 2",
        "employee": "Beth"
      },
      {
        "id": "Mon 3",
        "employee": null
      }
    ]
  },
  "inputMetrics": {
    "employees": 3,
    "shifts": 3,
    "pinnedShifts": 0
  },
  "kpis": {
    "assignedShifts": 2,
    "unassignedShifts": 1,
    "workingTimeFairnessPercentage": null,
    "disruptionPercentage": 0.0,
    "averageDurationOfEmployeesPreferencesMet": null,
    "minimumDurationOfPreferencesMetAcrossEmployees": null,
    "averageDurationOfEmployeesUnpreferencesViolated": null,
    "maximumDurationOfUnpreferencesViolatedAcrossEmployees": null,
    "activatedEmployees": 2,
    "assignedMandatoryShifts": 2,
    "assignedOptionalShifts": 0,
    "assignedShiftGroups": null,
    "unassignedShiftGroups": null,
    "travelDistance": 0
  }
}

Next

  • See the full API spec or try the online API.

  • Learn more about employee shift scheduling from our YouTube playlist.

  • Manage Shift rotations and patterns and Employee contracts.

  • © 2026 Timefold BV
  • Timefold.ai
  • Documentation
  • Changelog
  • Send feedback
  • Privacy
  • Legal
    • Light mode
    • Dark mode
    • System default