Upgrade to the latest version
From 1.35.0 to 1.36.0
Employee groups replace grouped employee pairings
The commonTagType, groupByEmployeeTag and groupShiftsPerDayLimit fields have been removed from employee pairings and replaced by the new top-level employeeGroups collection.
See Employee groups for details.
To migrate, for each distinct value of groupByEmployeeTag, create an employeeGroups entry.
Note the pairing and group roles are inverted: an employee who declared the pairing through requiredPairings requires another member to be present, so they map to the group’s preferredEmployees; an employee who declared the pairing through preferredPairings can work alone, so they map to the group’s requiredEmployees.
-
Move the employees who declared the pairing through
requiredPairingsintopreferredEmployees. -
Move the employees who declared the pairing through
preferredPairingsintorequiredEmployees. -
Move
commonTagTypefrom the pairing onto the employee group. -
Move
groupShiftsPerDayLimit.groupShiftsPerDayMaxonto the employee group asgroupShiftsPerDayMax.
For example, this pairing-based configuration:
{
"employees": [
{
"id": "Ann",
"preferredPairings": [
{
"includeEmployeeWithTags": [ "CAR 1" ],
"commonTagType": "Zone A",
"groupByEmployeeTag": "CAR 1",
"groupShiftsPerDayLimit": { "groupShiftsPerDayMax": 1 }
}
]
},
{
"id": "Beth",
"requiredPairings": [
{
"includeEmployeeWithTags": [ "CAR 1" ],
"commonTagType": "Zone A"
}
]
}
]
}
becomes:
{
"employees": [
{ "id": "Ann" },
{ "id": "Beth" }
],
"employeeGroups": [
{
"id": "CAR 1",
"requiredEmployees": [ "Ann" ],
"preferredEmployees": [ "Beth" ],
"commonTagType": "Zone A",
"groupShiftsPerDayMax": 1
}
]
}
If you do not use commonTagType, groupByEmployeeTag or groupShiftsPerDayLimit on employee pairings, this change has no effect on your datasets.
Absence mode is now an object (preview)
This change is not backward compatible. Absence-aware rules are a preview feature, so backward compatibility isn’t guaranteed for them.
The absenceMode field on consecutiveDaysWorkedRules, minutesBetweenShiftsRules, and rollingWindowRules in contracts has changed from a plain string to an object with a type field.
The type field accepts the same values as before: ABSENCE_AWARE or ABSENCE_UNAWARE.
Requests that still send absenceMode as a string are no longer valid.
Replace every string value with the object form.
If you omit absenceMode, the rule still defaults to ABSENCE_UNAWARE, so rules without absenceMode need no changes.
The change is identical for all three rule types. For example, for a consecutive days worked rule:
Before:
"contracts": [
{
"id": "fullTimeContract",
"consecutiveDaysWorkedRules": [
{
"id": "max6ConsecutiveDaysWorked",
"maximum": 6,
"satisfiability": "REQUIRED",
"absenceMode": "ABSENCE_AWARE"
}
]
}
]
}
After:
{
"contracts": [
{
"id": "fullTimeContract",
"consecutiveDaysWorkedRules": [
{
"id": "max6ConsecutiveDaysWorked",
"maximum": 6,
"satisfiability": "REQUIRED",
"absenceMode": {
"type": "ABSENCE_AWARE"
}
}
]
}
]
}
The absenceMode object also accepts an optional includeDateTimeSpanTags list.
When non-empty, only unavailableTimeSpans and availableTimeSpans that share at least one tag with includeDateTimeSpanTags count toward absence awareness.
Time spans are matched using their new tags field.
When includeDateTimeSpanTags is empty or omitted, every span counts, matching the previous behavior.
includeDateTimeSpanTags requires type to be ABSENCE_AWARE.
For more information, see:
From 1.26.0 to 1.27.0
Historic shifts excluded from constraint matching
Constraint matches whose shifts all end before the planning window start are no longer reported, and these shifts are excluded from input and output metrics.
See Historic shifts for details.
If you do not set the planning window explicitly, this change has no effect on your datasets: the auto-derived window starts at the earliest shift, so no shift is treated as historic.
If you set the planning window explicitly and include shifts that end before its start, you might see fewer constraint matches and smaller metric counts than before, since they are now better targeted.
Shifts that end before the planning window starts should be pinned to their assigned employee; otherwise the model raises a validation warning.
From 1.25.0 to 1.26.0
Minimize gaps between shifts rules
The existing requiredPriorShiftTags and requiredAfterShiftTags fields have been deprecated and replaced by includePreviousShiftTags and includeNextShiftTags.
-
requiredPriorShiftTags→includePreviousShiftTags -
requiredAfterShiftTags→includeNextShiftTags
Minutes between shifts rules
The existing requiredPriorShiftTags and requiredAfterShiftTags fields have been deprecated and replaced by includePreviousShiftTags and includeNextShiftTags.
Similarly, minimumConsecutivePriorShifts has been deprecated in favor of minConsecutivePreviousShifts.
-
requiredPriorShiftTags→includePreviousShiftTags -
requiredAfterShiftTags→includeNextShiftTags -
minimumConsecutivePriorShifts→minConsecutivePreviousShifts
From 1.23.0 to 1.24.0
Employee priority changes
The LOW, NORMAL, HIGH, CRITICAL values for the priority field of employees have been deprecated in favor of numeric values (1-10).
If you want to maintain the same priority levels, replace the existing values with the following mapping:
-
LOW→10 -
NORMAL→9 -
HIGH→8 -
CRITICAL→7
Otherwise, you can adjust the priority values according to your needs, where 1 is the highest priority and 10 is the lowest priority.
From 1.21.0 to 1.22.0
Disruption rules changes
The disruptionRules field of the globalRules has been deprecated in favor of the contract-level disruptionRules.
First, remove the global disruptionRules from the dataset.
Next, add a new contract to the dataset:
{
"contracts": [
{
"id": "disruptionContract",
"disruptionRules": [
{
"id": "disruptionRule",
"disruptionWeight": 1
}
]
}
]
}
And then assign this contract to every employee. This will replicate the behavior of a single global disruption rule.
Alternatively, each employee can have a disruption rule added to their existing contract, which is weighted according to the importance of disruption to them.
Additionally, the Minimize disruption per employee constraint has been split into two separate constraints:
-
Minimize outgoing disruption per employee: penalizes when an employee loses shifts that were originally assigned to them. -
Minimize incoming disruption per employee: penalizes when an employee receives shifts that were not originally assigned to them.
The existing constraint weight employeeAssignmentDisruptedOnReplanningWeight (for global disruption rules) is now deprecated.
Use minimizeOutgoingDisruptionForEmployeeWeight and minimizeIncomingDisruptionForEmployeeWeight instead.
From 1.19.0 to 1.20.0
Activation cost no longer included in cost rules calculation
The employeeActivationCost is no longer included in the total cost calculation for cost rules.
Previously, the activation cost was incorrectly added to every shift assigned to an employee, effectively multiplying it by the number of shifts.
This was unintended behavior - activation cost should be a one-time fee when an employee is first activated.
The activation cost continues to work correctly through the Minimize employee activation cost constraint.
If you want to increase the per-shift cost to compensate, you can adjust the cost value in your employeeShiftCostDetails.
For example, if your previous configuration had:
{
"employeeCostGroups": [
{
"id": "contractors",
"employeeActivationCost": 50
}
],
"globalRules": {
"costsRules": [
{
"id": "budgetRule",
"employeeShiftCostDetails": [
{
"employeeCostGroup": "contractors",
"shiftCostGroup": "standard",
"cost": 100
}
]
}
]
}
}
To maintain the same per-shift cost calculation, update the cost to include the activation cost:
{
"employeeCostGroups": [
{
"id": "contractors",
"employeeActivationCost": 50
}
],
"globalRules": {
"costsRules": [
{
"id": "budgetRule",
"employeeShiftCostDetails": [
{
"employeeCostGroup": "contractors",
"shiftCostGroup": "standard",
"cost": 150
}
]
}
]
}
}
From 1.18.0 to 1.19.0
Replace deprecated minutesWorkedMin and minutesWorkedMax with minutesWorkedLimit in period rules
The minutesWorkedMin and minutesWorkedMax attributes have been deprecated in favor of minutesWorkedLimit in period rules.
The following rules are affected:
Replace any occurrences of minutesWorkedMin and minutesWorkedMax with minutesWorkedLimit:
{
"contracts": [
{
"id": "fullTimeContract",
"periodRules": [
{
"id": "Maximum 40 hours a week",
"period": "WEEK",
"minutesWorkedLimit": {
"minutesWorkedMax": 2400
}
}
]
}
]
}
From 1.14.0 to 1.15.0
The output metrics of unassigned and assigned shifts now represent different things
Prior to the update, all shifts in the input were evaluated as either assigned or unassigned and these numbers were returned in the output metrics,
as assignedShifts and unassignedShifts.
Now only the shifts that are not a part of a shift group are counted.
For instance, with input that has ten shifts, including four shifts that belong to a shift group, if all six shifts and one shift from the shift group were assigned, the output metrics before the update would have been:
unassignedShifts |
3 |
assignedShifts |
7 |
assignedShiftGroups |
1 |
unassignedShiftGroups |
0 |
After the update the output metrics are:
unassignedShifts |
0 |
assignedShifts |
6 |
assignedShiftGroups |
1 |
unassignedShiftGroups |
0 |
From 1.10.0 to 1.11.0
The run object in the model response has been deprecated and renamed as metadata.
Its internal structure has not changed.
Affected endpoints:
-
GET /v1/schedules/{id}/
Before:
{
"run": {
"id": "ID",
"parentId": "parentID",
"originId": "originID",
"name": "dataset name",
"submitDateTime": "2022-03-10T12:15:50-04:00",
"startDateTime": "2022-03-10T12:15:50-04:00",
"activeDateTime": "2022-03-10T12:15:50-04:00",
"completeDateTime": "2022-03-10T12:15:50-04:00",
"shutdownDateTime": "2022-03-10T12:15:50-04:00",
...
}
After:
{
"metadata": {
"id": "ID",
"parentId": "parentID",
"originId": "originID",
"name": "dataset name",
"submitDateTime": "2022-03-10T12:15:50-04:00",
"startDateTime": "2022-03-10T12:15:50-04:00",
"activeDateTime": "2022-03-10T12:15:50-04:00",
"completeDateTime": "2022-03-10T12:15:50-04:00",
"shutdownDateTime": "2022-03-10T12:15:50-04:00",
...
}
}
Replace deprecated builtInRotationPeriod by rotationPeriod in shift rotation rules
The builtInRotationPeriod attribute has been deprecated in favor of rotationPeriod in shift rotation rules.
The following rules are affected:
Replace any occurrences of builtInRotationPeriod by rotationPeriod:
{
"contracts": [
{
"id": "fullTimeContract",
"shiftRotationRules": [
{
"id": "rotateMorningAndAfternoonShiftsWeekly",
"rotationPeriod": {
"type": "WEEKLY"
},
"rotationGroups": [
{
"id": "morningShifts",
"includeShiftTags": [
"Morning"
]
},
{
"id": "afternoonShifts",
"includeShiftTags": [
"Afternoon"
]
}
]
}
]
}
]
}
From 0.38.0 to 0.39.0
Added support for diminished returns termination
When submitting a new schedule with unspecified unimprovedSpentLimit in the run termination configuration, the run will use the new diminished returns termination.
Diminished returns termination is enabled by default when unimprovedSpentLimit isn’t present.
For existing datasets, remove unimprovedSpentLimit to enable diminished returns termination.
Before:
{
"config": {
"run": {
"name": "My run",
"termination": {
"spentLimit": "PT30M",
"unimprovedSpentLimit": "PT1M"
}
}
}
After:
{
"config": {
"run": {
"name": "My run",
"termination": {
"spentLimit": "PT30M"
}
}
}
If you weren’t setting the unimprovedSpentLimit and you need to keep the old behavior, set the unimprovedSpentLimit to the value of spentLimit:
Before:
{
"config": {
"run": {
"name": "My run",
"termination": {
"spentLimit": "PT30M"
}
}
}
After (only if you want to keep the old behavior):
{
"config": {
"run": {
"name": "My run",
"termination": {
"spentLimit": "PT30M",
"unimprovedSpentLimit": "PT30M"
}
}
}
Affects the following REST endpoints:
-
POST /v1/schedules
From 0.34.0 to 0.35.0
Travel configuration changes
The travelConfiguration field of the scheduleParameterization has been deprecated in favor of the contract-level travelConfigurations.
First, remove the global travelConfiguration from the dataset:
{
"scheduleParameterization": {
"travelConfiguration": {
"maxEmployeeToShiftTravelDistanceInMeters": 25000,
"minMinutesBetweenShiftsInDifferentLocations": 60
}
}
}
Next, add a new contract to the dataset with the travel configuration:
{
"contracts": [
{
"id": "travelContract",
"travelConfigurations": [
{
"id": "travelConfig",
"maxEmployeeToShiftTravelDistanceInMeters": 25000,
"minMinutesBetweenShiftsInDifferentLocations": 60
}
]
}
]
}
And then assign this contract to every employee. This will replicate the behavior of a single global travel configuration.
Alternatively, each employee can have a travel configuration added to their existing contract.
See Shift travel and locations for more information.
From 0.32.1 to 0.33.0
Single-day shift pattern rules with REQUIRED satisfiability deprecated
single day shift pattern rules with REQUIRED satisfiability have been deprecated and should be replaced by a rule with PREFERRED satisfiability with a high pattern weight.
Affects all REST endpoints starting with /v1/schedules when the input dataset uses single-day pattern rules.
Before:
"singleDayShiftSequencePatternRules": [
{
"id": "someRequiredPattern",
"satisfiability": "REQUIRED",
"pattern": [
...
]
},
{
"id": "somePreferredPattern",
"satisfiability": "PREFERRED",
"pattern": [
...
]
}
]
After:
"singleDayShiftSequencePatternRules": [
{
"id": "someRequiredPattern",
"satisfiability": "PREFERRED",
"weight": 100,
"pattern": [
...
]
},
{
"id": "somePreferredPattern",
"satisfiability": "PREFERRED",
// the default weight is 1
"pattern": [
...
]
}
]
Zone Offset Deprecation
zoneOffset on employees is now deprecated in favor of timeZoneId.
Before:
{
"employees":
{
"id": "Carl",
"contracts": [
"Carl's Contract"
],
"timezoneOffset": "+01:00"
}
}
After:
{
"employees":
{
"id": "Carl",
"contracts": [
"Carl's Contract"
],
"timeZoneId": "Europe/Brussels"
}
}
From 0.28.0 to 0.29.0
Multi-day shift pattern rules with REQUIRED satisfiability deprecated
Multi-day shift pattern rules with REQUIRED satisfiability have been deprecated and should be replaced by a rule with PREFERRED satisfiability with a high pattern weight.
Affects all REST endpoints starting with /v1/schedules when the input dataset uses multi-day pattern rules.
Before:
"multiDayShiftSequencePatternRules": [
{
"id": "someRequiredPattern",
"satisfiability": "REQUIRED",
"pattern": [
...
]
},
{
"id": "somePreferredPattern",
"satisfiability": "PREFERRED",
"pattern": [
...
]
}
]
After:
"multiDayShiftSequencePatternRules": [
{
"id": "someRequiredPattern",
"satisfiability": "PREFERRED",
"weight": 100,
"pattern": [
...
]
},
{
"id": "somePreferredPattern",
"satisfiability": "PREFERRED",
// the default weight is 1
"pattern": [
...
]
}
]
From 0.25.0 to 0.26.2
Justifications retrieved for a completed dataset are limited to 100 per constraint
The number of justifications that is stored and can be retrieved for a completed dataset has been limited to 100 per each constraint.
Affects the following REST endpoints:
-
GET /v1/schedules/{id}/score-analysis?includeJustifications=true
To get the full list of justifications, use the following endpoint:
-
POST /v1/schedules/score-analysis?includeJustifications=true
From 0.24.0 to 0.25.0
Shift’s assignmentPriority attribute has been deprecated in favor of the priority attribute.
See mandatory and optional shifts for more information.
From 0.18.0 to 0.19.0
The version 0.19.0 introduces changes to the API. The changes are not backward compatible and require changes to the client code.
Local date time replaced by date time with offset to UTC
All ISO 8601 local date time types have been replaced by ISO 8601 local date time with offset to UTC (Coordinated Universal Time) to support multiple time zones.
Affects all REST endpoints starting with /v1/schedules.
before (start and end are just examples, all date time attributes are affected):
{
"start": "2024-01-01T08:00:00",
"end": "2024-01-01T12:00:00"
}
after (assuming the original local date time values are in UTC):
{
"start": "2024-01-01T08:00:00Z",
"end": "2024-01-01T12:00:00Z"
}
From 0.17.0 to 0.17.1
The version 0.17.1 introduces changes to the API. The changes are not backward compatible and require changes to the client code.
Model output shift format changed
The employee object in the shift has been replaced by a string attribute.
The attribute represents the identifier of the employee.
Affects the following REST endpoints:
-
GET /v1/schedules/{id}
-
DELETE /v1/schedules/{id}
Before:
"modelOutput": {
"shifts": [
{
"id": "7",
"employee": {
"id": "John Doe"
}
},
...
]
}
After:
"modelOutput": {
"shifts": [
{
"id": "7",
"employee": "John Doe"
},
...
]
}
From 0.16.0 to 0.17.0
The version 0.17.0 introduces changes to the API. The changes are not backward compatible and require changes to the client code.
Model output format changed
The model output object now only contains shifts collection.
The shift object now only contains the id and employee attributes.
This helps to reduce the size of the response.
Affects the following REST endpoints:
-
GET /v1/schedules/{id}
-
DELETE /v1/schedules/{id}
Before:
"modelOutput": {
"contracts": [
...
],
"shifts": [
{
"id": "7",
"start": "2024-06-10T09:00:00",
"end": "2024-06-10T17:00:00",
"requiredSkills": [
"Supervisor"
]
"employee": "John Doe"
},
...
],
...
}
After:
"modelOutput": {
"shifts": [
{
"id": "7",
"employee": {
"id": "John Doe"
}
},
...
]
}
From 0.13.0 to 0.14.0
The version 0.14.0 introduces changes to the API. The changes are not backward compatible and require changes to the client code.
Submit schedule request input format changed
Submit schedule request introduces a new structure to separate the schedule from the configuration:
-
schedule object is now included in the
modelInputattribute. -
scheduleParametrization.constraintConfigurationhas been moved toconfig.model.overrides. -
terminationhas been moved toconfig.run.termination.
Affects the following REST endpoints:
-
POST /v1/schedules/
Before:
{
"contracts": [
...
],
"employees": [
...
],
"termination": {
"spentLimit": "PT10M",
"unimprovedSpentLimit": "PT5M"
}
...
}
After:
{
{
"modelInput": {
"contracts": [
...
],
"employees": [
...
],
},
"config": {
"run": {
"name": "ICU dataset 01-01-2024",
"termination": {
"spentLimit": "PT10M",
"unimprovedSpentLimit": "PT5M"
}
},
"model": {
"overrides": {
"preferredEmployeeAssignedWeight": 10
}
}
}
}
Schedule output format changed
Get schedule request introduces a new structure to separate the result schedule from the run information:
-
statusobject is now replaced byrunobject. -
schedule object is now included in the
modelOutputattribute.
Affects the following REST endpoints:
-
GET /v1/schedules/
-
DELETE /v1/schedules/
Before:
{
"contracts": [
...
],
"employees": [
...
],
"status": {
"id": "dd9b4560-be61-4124-a4cf-fae993ee1a31",
"submitDateTime": "2024-04-23T09:16:55.188848+02:00",
...
}
After:
{
"run": {
"id": "dd9b4560-be61-4124-a4cf-fae993ee1a31",
"name": "Run-2024-04-23T09:16:55.188848+02:00",
"submitDateTime": "2024-04-23T09:16:55.188848+02:00",
...
},
"modelOutput": {
"contracts": [
...
],
"employees": [
...
],
},
"kpis": {
"unassignedShifts": 0
}
}
Schedule status request replaced by run request
The schedule status request has been replaced by the run request.
Affects the following REST endpoints:
-
GET /v1/schedules/{id}/status
Before:
-
GET /v1/schedules/{id}/status
After:
-
GET /v1/schedules/{id}/run
Score analysis request input format changed
Score analysis request introduces a new structure to separate the schedule from the configuration:
-
schedule object is now included in the
modelInputattribute. -
scheduleParametrization.constraintConfigurationhas been moved toconfig.model.overrides.
Affects the following REST endpoints:
-
POST /v1/schedules/score-analysis
Before:
{
"contracts": [
...
],
"employees": [
...
],
"scheduleParametrization": {
"constraintConfiguration": {
"preferredEmployeeAssignedWeight": 10
}
}
...
}
After:
{
{
"modelInput": {
"contracts": [
...
],
"employees": [
...
],
},
"config": {
"model": {
"overrides": {
"preferredEmployeeAssignedWeight": 10
}
}
}
}
Recommend employees request input format changed
Recommend employees request introduces a new structure to separate the schedule from the configuration:
-
schedule object is now included in the
modelInputattribute. -
scheduleParametrization.constraintConfigurationhas been moved toconfig.model.overrides.
Affects the following REST endpoints:
-
POST /v1/schedules/recommendations/recommend-employees
Before:
{
"maxNumberOfRecommendations": 5,
"fitShiftId": "99999",
"contracts": [
...
],
"employees": [
...
],
"scheduleParametrization": {
"constraintConfiguration": {
"preferredEmployeeAssignedWeight": 10
}
}
...
}
After:
{
"maxNumberOfRecommendations": 5,
"fitShiftId": "99999",
"modelInput": {
"contracts": [
...
],
"employees": [
...
],
},
"config": {
"preferredEmployeeAssignedWeight": 10
}
}
Employee now supports declaring multiple contracts
This is useful when a single employee works in multiple institutions and each institution has different limits.
Affects the following REST endpoints:
-
POST /v1/schedules/
-
POST /v1/schedules/score-analysis
-
POST /v1/schedules/{id}/recommendations/recommend-employees
-
GET /v1/schedules/{id}
-
DELETE /v1/schedules/{id}
Before:
{
...
"employees": [
{
"id": "Elsa Green",
"contract": "ICU contract",
...
}
]
}
After:
{
...
"employees": [
{
"id": "Elsa Green",
"contracts": [
"Hospital 1 contract",
"Hospital 2 contract"
],
...
}
]
}
Default values and non-required attributes are no longer included in the response schedule
-
GET /v1/schedules/{id}
-
DELETE /v1/schedules/{id}
Before:
{
...
{
"periodRules": [
{
"id": "Maximum 40 hours a week",
"period": "WEEK",
"satisfiability": "REQUIRED",
"includeShiftTags": null,
"excludeShiftTags": null,
"shiftTagMatches": "ALL",
"minutesWorkedMin": null,
"minutesWorkedMax": 2400,
"shiftsWorkedMin": null,
"shiftsWorkedMax": null,
"daysWorkedMin": null,
"daysWorkedMax": null,
"shiftTypesTagCategories": null,
"shiftTypesWorkedMin": null,
"shiftTypesWorkedMax": null
}
...
}
After:
{
...
{
"periodRules": [
{
"id": "Maximum 40 hours a week",
"period": "WEEK",
"minutesWorkedMax": 2400
}
...
}
Collection attributes in the input schedule are no longer nullable
Affects the following REST endpoints:
-
POST /v1/schedules/
-
POST /v1/schedules/score-analysis
-
POST /v1/schedules/{id}/recommendations/recommend-employees
If included, the collection attributes now require a non-null value.
Before:
{
"periodRules": [
{
"id": "Maximum 40 hours a week",
"period": "WEEK",
"includeShiftTags": null,
"excludeShiftTags": null
...
}
After:
{
"periodRules": [
{
"id": "Maximum 40 hours a week",
"period": "WEEK",
"includeShiftTags": [],
"excludeShiftTags": []
...
}