NAV

# Introduction

Welcome to the adiutaByte API. The goal of the API is to provide an interface for generating plans for various fleet optimization problems. This API description is intended to help setting up your own code to access the adiutaByte API. Currently there are two API endpoints implemented. The first one is for submitting a problem description, for which an optimized plan is then calculated. The second endpoint is for retrieving this finalized plan.

The API uses token-based authentication to protect these endpoints; users are generated on demand. Feel free to contact us for such a personalized access.

The furthest right column of this page will provide examples to data structures, requests or responses. Additionally there will be a few code snippets for some languages. With the tabs in the upper right corner you can switch the example's programming language.

Currently the API solely supports JSON formatted data. For the JSON structures there is a schema that is used to validate the data. Non-valid requests are immediately rejected with an error message. The structure and meaning of the JSON data used is shown in the first part of the following description. In each section a downloadable corresponding JSON schema in the latest version is linked.

For the different requests you need to insert some entries in the header:

• Authorization (your ID-token, see Authentication)
• Accepts ("application/json")
• Content-Type ("application/json")

Currently we distinguish between users whose limits for how many tasks can be planned within a month are managed by us, and accounts which are used for clients, to which a special management account exists to register new clients. For such an account the limits are set per client. The account for submitting plans and the account for management use the same e-mail-address but need to identify against different cognitio pools. The configuration for the different account types can be found in Authentication. To identify the different clients you need to relay the client-ID to the backend in every request.

## Tags

• Features that are planned and not yet implemented are marked with TBA (Example: timeEarliest TBA). These are in a conceptual phase and might still get changed or deleted.
• Some features might not yet work, depending on what application version the plan is being calculated on. Features that are not yet live for all requests are marked with the version they are first introduced on (Example: timeEarliest v1.0.0). To determine the used version, check the field info->text in the response or contact us. pre v2.26.0: This only works for MixedPlanner-Requests

## Restrictions

Certain values on input objects can restrict the general set of available solutions. These include time windows on tasks, workers or shifts, preferences of all kinds, categories, qualifications and many more. Due to the nature of optimization, not all of them can be kept nor is that even intended, as violating a constraint can often lead to vast improvements regarding another metric. Nevertheless there are some constraints the algorithm will keep at all costs, as they are deemed too important to be disregarded.

To differentiate the types of constraints, there will be an occasional Depends on column added to the parameter listing. It can contain a number of different text markers:

• "strict": A constraint that the algorithm either literally cannot violate or can do so but only in a worst-case scenario, for instance to keep another strict constraint. (Example: Qualifications)
• An optimization parameter: The constraint depends on the optimization parameter setting. The higher the setting value, the more likely it is for the restriction to be kept. However, unless noted otherwise, it cannot reach the importance level of a strict constraint. (Example: preferredWorkers)
• Nothing: The parameter either is not a constraint or its importance cannot be influenced via input data settings. (Example: gender or desiredWorker)

If you notice issues or error with the documentation, if you have questions regarding the API or its documentation or if you're having another related issue, please contact us.

# Definition of common types

## Integers/Numbers

{
"integer_u32": 12,
"integer_s32": -12,
"number_u32" : 7.184535,
"number_s32" : -7.184535,
"number_u64" : 7.184535,
"number_s64" : -7.184535
}


JSON-Schema

The following ranges get used for values of type integer/ number:

ID Name Range
integer_u32 integer $0 \leq x \leq 2147483647$
integer_s32 integer $-2147483648 \leq x \leq 2147483647$
number_u32 number $0 \leq x \leq 3.4e+38$
number_s32 number $-3.4e+38 \leq x \leq 3.4e+38$
number_u64 number $0 \leq x \leq 1.7e+308$
number_s64 number $-1.7e+308 \leq x \leq 1.7e+308$

Please refer to the respective linked json schema to determine which type of integer/number gets used.

## GeoCoord

{
"lat": 50.780241,
"lng": 7.184535
}


JSON-Schema

Parameter Type Required Domain Description
lat number $-90 \leq x \leq 90$ The latitude of the coordinate
lng number $-180 \leq x \leq 180$ The longitude of the coordinate

## Date

Examples for valid date strings are :

"2018-01-10"
"2019-12-03"
"2020-05-23"


JSON-Schema

A string consisting of three parts following the pattern "YYYY-MM-DD":

• "YYYY": year AD, $2010 \leq x \leq 2099$
• "MM": month, $1 \leq x \leq 12$
• "DD": day, $1 \leq x \leq 31$

## Time

Examples for valid time strings are :

"06:59"
"15:59"
"1230:33"
"-39:12"
"03:01"


JSON-Schema

A string of either format "hh:mm" or "-hh:mm":

• "hh": hours, $0 \leq x \leq 9999$
• "mm": minutes, $0 \leq x \leq 59$ with exactly 2 digits

All times are interpreted in 24-hour notation and relative to midnight ("00:00") of a certain defined date. Those dates are:

This means that the following times applied to the respective date (in Date format) are equivalent:

• "2021-05-21" at "07:25"
• "2021-05-20" at "31:25"
• "2021-05-19" at "55:25"
• "2021-05-22" at "-16:35"
• "2021-05-23" at "-40:35"

Input data containing only identical dates and no time of format "-hh:mm" will not result in output data containing times of format "-hh:mm".

## VehicleType

An integer in the range $0 \leq x \leq 4$.

JSON-Schema

VehicleTypeID Description
0 Car
1 Bicycle
2 Pedestrian
3 Truck
4 Public Transport Approximation

## GenderType

JSON-Schema

An integer in the range $0 \leq x \leq 3$.

GenderTypeID Description
0 Not provided
1 Male
2 Female
3 Other

## LanguageType

An integer in the range $0 \leq x \leq 1$.

LanguageTypeID Description
0 German
1 English

## Parameter Preset

An integer in the range $0 \leq x \leq 4$. Depending on the type of plan (MixedPlanner/ ShiftPlanner) not all presets are valid for use. For more information please refer to the respective preset specification.

Preset ID Description
0 Eco orientied
1 Worker oriented
2 Customer oriented
3 Fleet oriented
4 Random

## Location Site

{
"locationSiteID": 200,
"location": {
"lat": 50.878847,
"lng": 6.964728400000013
}
}


JSON-Schema

A location site is a GeoCoord which can be referenced by an id in various places:

Parameter Type Required Description
locationSiteID integer The unique id of the location site
location GeoCoord The geocoordinates of the location site

## Shift

The minimum required shift JSON-body looks like this:

{
"shiftID": 1,
"shiftDate": "2019-12-03",
"shiftStart": "05:00",
"shiftEnd": "12:00"
}


The full shift JSON-body looks like this:

{
"shiftID": 1,
"shiftDate": "2019-12-03",
"shiftStart": "05:00",
"shiftEnd": "12:00",
"shiftPriority": 2
}


JSON-Schema (TODO)

A shift represents a worker's timeslot in which exactly one ShiftPlanner-Task can be carried out. For exceptions see the groupOrder parameter in ShiftPlanner-Tasks.

Parameter Required Type Description
shiftID integer A unique identifier for this shift.
shiftDate string (date) The date this timeslot is available on.
shiftStart string (time) The time this timeslot starts.
shiftEnd string (time) The time this timeslot ends.
shiftPriority integer The priority to keep the defined shift start/end times ranging from 0-3: irrelevant, neutral, important, very important. (Default: 1)

## Construction Site

{
"constructionSiteID": 666,
"startDate": "2020-07-23",
"endDate": "2020-07-25",
"startPoint": {
"lat": 48.17083,
"lng": 11.3292
},
"endPoint": {
"lat": 48.16774,
"lng": 11.33253
},
"info": "Waldstraße gesperrt 2020"
}


JSON-Schema

A construction site gets represented by a straight line between its startPoint and endPoint. These can be identical for small scale obstructions.

Parameter Required Type Description
constructionSiteID integer The unique ID of this construction site.
startPoint GeoCord Start point of the construction site.
endPoint GeoCoord End point of the construction site.
startDate string (date) The first day of construction work at this site.
endDate string (date) The last day of construction work at this site.
info string Misc. information.

## Clientinformation

{
"clientID": "{1234-5678-9123}"
}

Parameter Type Required Description
clientID string Identifies a specific client.

## Obstacle

The minimum required obstacle can look like these:

{
"type": "polyline",
"factor": 2.5,
"points": [
{
"lat": 51.46149994737996,
"lng": 7.850463381293338
},
{
"lat": 51.66914967977792,
"lng": 9.753747625087499
},
...
]
},
{
"type": "polygon",
"restriction": 0.5,
"points": [
{
"lat": 51.46149994737996,
"lng": 7.850463381293338
},
{
"lat": 51.66914967977792,
"lng": 9.753747625087499
},
...
]
},
{
"type": "polygon",
"travelTimeIncrease": 2.5,
"points": [
...
]
}


A full obstacle can look like this:

{
"type": "polyline",
"factor": 2.5,
"restriction": 0.5,
"travelTimeIncrease": 2.5,
"description": "This is a line",
"points": [
{
"lat": 51.46149994737996,
"lng": 7.850463381293338
},
{
"lat": 51.66914967977792,
"lng": 9.753747625087499
},
...
]
}


Further examples for obstacles

{
"type": "polygon",
"factor": 2.5,
"description": "This is a square obstacle",
"points": [
{
"lat": 0.0,
"lng": 0.0
},
{
"lat": 1.0,
"lng": 0.0
},
{
"lat": 1.0,
"lng": 1.0
},
{
"lat": 0.0,
"lng": 1.0
}
]
},
{
"type": "polyline",
"restriction": 0.5,
"description": "This is a W",
"points": [
{
"lat": 0.0,
"lng": 1.0
},
{
"lat": 0.5,
"lng": 0.0
},
{
"lat": 1.0,
"lng": 0.5
},
{
"lat": 1.5,
"lng": 0.0
},
{
"lat": 2.0,
"lng": 1.0
}
]
}


JSON-Schema

An obstacle represents a permanent traffic hindrance that increases travel times.

Parameter Type Required Description
type string Determines the type of obstacle. Currently available options are:
• polygon - An area based obstacle
• polyline - A line based obstacle
factor number The modifier to travel times through the obstacle. Can roughly be treated as an amplification factor on base travel time when driving short distances, but behaviour changes based on a multitude of other influences.
restriction number A level of restriction by this obstacle. Any travel through the obstacle will be avoided, if that is impossible, the algorithm will try to direct through those with lower restriction values. (0.0 - 1.0)
travelTimeIncrease number A flat travel time increase on each travel through this obstacle.
points Array<GeoCoord> The ordered set of coordinates that define the obstacle. For more information, see below.
description string A textual description of the obstacle.

Based on obstacle type, the shape of the obstacle is defined as follows:

• polygon: The points define the corner points of the obstacle, in order of their listing in the array. Each consecutive pair of GeoCoords defines a side of the polygon, so does the pair consisting of the first and last GeoCoord in the array.
• polyline: The points define the obstacle by connecting each consecutive pair of GeoCoords with a straight line.

At least one offactor, restriction or travelTimeIncrease needs to be set.

## Backend Version

Introduced in: v2.35.0

The minimum required Backend Version JSON-body looks like this:

{
"schema": "v0.0.0"
}


The full Backend Version JSON-body looks like this:

{
"schema": "v0.0.0",
"version": "v0.0.0",
"rev": "abde12"
}


JSON-Schema

Parameter Type Required Description
schema version The json schema version used for validating input and output.
version version The backend version used for calculating the result.
rev string An internal key for the backed version used for calculating the result.

# Definition of MixedPlanner-Types

## Mixedplanner-Metainformation

The minimum required Meta-Information looks like this:

{
"dateFrom": "2019-12-03",
"dateTo": "2019-12-03",
"resCapacity": false,
"resCategory": false,
"resQualification": false,
"postProcessing": false
}


A full Meta-Information object can look like this:

{
"dateFrom": "2019-12-03",
"dateTo": "2019-12-03",
"resCapacity": false,
"resCategory": false,
"resQualification": false,
"postProcessing": false,
"accuracyMode": 1.0,
"outputLanguage": 1,
"tightSchedule": false,
"travelTimeMin": 5,
"integrateDurationExtensions": true,
"integrateGermanBreakRegulations": true,
"enablePlanSplitting": true
}


JSON-Schema

Parameter Type Required Description
dateFrom string (date) Planning horizon start TBA.
dateTo string (date) Planning horizon end TBA.
resCapacity boolean Activate/Deactivate whether capacities should be considered in the optimization.
resCategory boolean Activate/Deactivate whether category types should be considered in the optimization.
resQualification boolean Activate/Deactivate whether qualifications should be considered in the optimization.
postProcessing boolean Enable or disable additional traffic optimizations.
accuracyMode number Manages a solution refinement process. An accuracy > 0.0 can improve the solution significantly but will take longer to calculate, effects increase with higher accuracyMode. (Default: 1.0)
outputLanguage integer (LanguageType) Defines which language should be used in the output. (Default: German)
tightSchedule boolean Defines if buffer should be eliminated after optimization to increase profitability. Time windows with a priority lower than 3 can be exceeded. (Default: false)
travelTimeMin integer A global lower limit to travel time, travel times below this will be raised. (Default: 0)
integrateDurationExtensions boolean All travel time and task duration return values will already include their respective modifier, further information below. This does not change algorithm results. (Default: false)
integrateGermanBreakRegulations boolean Adds mandatory breaks to workers according to the German Working Time Act if set. (Default: false)
enablePlanSplitting boolean Enables splitting the plan into disjunct plan parts. See below for details. (Default: true)
allowUnassignedTasks TBA boolean Enables unassigned tasks for the optimizer. See below for details. (Default: false)
useInitialClustering v2.33.0 boolean Use only clustering as a first optimization step instead of the default algorithms. Developer feature, use at your own risk! (Default: false)
dontOptimizeResets TBA boolean Don't factor in travel times to and from reset locations for the optimization. See below for details. (Default: false)

The options res* describe which fields from the dataset should be taken into account. More precisely those are:

The setting integrateDurationExtensions is an output-only setting, meaning both internal calculations and algorithm result are unaffected. Any values besides the ones listed below are unchanged:

Using the integrateDurationExtensions setting might provide some better readable data: Since internal calculations always apply the modifiers to durations and travel times, the internal values when calculating a plan are greater or equal to the ones that get output when not using integrateDurationExtensions. As a result, the output plan will feature gaps in time where for instance travel happens internally but would already be concluded if you used the output values. The integrateDurationExtensions setting outputs the internally used values to avoid this effect. However, the downside is inflated travel and work times in the output, since all buffers are now included in their respective work or travel time.

Using the option enablePlanSplitting can be benefitial if your input data contains clearly separateable sets of data, meaning you can create sets of workers and tasks, which can never be assigned to or carry out a task/worker from a different set than its own. In this case the option allows the algorithm to simplify the problem by solving each set separately. Additionally, any automatic input data modifications will be applied separately as well, meaning they'll be more focussed towards the respective set and can work more accurately.

However, due to the nature of the algorithm, this can lead to a timeout without having obtained a solution to the plan, and an error solution will be returned (Code 103). The likelihood of this happening increases with input data size.

Using the option allowUnassignedTasks enables an unassignment behaviour in the algorithm, meaning it will, if deemed necessary, refuse to assign subsets of tasks to any worker. Examples are scenarios where the only qualified workers are overloaded or there is no workers that can even carry out a task. In the output data this can be recognized by the task missing its assignment data, such as timeScheduled or travelTime. The differences to an assigned task are noted in the description for the Assigned MixedPlanner-Task. Additionally, the info section will notify of unassignment and, if possible, the reason for it.

Per default, travel from and to capacity reset locations is part of the optimization, after a reset the worker will often continue their tour closer to the reset location. Other tours might lead to or from reset locations to minimize travel from the task before reset to the reset location and vice versa from the reset location to the next task. While this behaviour is no doubt beneficial for reducing travel time/ distance, it can lead to unwanted results in use cases where a high amount of clustering is intended, since from a pure time/distance approach, it makes little sense to have a worker return to their cluster after a reset. For these cases, the option dontOptimizeResets can be set to true so that travel to and from reset locations does not get considered in the optimization anymore. Of course, the travel will still get factored into scheduled times etc, but the algorithm will no longer consider these travels as part of the optimization.

## Mixedplanner-Optimization-Parameters

The minimum optimization parameters JSON-body is an empty body. The full body looks like this:

{
"preset": 1,
"fairDistribution": 4,
"localityClustering": 2,
"shortPaths": 7,
"timeliness": 5,
"travelTimeRelax": 0,
"workerPrefs": 5,
"workerReduction": 1,
"workTimeRelax": 0,
"genderPref": 2,
"profitability": 3
}


JSON-Schema

All parameters are integer numbers $0 \leq x \leq 9$. You only need to pass the ones you want to use, all others will be implicitly set to 0.

Parameter Type Required Description
preset integer (preset type) Sets the parameters to a predefined preset (details below). Additionally specified parameters will override the preset parameters.
fairDistribution integer Distribute the tasks fairly among the workers.
localityClustering integer Build local clusters for the workers to work within if possible.
shortPaths integer Optimize the plan towards short travel paths.
timeliness integer Optimize towards satisfying the time windows.
travelTimeRelax integer Increase the travel time by introducing travel time buffers.
workerPrefs integer Try to satisfy any tasks' worker preferences.
workerReduction integer Reduce the number of necessary workers.
workTimeRelax integer Increase the time needed for a task (duration) by introducing work time buffers.
genderPref integer Try to satisfy any tasks' gender preferences. Setting this parameter to 9 will upgrade the algorithm to consider prefGender a restriction rather than merely a preference.
profitability integer Optimize towards high single-tour profitability.

The following presets are currently available (parameters not listed are set to 0):

ID Name Parameter settings
0 Eco orientied
• shortPaths: 9
• timeliness: 5
• genderPref: 4
• profitability: 9
1 Worker oriented
• fairDistribution: 9
• shortPaths: 5
• timeliness: 4
• workerPref: 4
• genderPref: 4
• profitability: 4
2 Customer oriented
• shortPaths: 2
• timeliness: 9
• workerPref: 7
• genderPref: 9
• profitability: 2
3 Fleet oriented
• shortPaths: 5
• timeliness: 2
• workerReduction: 9
• profitability: 2
4 Random The values shortPaths, timeliness are set to a random value 1 to 9. The values fairDistribution, workerPrefs, workerReduction, genderPref, profitability are set to a random value 0 to 9.

The minimum required unassigned task JSON-body looks like this:

{
"date": "2019-12-03",
"duration": 65,
"timeEarliest": "10:00",
"timeLatest": "12:00"
}


The full unassigned task JSON-body when using a GeoCoord location looks like this:

{
"externalID": "id123",
"date": "2019-12-03",
"duration": 65,
"timeEarliest": "10:00",
"timeLatest": "12:00",
"timePriority": 2,
"location": {
"lat": 50.878847,
"lng": 6.964728400000013
},
"prefWorkers": [
1,2
],
"forbWorkers": [
3,4
],
"capacity": 40,
"weight": 40,
"volume": 40,
"qualification": 3,
"categories": [
1
],
"antiCategories": [
2
],
"exchangeableCategories": [
4,5,6
],
"twinCategories": [
3
],
"desiredWorker": 1,
"initassignedWorker": 1,
"initassignedOrder": 1,
"preassignedWorker": 2,
"prefGender": 1,
1, 2
],
3
],
"revenue": 1.25,
"travelTimeExtra": 2,
"group": 2
}


The full unassigned task JSON-body when using a Location Site looks like this:

{
"externalID": "id123",
"date": "2019-12-03",
"duration": 65,
"timeEarliest": "10:00",
"timeLatest": "15:00",
"forbTimeEarliest": "12:30",
"forbTimeLatest": "12:45",
"timePriority": 2,
"locationSiteID": 1,
"prefWorkers": [
1,2
],
"antiWorkers": [
1,2
],
"forbWorkers": [
3,4
],
"capacity": 40,
"weight": 40,
"volume": 40,
"qualification": 3,
"categories": [
1
],
"antiCategories": [
2
],
"exchangeableCategories": [
4,5,6
],
"twinCategories": [
3
],
"desiredWorker": 1,
"initassignedWorker": 1,
"initassignedOrder": 1,
"preassignedWorker": 2,
"prefGender": 1,
1, 2
],
3
],
"revenue": 1.25,
"travelTimeExtra": 2,
"group": 2
}


The JSON-Schema of the unassigned task is an extension of the JSON-Schema of an abstract task.

The unassigned task is the incoming task description for the optimizer outlining the restrictions for the optimization.

Parameter Required Type Description Depends on
externalID string A string to identify the task in the solution. Cannot be used as identifier by other fields.
clientID integer A unique id to identify a client to whom different tasks can be attributed. Only tasks with clientID are considered in History evaluation.
baseScheduleTime v2.36.0 string (time) A time for identifying History-Assignments. Assignments with identical clientID and similar baseScheduleTime are associated with each other. If no baseScheduleTime is set, timeEarliest gest used instead.
date string (date) The date for the day to be planned. timeliness
duration integer The time in minutes it takes to complete this task. strict
timeEarliest string (time) The earliest possible start-time of this task. timeliness
timeLatest string (time) The latest time at which this task should be finished. timeliness
forbTimeEarliest string (time) The start of the forbidden time window. Tasks will not be carried out in the forbidden time window and will be scheduled either completely before or after it. strict
forbTimeLatest string (time) The end of the forbidden time window. Tasks will not be carried out in the forbidden time window and will be scheduled either completely before or after it. strict
timePriority integer The priority of the time window ranging from 0-5. (Default: 1)
• 0 - irrelevant
• 1 - not important (automatically extended by 30 minutes)
• 2 - more important (automatically extended by 15 minutes)
• 3 - important (no extension)
• 4 - very important (no extension)
• 5 - fixed time (no extension)
Tasks with high time priority are more likely to get scheduled inside their given time window. Tasks with time priority 0 completely ignore their given time window.
strict on value 5
location GeoCoord The geo-coordinates where the task has to be performed. Not defining a location will allow the task to be performed anywhere. Only one of location and locationSiteID may be set on each task. strict
locationSiteID integer (LocationSite) The ID of the location site which should be used as location for this task. Not defining a location will allow the task to be performed anywhere. Only one of location and locationSiteID may be set on each task. strict
description string DEPRECATED
prefWorkers Array<integer> The IDs of preferred workers. workerPrefs
antiWorkers Array<integer> The IDs of workers to which an assignment is undesirable. workerPrefs
forbWorkers Array<integer> The IDs of forbidden workers. strict
capacity number The capacity requirement of this task, which the assigned worker will need to provide. strict
weight number The weight requirement of this task, which the assigned worker will need to provide. strict
volume number The volume requirement of this task, which the assigned worker will need to provide. strict
qualification integer The minimum qualification of the employee required to perform the task (e.g. years of experience). strict
categories Array<integer> A suitable worker has to fulfill all of these categories. strict
antiCategories Array<integer> Categories of other tasks which exclude joint performance with this task. strict
exchangeableCategories Array<integer> A suitable worker has to fulfill at least one of these categories. strict
twinCategories Array<integer> The assigned worker will need to perform at least two tasks with each of these categories. strict
preassignedWorker integer The unique ID of the worker who has to take over this task. Restrictions such as qualifications, capacity, category still apply. strict
desiredWorker integer The unique ID of the worker who is desired (strong preference, not influenced to workerPrefs) to take over this task.
initassignedWorker integer The unique ID of the worker who will be initially assigned. This creates a higher likelihood of the task being assigned to this worker in the solution, especially if the initial assignment stems from a previous solution.
initassignedOrder integer The order within the initially assigned worker's tour. Requires an initassignedWorker.
prefGender integer (gender) The assigned worker needs to have this gender. strict
precedingTasks Array<integer> Tasks in this list and this task will be performed by the same worker and all tasks in list will have to be finished before this task starts. strict
predecessorTasks Array<integer> The tasks of which one has to be performed right before this task by the same worker as this task. strict
revenue number The revenue which will be achieved with this task.
travelTimeExtra integer Fixed amount of time added to this task's travel time. strict
group integer A group ID. Tasks with the same group ID get assigned to the same worker. strict
assignmentPriority TBA integer A priority for assignment (see allowUnassignedTasks) ranging 0-5.
• 0 - no preference regarding unassignment, whether or not the task is assigned does not matter and will depend solely on other factors
• 1-4 - progressively higher assignment importance
• 5 - task has to be assigned
strict on value 5

categories, antiCategories and exchangeableCategories need to be disjoint sets on each task. This means that a category appearing in categories may not appear in antiCategories or exchangeableCategories and vice versa. twinCategories represent a different set and are not affected by this restriction.

Positive numbers for capacity, volume or weight represent loading tasks while negative numbers for capacity, volume or weight represent unloading tasks.

The minimum required assigned task JSON-body looks like this:

{
"date": "2019-12-03",
"duration": 65,
"timeEarliest": "10:00",
"timeLatest": "12:00",
"timeScheduled": "11:01",
"travelTime": 3,
"travelDistance": 2.83061,
"assignedWorker": 2,
"info": "This task assignment causes negative arrival slack: -6",
"finalassignedOrder": 3
}


The full assigned task JSON-body when using a GeoCoord location looks like this:

{
"externalID": "id123",
"date": "2019-12-03",
"duration": 65,
"timeEarliest": "10:00",
"timeLatest": "15:00",
"forbTimeEarliest": "12:30",
"forbTimeLatest": "12:45",
"timePriority": 2,
"location": {
"lat": 50.878847,
"lng": 6.964728400000013
},
"prefWorkers": [
1,2
],
"antiWorkers": [
1,2
],
"forbWorkers": [
3,4
],
"capacity": 40,
"weight": 40,
"volume": 40,
"qualification": 3,
"categories": [
1
],
"antiCategories": [
2
],
"exchangeableCategories": [
4,5,6
],
"twinCategories": [
3
],
"desiredWorker": 1,
"initassignedWorker": 1,
"initassignedOrder": 1,
"preassignedWorker": 2,
"prefGender": 1,
1,2
],
3
],
"revenue": 1.25,
"travelTimeExtra": 2,
"timeScheduled": "11:01",
"travelTime": 3,
"travelDistance": 2.83061,
"assignedWorker": 2,
"info": "This task assignment causes negative arrival slack: -6",
"profit": 12.21,
"performResetBeforeAtID": 2,
"finalassignedOrder": 3,
"group": 2,
}


The JSON-Schema of the assigned task is an extension of the JSON-Schema of an abstract task.

Extension Parameter Required if assigned Required if unassigned Type Description
externalID string A string to identify the task in the solution. Cannot be used as identifier by other fields.
clientID integer A unique id to identify a client to whom different tasks can be attributed.
baseScheduleTime v2.36.0 string (time) A time for identifying History-Assignments.
date string (date) The date for the day to be planned.
duration integer The time in minutes it takes to complete this task.
timeEarliest string (time) The earliest possible start-time of this task.
timeLatest string (time) The latest time at which this task should be finished.
forbTimeEarliest string (time) The start of the forbidden time window. Tasks will not be carried out in the forbidden time window and will be scheduled either completely before or after it.
forbTimeLatest string (time) The end of the forbidden time window. Tasks will not be carried out in the forbidden time window and will be scheduled either completely before or after it.
timePriority integer The priority of the time window ranging from 0-5. (Default: 1)
• 0 - irrelevant
• 1 - not important (automatically extended by 30 minutes)
• 2 - more important (automatically extended by 15 minutes)
• 3 - important (no extension)
• 4 - very important (no extension)
• 5 - fixed time (no extension)
Tasks with high time priority are more likely to get scheduled inside their given time window. Tasks with time priority 0 completely ignore their given time window.
location GeoCoord The geo-coordinates where the task has to be performed. Not defining a location will allow the task to be performed anywhere. Only one of location and locationSiteID may be set on each task.
locationSiteID integer (LocationSite) The ID of the location site which should be used as location for this task. Not defining a location will allow the task to be performed anywhere. Only one of location and locationSiteID may be set on each task.
description string DEPRECATED
prefWorkers Array<integer> The IDs of preferred workers.
antiWorkers Array<integer> The IDs of workers to which an assignment is undesirable.
forbWorkers Array<integer> The IDs of forbidden workers.
capacity number The capacity requirement of this task, which the assigned worker will need to provide.
weight number The weight requirement of this task, which the assigned worker will need to provide.
volume number The volume requirement of this task, which the assigned worker will need to provide.
qualification integer The minimum qualification of the employee required to perform the task (e.g. years of experience).
categories Array<integer> A suitable worker has to fulfill all of these categories.
antiCategories Array<integer> Categories of other tasks which exclude joint performance with this task.
exchangeableCategories Array<integer> A suitable worker has to fulfill at least one of these categories.
twinCategories Array<integer> The assigned worker will need to perform at least two tasks with each of these categories.
preassignedWorker integer The unique ID of the worker who has to take over this task. Restrictions such as qualifications, capacity, category still apply.
desiredWorker integer The unique ID of the worker who is desired (strong preference, not influenced to workerPrefs) to take over this task.
initassignedWorker integer The unique ID of the worker who will be initially assigned. This creates a higher likelihood of the task being assigned to this worker in the solution, especially if the initial assignment stems from a previous solution.
initassignedOrder integer The order within the initially assigned worker's tour.
prefGender integer (gender) The assigned worker needs to have this gender.
precedingTasks Array<integer> Tasks in this list and this task will be performed by the same worker and all tasks in list will have to be finished before this task starts.
predecessorTasks Array<integer> The tasks of which one has to be performed right before this task by the same worker as this task.
revenue number The revenue which will be achieved with this task.
travelTimeExtra integer Fixed amount of time added to this task's travel time.
group integer A group ID. Tasks with the same group ID get assigned to the same worker.
assignmentPriority TBA integer A priority for assignment (see allowUnassignedTasks) ranging 0-5.
• 0 - no preference regarding unassignment, whether or not the task is assigned does not matter and will depend solely on other factors
• 1-4 - progressively higher assignment importance
• 5 - task has to be assigned
timeScheduled string (time) The predicted/planned time to start this task by the assigned worker.
travelTime integer The time in minutes needed to travel from the previous task to this task. For a more detailed explanation see the table below.
travelDistance number The distance in km needed to travel from the previous task to this task.
assignedWorker integer The unique ID of the assigned worker who will perform this task.
profit number The profit the task creates ($revenue - costs$).
performResetBeforeAtID integer The id of the location site which will be visited to reset capacity/weight/volume before this task starts.
finalassignedOrder integer The order number within the assigned tour.

The value travelTime also includes travel times to and from a capacity reset location, as well as the reset duration, if a reset is performed directly before this task. Depending on the integrateDurationExtensions settings, it may also include travelTimeExtra and the travel time multiplicator based on travelTimeRelax. The following table provides the calculations in each case:

integrateDurationExtensions set to false $travelTime = max( actualTravelTime,$ travelTimeMin $)$ $travelTime = max( travelTimeToResetLocation,$ travelTimeMin $) +$ capacityResetDuration $+ max( travelTimeFromResetLocation,$ travelTimeMin $)$
integrateDurationExtensions set to true $travelTime = max( actualTravelTime,$ travelTimeMin $) * travelTimeMultiplicator +$ travelTimeExtra $travelTime = max( travelTimeToResetLocation,$ travelTimeMin $) * travelTimeMultiplicator +$ capacityResetDuration $+ max( travelTimeFromResetLocation,$ travelTimeMin $) * travelTimeMultiplicator +$ travelTimeExtra

In case no actual travel happens (for instance identical locations of consecutive tasks, no location or no startLocation/ endLocation ) the values $max( actualTravelTime, travelTimeMin )$ and similar are zero.

Please note that the formula changes with integrateDurationExtensions set to true influence only output values, since the setting does not change internal calculations or the algorithm result (see MixedPlanner-Metainformation for more details).

## Unassigned MixedPlanner-Worker

The minimum required JSON-body of an unassigned worker when using GeoCoord locations looks like this:

{
"workerID": 1,
"shiftStart": "06:00",
"shiftEnd": "14:00",
"shiftDate": "2019-12-03"
}


The full JSON-body of an unassigned worker when using GeoCoord locations and dontAlter looks like this:

{
"workerID": 1,
"externalID": "id123",
"shiftStart": "06:00",
"shiftEnd": "14:00",
"shiftDate": "2019-12-03",
"startLocation":{
"lat": 50.878847,
"lng": 6.964728400000013
},
"endLocation":{
"lat": 50.878847,
"lng": 6.964728400000013
},
"shiftPriority": 2,
"capacity": 20.5,
"capacityInitial": 10.1,
"capacityResetLocationSiteIDs": [
1,2
],
"capacityResetDuration": 10,
"maxResets": 2,
"volume": 12.5,
"volumeInitial": 5.5,
"weight": 2.5,
"weightInitial": 1.0,
"finalCapacityResetThreshold": 12.1,
"finalVolumeResetThreshold": 5.5,
"finalWeightResetThreshold": 1.5,
"qualification": 1,
"categories": [
4,5
],
"prefCategories": [
6
],
"breakStartEarliest": "12:21",
"breakEndLatest": "13:00",
"breakDuration": 10,
"vehicleType": 1,
"gender": 1,
"costsPerKM": 0.05,
"costsPerMinute": 1.23,
"costsInitial": 234.56,
"maxDesiredTotalDistance": 100.0,
"maxDesiredSingleDistance": 5.0,
"dontAlter": true,
"dontVary": true
}


The full JSON-body of an unassigned worker when using Location Sites and dontVary looks like this:

{
"workerID": 1,
"externalID": "id123",
"shiftStart": "06:00",
"shiftEnd": "14:00",
"shiftDate": "2019-12-03",
"startLocationSiteID": 4,
"endLocationSiteID": 5,
"shiftPriority": 2,
"capacity": 20.5,
"capacityInitial": 10.1,
"capacityResetLocationSiteIDs": [
1,2
],
"capacityResetDuration": 10,
"maxResets": 2,
"volume": 12.5,
"volumeInitial": 5.5,
"weight": 2.5,
"weightInitial": 1.0,
"finalCapacityResetThreshold": 12.1,
"finalVolumeResetThreshold": 5.5,
"finalWeightResetThreshold": 1.5,
"qualification": 1,
"categories": [
4,5
],
"prefCategories": [
6
],
"desiredCategory": 12,
"breakStartEarliest": "12:21",
"breakEndLatest": "13:00",
"breakDuration": 10,
"vehicleType": 1,
"gender": 1,
"costsPerKM": 0.05,
"costsPerMinute": 1.23,
"costsInitial": 234.56,
"maxDesiredTotalDistance": 100.0,
"maxDesiredSingleDistance": 5.0,
"dontVary": true,
"dontAlter": true
}


The JSON-Schema of the unassigned worker is an extension of the JSON-Schema of an abstract worker.

The worker has both optional and required parameters as marked in the following table.

Parameter Required Type Description Depends on
workerID integer The unique ID of the worker. If a worker has multiple shifts this day, there can be multiple respective worker-objects with this (same) ID.
externalID string A string to identify the worker in the solution. Cannot be used as identifier by other fields.
startLocation GeoCoord The location where the worker begins their working day. Only one of startLocation and startLocationSiteID may be set on any given worker. strict
startLocationSiteID integer (LocationSite) The id of the location where the worker begins their working day. Only one of startLocation and startLocationSiteID may be set on each worker. strict
endLocation GeoCoord The location where the worker finishes their working day. Only one of endLocation and endLocationSiteID may be set on any given worker. strict
endLocationSiteID integer (LocationSite) The id of the location where the worker finishes their working day. Only one of endLocation and endLocationSiteID may be set on each worker. strict
shiftDate string (date) The date of this shift (should match the date of the submitted tasks in general for daily plannings).
shiftStart string (time) The time this shift starts.
shiftEnd string (time) The time this shift ends.
shiftPriority integer The priority to keep the defined shift start and end times ranging from 0-3: irrelevant, neutral, important, very important. The default value is 1 (neutral).
hoursPerWeek integer DEPRECATED
capacity number The available capacity (positive value) of the worker or their vehicle. strict
capacityInitial number The initially occupied capacity (positive value) on shift start of this worker or their vehicle.
capacityResetLocationSiteIDs Array<integer> (LocationSite) The ids of location sites at which capacity/volume/weight can be reset. strict
capacityResetDuration integer The time in minutes needed for a capacity reset (Default: 0). Only allowed in combination with capacity reset locations. strict
maxResets v2.34.0 integer The maximum number of allowed capacity resets on this worker. strict
volume number The available volume (positive value) of the worker or their vehicle. strict
volumeInitial number The initially loaded volume (positive value) on shift start of this worker or their vehicle.
weight number The weight (positive value) the worker or their vehicle is able to handle. strict
weightInitial number The initially loaded weight (positive value) on shift start of this worker or their vehicle.
finalCapacityResetThreshold number The used capacity threshold (positive value) above which a reset will be enforced before ending the shift.
finalVolumeResetThreshold number The used volume threshold (positive value) above which a reset will be enforced before ending the shift.
finalWeightResetThreshold number The used weight threshold (positive value) above which a reset will be enforced before ending the shift.
qualification integer The qualification of the worker. Workers can perform any task with equal or lower qualification requirement. strict
categories Array<integer> The categories the workers can take over. strict
desiredCategory integer The worker has a strong preference towards tasks with this category.
prefCategories Array<integer> Tasks with any of these categories will be preferred by this worker. workerPrefs
breakStartEarliest string (time) The earliest start of the break a worker has to do. strict, unless tightSchedule is set to true
breakEndLatest string (time) The latest end of the break a worker has to do.
breakDuration integer The duration in minutes of the break. strict
vehicleType integer (vehicle) The vehicle type used by this worker.
gender integer (gender) The gender type of the worker.
costsPerKM number The costs per km for this worker (e.g. fuel costs). profitability
costsPerMinute number The costs per minute working time (carrying out tasks) for this worker (e.g. monthly salary converted to minutes). profitability
costsInitial number Costs that occur if there is at least one task assigned to the worker. profitability
maxDesiredTotalDistance number The maximum total travel distance per shift that a worker wants to perform (if possible).
maxDesiredSingleDistance number The maximum travel distance for each individual travel that a worker wants to perform (if possible).
dontVary boolean Lock existing task assignment, see below for details. strict
dontAlter boolean Lock existing task order, see below for details. strict

When no startLocation or startLocationSiteID is given, the shift of the worker will start at the first assigned task with no travel time or distance to it. This can be used in situations where workers start their day at home and any travel time to their first client does not count as working time. (By analogy: endLocation/endLocationSiteID)

A worker with dontVary set to true is "fixed" for the optimizer, meaning they get assigned all tasks (and only those tasks) that have this worker set as preassignedWorker or initassignedWorker in the order of initassignedOrder. That also means that initassignedOrder is required for these tasks. Travel times, resets, etc still get calculated on both worker and task and the worker and its tasks will be considered in MixedPlanner-Statistics and MixedPlanner-Info.

Workers with dontAlter set to true behave similarly to workers with dontVary. The only difference is that a dontVary-worker cannot get assigned more tasks than specified in the input data, a dontAlter-worker will be assigned all tasks that have this worker as initassignedWorker or preassignedWorker, but can also have other tasks assigned. While the preassigned/initassigned tasks will be in order of initassignedOrder, other tasks can be inserted before, between or after those tasks; if there is no initassignedOrder set, the task will be ignored. Every other behavior and requirement is exactly as in dontVary.

## Assigned MixedPlanner-Worker

The assigned worker - after the performed optimization - extends the unassigned worker with information about when their break is scheduled (when one was given). Additionally some information about the worker can be added in the info field.

The minimum required JSON-body of an assigned worker when using GeoCoord locations and dontAlter looks like this:

{
"workerID": 1,
"shiftStart": "06:00",
"shiftEnd": "14:00",
"shiftDate": "2019-12-03",
"travelHomeTime": 2,
"travelHomeDistance": 1.123,
}


The full JSON-body of an assigned worker when using GeoCoord locations and dontAlter looks like this:

{
"workerID": 1,
"externalID": "id123",
"shiftStart": "06:00",
"shiftEnd": "14:00",
"shiftDate": "2019-12-03",
"startLocationSiteID": 4,
"endLocationSiteID": 5,
"shiftPriority": 2,
"capacity": 20.5,
"capacityInitial": 10.1,
"capacityResetLocationSiteIDs": [
1,2
],
"capacityResetDuration": 10,
"volume": 12.5,
"volumeInitial": 5.5,
"weight": 2.5,
"weightInitial": 1.0,
"finalCapacityResetThreshold": 12.1,
"finalVolumeResetThreshold": 5.5,
"finalWeightResetThreshold": 1.5,
"qualification": 1,
"categories": [
4,5
],
"prefCategories": [
6
],
"desiredCategory": 12,
"breakStartEarliest": "12:21",
"breakEndLatest": "13:00",
"breakDuration": 10,
"vehicleType": 1,
"gender": 1,
"costsPerKM": 0.05,
"costsPerMinute": 1.23,
"costsInitial": 234.56,
"maxDesiredTotalDistance": 100.0,
"maxDesiredSingleDistance": 5.0,
"dontVary": true,
"info": "",
"breakScheduled": "12:30",
"travelHomeTime": 2,
"travelHomeDistance": 1.123,
"performFinalResetAtID": 1,
"dontAlter": true
}


The JSON-Schema of the assigned worker is an extension of the JSON-Schema of an abstract worker.

Extension Parameter Required Type Description
workerID integer The unique ID of the worker. If a worker has multiple shifts this day, there can be multiple respective worker-objects with this (same) ID.
externalID string A string to identify the worker in the solution. Cannot be used as identifier by other fields.
startLocation GeoCoord The location where the worker begins their working day. Only one of startLocation and startLocationSiteID may be set on any given worker.
startLocationSiteID integer (LocationSite) The id of the location where the worker begins their working day. Only one of startLocation and startLocationSiteID may be set on any given worker.
endLocation GeoCoord The location where the worker finishes their working day. Only one of endLocation and endLocationSiteID may be set on any given worker.
endLocationSiteID integer (LocationSite) The id of the location where the worker finishes their working day. Only one of endLocation and endLocationSiteID may be set on any given worker.
shiftDate string (date) The date of this shift (should match the date of the submitted tasks in general for daily plannings).
shiftStart string (time) The time this shift starts.
shiftEnd string (time) The time this shift ends.
shiftPriority integer The priority to keep the defined shift start and end times ranging from 0-3: irrelevant, neutral, important, very important. The default value is 1 (neutral).
hoursPerWeek integer DEPRECATED
capacity number The available capacity (positive value) of the worker or their vehicle.
capacityInitial number The initially occupied capacity (positive value) on shift start of this worker or their vehicle.
capacityResetLocationSiteIDs Array<integer> (LocationSite) The ids of location sites at which capacity/volume/weight can be reset.
capacityResetDuration integer The time in minutes needed for a capacity reset (Default: 0). Only allowed in combination with capacity reset locations.
maxResets v2.34.0 integer The maximum number of allowed capacity resets on this worker.
volume number The available volume (positive value) of the worker or their vehicle.
volumeInitial number The initially loaded volume (positive value) on shift start of this worker or their vehicle.
weight number The weight (positive value) the worker or their vehicle is able to handle.
weightInitial number The initially loaded weight (positive value) on shift start of this worker or their vehicle.
finalCapacityResetThreshold number The used capacity threshold (positive value) above which a reset will be enforced before ending the shift.
finalVolumeResetThreshold number The used volume threshold (positive value) above which a reset will be enforced before ending the shift.
finalWeightResetThreshold number The used weight threshold (positive value) above which a reset will be enforced before ending the shift.
qualification integer The qualification of the worker. Workers can perform any task with equal or lower qualification requirement.
categories Array<integer> The categories the workers can take over.
desiredCategory integer The worker has a strong preference towards tasks with this category.
prefCategories Array<integer> Tasks with any of these categories will be preferred by this worker.
breakStartEarliest string (time) The earliest start of the break a worker has to do.
breakEndLatest string (time) The latest end of the break a worker has to do.
breakDuration integer The duration in minutes of the break.
vehicleType integer (vehicle) The vehicle type used by this worker.
gender integer (gender) The gender type of the worker.
costsPerKM number The costs per km for this worker (e.g. fuel costs).
costsPerMinute number The costs per minute working time (carrying out tasks) for this worker (e.g. monthly salary converted to minutes).
costsInitial number Costs that occur if there is at least one task assigned to the worker.
maxDesiredTotalDistance number The maximum total travel distance per shift that a worker wants to perform (if possible).
maxDesiredSingleDistance number The maximum travel distance for each individual travel that a worker wants to perform (if possible).
dontVary boolean Lock existing task assignment.
dontAlter boolean Lock existing task order.
breakScheduled string (time) When the break of the worker is scheduled, is just passed when a break was given.
info string Some textual information about the worker, e.g. for delays.
travelHomeTime integer Time in minutes needed to get to the end location from the last task. For a more detailed explanation see the table to travelTime.
travelHomeDistance number Distance in km between last task and the end location.
performFinalResetAtID integer (LocationSite) The id of the location site at which a capacity/ weight/ volume reset was performed after the last task and before returning to a depot.

If an Unassigned MixedPlanner-Worker does not already contain the data breakStartEarliest, breakEndLatest or breakDuration, integrateGermanBreakRegulations is set to true and the worker has to take a break due to their shift length and German law, the automatically generated break data regarding these values will be added to the Assigned MixedPlanner-Worker as extension. If these values were already written in the Unassigned MixedPlanner-Worker, they do not get changed in the Assigned MixedPlanner-Worker. If the values were not written in the Unassigned MixedPlanner-Worker but integrateGermanBreakRegulations is set to false or German law does not require a break for this shift, no data will be added.

## MixedPlanner-History

An example for MixedPlanner-History looks like this

{
{
"clientID": 100,
"scheduling": [
{
"date": "2000-01-01",
"baseScheduleTime": "00:00",
"baseWorker": 1,
"timeScheduled": "00:00",
"assignedWorker": 0,
"timeVariance": 0,
"timePriority": 0,
"timeScheduledAutomatically": "00:00",
"assignedWorkerAutomatically": 0,
"actualStartTime": "00:00",
"actualWorker": 0,
},
...
]
},
...
],
"workers": [
{
"workerID": 0,
"gender": 1,
"qualification": 1,
"categories": [ 1,2 ]
},
...
]
}


The JSON-schema is called history

Parameter Required Type Description
tasks Array All tasks that are connected to MixedPlanner-Tasks in the optimization either by taskID or clientID.
workers Array Workers that are not included in the optimization but are referenced in MixedPlanner-History-Tasks, e.g. as assignedWorker.

### MixedPlanner-History-Assignment

The minimum required JSON-body of a MixedPlanner-History-Assignment looks like this

{
"date": "2000-01-01"
}


The full JSON-body of a MixedPlanner-History-Assignment looks like this

{
"date": "2000-01-01",
"baseScheduleTime": "00:00",
"baseWorker": 1,
"timeScheduled": "00:00",
"assignedWorker": 0,
"timeVariance": 0,
"timePriority": 0,
"timeScheduledAutomatically": "00:00",
"assignedWorkerAutomatically": 0,
"actualStartTime": "00:00",
"actualWorker": 0,
}


The JSON-schema is called History-Assignment

Parameter Required Type Description
date string (Date) Date this assignment was on.
baseScheduleTime string (time) A baseline orientation when the corresponding task was supposed to be scheduled.
baseWorker integer A baseline orientation for the worker to be assigned.
timeScheduled string (time) The time the corresponding task was scheduled (meaning the time the final plan had this task scheduled on, not to be confused with actualStartTime)
assignedWorker integer The worker the corresponding task was assigned to in the final planned version.
timeVariance integer The time variance the corresponding task was scheduled with at the time.
timePriority integer The timePriority the corresponding task was scheduled with at the time.
timeScheduledAutomatically string (time) The time the corresponding task was scheduled on by the optimizer at the time.
assignedWorkerAutomatically integer The worker the corresponding task was assigned to by the optimizer at the time.
actualStartTime string (time) The time the task was actually started, for instance as determined by mobile tracking.
actualWorker integer The worker the task was actually carried out by, for instance as determined by mobile tracking.

The JSON-body of a MixedPlanner-History-Task looks like this

{
"clientID": 100,
"scheduling": [
{
"date": "2000-01-01",
"baseScheduleTime": "00:00",
"baseWorker": 1,
"timeScheduled": "00:00",
"assignedWorker": 0,
"timeVariance": 0,
"timePriority": 0,
"timeScheduledAutomatically": "00:00",
"assignedWorkerAutomatically": 0,
"actualStartTime": "00:00",
"actualWorker": 0,
},
...
]
}


Parameter Required Type Description
scheduling Array All considered historical assignments of this task.

### MixedPlanner-History-Worker

The minimum required JSON-body of a MixedPlanner-History-Worker looks like this

{
"workerID": 0
}


The full JSON-body of a MixedPlanner-History-Worker looks like this

{
"workerID": 0,
"gender": 1,
"qualification": 1,
"categories": [ 1,2 ]
}


The JSON-schema is called History-Worker

Parameter Required Type Description
workerID integer Unique ID of a worker that is not present in the input data
gender GenderType See MixedPlanner-Worker.
qualification integer See MixedPlanner-Worker.
categories Array<integer> See MixedPlanner-Worker.

## MixedPlanner-Statistics

The JSON-body of statistics for a calculated plan looks like this:

{
"configuration": [
{
"label": "Short Path",
"value": 0.777778
},
...
],
{
"workerID": 1,
"values": [
0,0,0,0,0,0,0.97,1,0.5,0.17,0.07,0.5,0,0,0,0,0,0,0,0,0,0,0
]
},
...
],
"travelTimes": [
{
"workerID": 1,
"time": 51
},
...
],
"travelDistances": [
{
"workerID": 1,
"distance": 32.1
},
...
],
{
"workerID": 1,
"time": 145
},
...
],
{
"workerID": 1,
"busyness": 0.3
},
...
],
"travelBusyness": [
{
"workerID": 1,
"busyness": 0.4
},
...
],
"workTimeDistribution": [
{
"type": "Working Time",
"time": 716
},
...
],
"preferredWorkers": [
{
"type": "matched",
"count": 12
},
{
"type": "unmatched",
"count": 7
}
],
"preferredGender": [
{
"type": "matched",
"count": 3
},
{
"type": "unmatched",
"count": 4
}
],
"desiredWorkers": [
{
"type": "matched",
"count": 9
},
{
"type": "unmatched",
"count": 13
}
],
"vehicleTypeDistances": [
{
"vehicleType": 0,
"distance": 9.123
},
{
"vehicleType": 3,
"distance": 4.2
},
...
],
"impact": [
{
"label": "Anticategories",
"value": 0.123
},
...
],
"routeLength": 146.841095,
"onTime": 96,
"planProfitability": 150.12
}


JSON-Schema

Parameter Type Required Description
configuration Array<Object<label: string, value: number>> The applied optimizer configurations mapped in ranges from $0.0$ to $1.0$.
workload Array<Object<workerID: integer, values: Array<number>>> The workload per worker for each hour of the day in ranges from $0.0$ to $1.0$ (worked 0 min to worked 60 min).
travelTimes Array<Object<workerID: integer, time: integer>> The total time in minutes each worker spends traveling. Capacity reset durations are excluded!
travelDistances Array<Object<workerID: integer, distance: number>> The distance in km each worker drives for this plan.
taskTimes Array<Object<workerID: integer, time: integer>> The time in minutes each worker spends on working on tasks (sum of durations). Previously called careTime.
taskBusyness Array<Object<workerID: integer, busyness: number>> Proportion of working time to shift time ($0.0$ to $1.0$).
travelBusyness Array<Object<workerID: integer, busyness: number>> Proportion of travel time to shift time ($0.0$ to $1.0$). Capacity reset durations are excluded!
workTimeDistribution Array<Object<type: string, time: integer>> The time in minutes spent on different actions summed up. Capacity reset durations are excluded!
preferredWorkers Array<Object<type: string, count: integer>> Sum of fulfilled (type: matched) as well as unfulfilled (type: unmatched) worker preferences.
preferredGender Array<Object<type: string, count: integer>> Sum of fulfilled (type: matched) as well as unfulfilled (type: unmatched) gender preferences.
desiredWorkers Array<Object<type: string, count: integer>> Sum of tasks assigned to desired workers (type: matched) and sum of tasks assigned to another worker (type: unmatched).
unassignedTaskIDs TBA Array<integer> taskIDs of all tasks that were not assigned during optimization. Only included if not empty.
unassignableTaskIDs TBA Array<integer> taskIDs of all tasks that were not assigned during optimization because there is no assignment possible (meaning they would fail input validation if unassigned tasks were not allowed). Only included if not empty.
impact Array<Object<label: string, value: number>> A number based summary of calculation results. See below for details.
vehicleTypeDistances Array<Object<vehicleType: VehicleType, distance: number>> A number based summary of total distance for each VehicleType.
routeLength number The driven distance in km summed up over all workers.
onTime integer Percentage for tasks scheduled perfectly inside the desired time windows ($0$ to $100$).
planProfitability number The profitability this plan archives based on worker costs and task revenues.

The array configuration contains the following fields. They are translated based on the language setting and are all required:

German label English label
Kurze Wege Short Path
Arbeiterpräferenzen Worker Preferences
Faire Verteilung Fair Distribution
Clustering Clustering
Pünktlichkeit Timeliness
Weniger Arbeiter Worker Reduction
Reisezeit Travel Time
Arbeitszeit Working Time
Geschlechterpräferenzen Gender Preferences
Profitabilität Profitability

The array workTimeDistribution contains the following fields. They are translated based on the language setting and are all required:

German type English type
Arbeitszeit Working Time
Pausenzeit Break Time
Fahrzeit Travel Time
Schichtzeit Shift Time
Puffer Buffer

The array impact contains all restriction types and gives a percentage (0.0-1.0) evaluation of each restriction's final influence on the algorithmic optimization and plan result. This can be used to detect logical problems in the input data, i.e. too restrictive time windows, large travel times or a large amount of worker preferences that just cannot be fulfilled. However, please note that if a restriction is listed in impact with a value greater zero, it does not mean that there even is a way to erase its impact. For instance, travel values will always be featured unless the total amount of travel time is zero or the shortPaths option is set to zero.

The following fields are getting written in impact. They get translated based on the language setting and are all optional and only set if greater zero.:

German label English label
Anti-Kategorien Anticategories
Pausen Breaks
Wunschmitarbeiter Desired workers
Ausgeglichener Plan Fair distribution
Geschlechterpräferenz Gender preference
Gruppierung Groups
Initiale Kosten Initial costs
Maximale Fahrtstrecke Maximum travel distance
Multischicht Multishift
Ungültige Zuweisung Invalid assignment
Kategoriepräferenz Preferred category
Mitarbeiterpräferenz Preferred worker
Anti-Mitarbeiter Antiworker
Arbeitszeitkosten Working time costs
Schichtzeitverletzungen Shift time violations
Fahrtkosten Travel costs
Twin-Kategorien Twin categories
Mitarbeiterreduzierung Worker reduction
Wunschkategorie Desired category
Nicht-erbrachter Ertrag Missing revenue
Präferenz-Wunschzuweisung Kombination Preference-Desired combination
Kapazitäten v2.30.0 Capacities v2.30.0

## MixedPlanner-Info

The JSON-body of info for a calculated plan with German language settings looks like this:

{
"text": "Alle Aufgaben wurden valide den Mitarbeitern zugewiesen!",
"balance": "4 Mitarbeiter sind eingeplant\n6,2 Aufgaben durchschnittlich (pro Mitarbeiter)\n1,2 Aufgaben Abweichung von der durchschnittlichen Aufgabenzahl (pro Mitarbeiter)\nAufgaben- und Reisezeiten in Summe: 886 Minuten\nSchichtzeiten in Summe: 1860 Minuten\nAuslastung (netto): 47,6%",
"dist": "146,8 km auf der Straße",
"pref": "12 Aufträge werden von einem gewünschten Mitarbeiter durchgeführt, bei 7 Aufträgen war dies leider nicht sinnvoll oder möglich",
"relax": "Aufträge:\n\nPrognostizierte kurze Verspätungen [5-30 Minuten] (4%):\n200, \n\nPrognostizierte Verspätungen [über 30 Minuten] (0%):\n\n\nDie anderen 24 Aufgaben (96%) werden pünktlich erreicht!\n\nSchichten:\nAlle Mitarbeiterschichten können eingehalten werden.",
"time": "170 Minuten auf der Straße\n42,5 Minuten auf der Straße durchschnittlich (pro Mitarbeiter)\n9,0 Minuten Reisezeitvarianz (pro Mitarbeiter)",
"feasible": false,
"constructionSites": [
{
"constructionSiteID": 666,
"startDate": "2020-07-23",
"endDate": "2020-07-25",
"startPoint": {
"lat": 48.17083,
"lng": 11.3292
},
"endPoint": {
"lat": 48.16774,
"lng": 11.33253
},
"info": "Waldstraße gesperrt 2020"
},
...
]
}


JSON-Schema

Parameter Required Type Description
text string Some general information about the plan. Contains warnings if any "hard" constraints could not be kept.
dist string Distance in km driven by the workers.
pref string Information about preferred workers matches.
relax string Information about delayed tasks grouped by delay amount: 5-30 minutes, 30+ minutes. Information about exceeded worker shifts.
time string Total and average travel time. Capacity reset durations are excluded!
feasible boolean Set to false if certain input requirements (capacity, categories, qualifications, shifts, time windows with high timePriority, ...) could not be kept in the final solution.
constructionSites Array<Construction Site> A list of construction sites in close proximity to the calculated routes.

All text in text, balance, dist, pref, relax, time gets translated based on language setting.

## Travel Override

Introduced in: v2.31.0

{
"sparse": [
{
"vehicleTypes": [0,2],
"sourceIDs": [12,13,1,12],
"targetIDs": [14,11,12,1],
"travelTime": [3,4,1,1],
"travelDistance": [2.83,1.5,2.01,3.12]
},
{
"vehicleTypes": [1],
"sourceIDs": [12,13,1,12],
"targetIDs": [14,11,12,1],
"travelTime": [3,4,1,1],
"travelDistance": [2.83,1.5,2.01,3.12]
},
...
],
"dense": [
{
"travelTime": [0,2,3,4,0,2,12,5,0],
"travelDistance": [0,1.123,2.123,3.456,0,4.5,2.123,10.11,4.9,0],
"vehicleTypes": [0,3]
},
{
"travelTime": [0,2,3,4,0,2,12,5,0],
"travelDistance": [0,1.123,2.123,3.456,0,4.5,2.123,10.11,4.9,0],
"vehicleTypes": [2]
},
...
]
}


JSON-Schema

The base schema consists of a single dense and/or a single sparse array, but at least one element:

Parameter Required Type Description
dense Array Dense travel override data.
sparse Array Sparse travel override data.

A single entry in the dense array looks like this: JSON-Schema

Parameter Required Type Description
vehicleTypes Array<VehicleType> All vehicle types this override is relevant for.
travelTime Array<integer> A row-concatenated matrix where $m(i,j) = travelTime($LocationSiteID i to LocationSiteID j$)$.
travelDistance Array<number> A row-concatenated matrix where $m(i,j) = travelDistance($LocationSiteID i to LocationSiteID j$)$.

Example: The travelTime array [0,2,3,4,0,2,12,5,0] translates to the following 3x3 matrix:

0 2 3
4 0 2
12 5 0

A single entry in the sparse array looks like this: JSON-Schema

Parameter Required Type Description
vehicleTypes Array<VehicleType> All vehicle types this override is relevant for.
sourceIDs Array<integer> Start LocationSiteID.
targetIDs Array<integer> End LocationSiteID.
travelTime Array<integer> Travel time for the travel between source and target at the repective position in the array.
travelDistance Array<number> Travel distance for the travel between source and target at the repective position in the array.
• In the text above, LocationSiteID refers to locationSiteID.
• Entries in travelTime and travelDistance are considered "not set" if they are either 0 or -1 and thus will not be used to override algorithm calculations.
• Travel from or to LocationSiteIDs out of bounds (dense)/ Travel not specified in data (sparse) will be considered exactly like unset data

# Definition of ShiftPlanner-Types

## ShiftPlanner-Metainformation

The minimum required JSON-body of metainformation looks like this:

{
"dateFrom": "2019-12-03",
"dateTo": "2019-12-03",
"resCategory": false,
"resQualification": false
}


The full JSON-body of metainformation looks like this:

{
"dateFrom": "2019-12-03",
"dateTo": "2019-12-03",
"resCategory": false,
"resQualification": false,
"accuracyMode": 1.0,
"outputLanguage": 1,
3,5,6
],
"enablePlanSplitting": false,
"followBiorhythm": true
}


JSON-Schema (TODO)

Parameter Type Required Description
dateFrom string (date) Planning horizont start.
dateTo string (date) Planning horizont end.
resCategory boolean Activate/Deactivate whether category types should be considered in the optimization.
resQualification boolean Activate/Deactivate whether qualifications should be considered in the optimization.
accuracyMode number Manages a solution refinement process. An accuracy > 0.0 can improve the solution significantly but will take longer to calculate, effects increase with higher accuracyMode. Default: 1.0
outputLanguage integer (languagetype) Defines which language should be used in the output. Default: German
minQualificationOfTaskCoverage integer At each minute between the earliest shiftStart of any ShiftPlanner-Worker and latest shiftEnd of any ShiftPlanner-Worker there shall be least one ShiftPlanner-Worker of this qualification or higher performing a task.
omnipresentCategoriesOfTaskCoverage Array<integer> For each of these categories, at each minute between the earliest shiftStart of any ShiftPlanner-Worker and latest shiftEnd of any ShiftPlanner-Worker there shall be least one ShiftPlanner-Worker with the category performing a task.
enablePlanSplitting boolean Enables splitting the plan into disjunct plan parts. See below for details. (Default: true)
allowUnassignedTasks boolean Enables unassigned tasks for the optimizer. See below for details. (Default: false)
followBiorhythm boolean Tasks shall be spaced out so that there is at least a 24h time span between the start of consecutive tasks on the same worker.

The options res* describe which fields from the dataset should be taken into account. More precisely those are:

Using the enablePlanSplitting can be benefitial if your input data contains clearly separateable sets of data, meaning you can create sets of workers and tasks, which can never be assigned to or carry out a task/worker from a different set than its own. In this case the option allows the algorithm to simplify the problem by solving each set separately. Additionally, any automatic input data modifications will be applied separately as well, meaning they'll be more focussed towards the respective set and can work more accurately.

However, due to the nature of the algorithm, this can lead to a timeout without having obtained a solution to the plan, and an error solution will be returned (Code 103). The likelihood of this happening increases with input data size.

Using the option allowUnassignedTasks enables an unassignment behaviour in the algorithm, meaning it will, if deemed necessary, refuse to assign subsets of tasks to any worker. Examples are scenarios where the only qualified workers are overloaded or there is no workers that can even carry out a task. In the output data this can be recognized by the task missing its assignment data, such as timeScheduled or finalassignedOrder. The differences to an assigned task are noted in the description for the Assigned ShiftPlanner-Task. Additionally, the info section will notify of unassignment and, if possible, the reason for it.

## ShiftPlanner-Optimization-Parameters

The minimum optimization parameters JSON-body is an empty body. The full body looks like this:

{
"preset": 1,
"fairDistribution": 4,
"timeliness": 5,
"workerPrefs": 5,
"teamPrefs": 5,
"worktimePrefs": 5,
"workerReduction": 1,
"genderPref": 2,
"profitability": 3
}


JSON-Schema (TODO)

All parameters are integer numbers between 0 and 9 (inclusive). You only need to pass the ones you want to use, the other will be implicitly set to 0.

Parameter Type Required Description
preset integer (preset type) Sets the parameters to a predefined preset (details below). Parameters specified in the json-body will override the preset.
fairDistribution integer Distribute the tasks fairly among the workers.
timeliness integer Optimize towards satisfying the time windows.
workerPrefs integer Try to satisfy the workers' preferences.
teamPrefs integer Try to satisfy preferences in relations between workers.
worktimePrefs integer Try to satisfy worktime related restrictions.
workerReduction integer Reduce the number of necessary workers.
genderPref integer Try to satisfy any tasks' gender preferences. Setting this parameter to 9 will upgrade the algorithm to consider prefGender a restriction rather than merely a preference.
profitability integer Optimize towards high single-worker profitability.

The following presets are currently available (parameters not listed are set to 0):

ID Name Parameter settings
TBA

The minimum required JSON-body of an unassigned task looks like this:

{
"date": "2019-12-03",
"duration": 240,
"timeEarliest": "06:00",
"timeLatest": "12:00"
}


The full JSON-body of an unassigned task looks like this:

{
"externalID": "id123",
"date": "2019-12-03",
"duration": 240,
"timeEarliest": "06:00",
"timeLatest": "12:00",
"timePriority": 2,
"prefWorkers": [
1,2
],
"antiWorkers": [
5,6
],
"forbWorkers": [
3,4
],
"qualification": 3,
"categories": [
1
],
"exchangeableCategories": [
2,4
],
"preassignedWorker": 2,
"desiredWorker": 2,
"prefGender": 1,
1,2
],
1,2
],
"group": 2,
"groupOrder": 3,
"revenue": 2.123,
"assignmentPriority": 2
}


The JSON-Schema of the unassigned shiftplanner task (TODO) is an extension of the JSON-Schema of an abstract task.

The unassigned task is the incoming task description for the optimizer outlining the restrictions for the optimization.

Parameter Required Type Description Depends on
externalID string A string to identify the task in the solution. Cannot be used as identifier by other fields.
date string (date) The date for the day to be planned. timeliness
duration integer The time in minutes it takes to complete this task. strict
timeEarliest string (time) The earliest possible start-time of this task. timeliness
timeLatest string (time) The latest time at which this task should be finished. timeliness
timePriority integer The priority of the time window ranging from 0-5. (Default: 1)
• 0 - irrelevant
• 1 - not important (automatically extended by 30 minutes)
• 2 - more important (automatically extended by 15 minutes)
• 3 - important (no extension)
• 4 - very important (no extension)
• 5 - fixed time (no extension)
Tasks with high time priority are more likely to get scheduled inside their given time window. Tasks with time priority 0 completely ignore their given time window.
prefWorkers Array<integer> The IDs of preferred workers. taskPrefs
antiWorkers Array<integer> The IDs of workers to which an assignment is undesirable. taskPrefs
forbWorkers Array<integer> The IDs of forbidden workers. strict
qualification integer The minimum qualification of the employee required to perform the task (e.g. years of experience). strict
categories Array<integer> A suitable worker has to fulfill all of these categories. strict
exchangeableCategories Array<integer> A suitable worker has to fulfill at least one of these categories. strict
preassignedWorker integer The unique ID of the worker who has to take over this task. Restrictions such as qualifications, capacity, category still apply. strict
desiredWorker integer The unique ID of the worker who is desired (strong preference, not influenced by workerPrefs) to take over this task.
prefGender integer (gender) The preferred gender for the assigned worker. genderPrefs, strict if set to 9
precedingTasks Array<integer> Tasks in this list and this task will be performed by the same worker and all tasks in list will have to be finished before this task starts. strict
predecessorTasks Array<integer> The tasks of which one has to be performed right before this task by the same worker as this task. strict
group integer A group ID. Tasks with the same group ID get assigned to the same worker. strict
groupOrder integer The order within a group. For more details, see below. strict
revenue number The revenue which will be achieved with this task.
initassignedShift integer The id to the Shift this task will be initially assigned to. This creates a higher likelihood that this task will be assigned to the specified shift in the solution.
assignmentPriority integer A priority for assignment (see allowUnassignedTasks) ranging 0-5.
• 0 - no preference regarding unassignment, whether or not the task is assigned does not matter and will depend solely on other factors
• 1-4 - progressively higher assignment importance
• 5 - task has to be assigned
strict on value 5

Tasks within the same group (identical groupID) will still need a Shift each where they will be assigned on seperately. If the whole group or a subset of a group shall be assigned to a single Shift, each task in the set/ subset needs to have a unique groupOrder. The tasks will then be assigned to a single Shift in that order. Tasks without groupOrder within the same group will not get assigned to that Shift and need a seperate Shift each. Note that there can obviously be only one such subset per group.

If tasks are supposed to be on the same worker in a specified order but on seperate Shifts, set the groupID but use precedingTasks or predecessorTasks instead of groupOrder.

The assigned task - after the performed optimization - extends the unassigned tasks with information about when the task is scheduled and by whom it will be completed.

The minimum required JSON-body of an assigned task looks like this:

{
"date": "2019-12-03",
"duration": 240,
"timeEarliest": "06:00",
"timeLatest": "12:00",
"timeScheduled": "13:45",
"assignedWorker": 2,
"info": "",
"finalassignedOrder": 1,
"profit": 1.123
}


The full JSON-body of an assigned task looks like this:

{
"externalID": "id123",
"date": "2019-12-03",
"duration": 240,
"timeEarliest": "06:00",
"timeLatest": "12:00",
"timePriority": 2,
"prefWorkers": [
1,2
],
"antiWorkers": [
5,6
],
"forbWorkers": [
3,4
],
"qualification": 3,
"categories": [
1
],
"exchangeableCategories": [
2,4
],
"preassignedWorker": 2,
"desiredWorker": 2,
"prefGender": 1,
1,2
],
1,2
],
"group": 2,
"groupOrder": 3,
"revenue": 2.123,
"timeScheduled": "13:45",
"assignedWorker": 2,
"info": "",
"finalassignedOrder": 1,
"profit": 1.123
}


The JSON-Schema of the assigned shiftplanner task (TODO) is an extension of the JSON-Schema of an abstract task.

Extension Parameter Required if assigned Required if unassigned Type Description
externalID string A string to identify the task in the solution. Cannot be used as identifier by other fields.
date string (date) The date for the day to be planned.
duration integer The time in minutes it takes to complete this task.
timeEarliest string (time) The earliest possible start-time of this task.
timeLatest string (time) The latest time at which this task should be finished.
timePriority integer The priority of the time window ranging from 0-5. (Default: 1)
• 0 - irrelevant
• 1 - not important (automatically extended by 30 minutes)
• 2 - more important (automatically extended by 15 minutes)
• 3 - important (no extension)
• 4 - very important (no extension)
• 5 - fixed time (no extension)
Tasks with high time priority are more likely to get scheduled inside their given time window. Tasks with time priority 0 completely ignore their given time window.
prefWorkers Array<integer> The IDs of the preferred workers.
antiWorkers Array<integer> The IDs of workers to which an assignment is undesirable.
forbWorkers Array<integer> The IDs of the forbidden workers.
qualification integer The minimum qualification of the employee required to perform the task (e.g. years of experience).
categories Array<integer> A suitable worker has to fulfill all of these categories.
exchangeableCategories Array<integer> A suitable worker has to fulfill at least one of these categories.
preassignedWorker integer The unique ID of the worker who has to take over this task. Restrictions such as qualifications, capacity, category still apply.
desiredWorker integer The unique ID of the worker who is desired (strong preference, not influenced by workerPrefs) to take over this task.
prefGender integer (gender) The preferred gender for the assigned worker.
precedingTasks Array<integer> Tasks in this list and this task will be performed by the same worker and all tasks in list will have to be finished before this task starts.
predecessorTasks Array<integer> The tasks of which one has to be performed right before this task by the same worker as this task.
group integer A group ID. Tasks with the same group ID get assigned to the same worker.
groupOrder integer The order within a group.
revenue number The revenue which will be achieved with this task.
initassignedShift number The id to the Shift this task will be initially assigned to. This creates a higher likelihood that this task will be assigned to the specified shift in the solution.
assignmentPriority integer A priority for assignment (see allowUnassignedTasks) ranging 0-5.
• 0 - no preference regarding unassignment, whether or not the task is assigned does not matter and will depend solely on other factors
• 1-4 - progressively higher assignment importance
• 5 - task has to be assigned
timeScheduled string (time) The predicted/planned time to start this task by the assigned worker.
assignedWorker integer The unique ID of the assigned worker who will take over this task.
assignedShift integer The unique ID of the assigned shift on the assigned worker.
info string may contain some information about the worker.
finalassignedOrder integer The order number on the assigned worker.
profit number The profit the task creates ($revenue - costs$).

## Unassigned ShiftPlanner-Worker

The minimum required JSON-body of an unassigned worker looks like:

{
"workerID": 1
}


The full JSON-body of an unassigned worker looks like:

{
"workerID": 1,
"externalID": "id123",
"qualification": 1,
"categories": [
1,2
],
"desiredCategory": 12,
"prefCategories": [
3
],
"prefWeekCategories": [
2
],
"prefWeekendCategories" : [
3
],
"prefWorkers": [
5,43
],
"antiWorkers": [
5,43
],
"shifts": [
{
"shiftStart": "05:00",
"shiftEnd": "12:00",
"shiftDate": "2019-12-03"
}
],
"gender": 1,
"expectedWorkingMinutes": 9200,
"minWorkingMinutes": 8000,
"maxWorkingMinutes": 12000,
"maxConsecutiveWorkdays": 6,
"carryoverConsecutiveWorkdays": 0,
"maxConsecutiveOffdays": 2,
"minConsecutiveOffdays": 2,
"prefConsecutiveWorkdays": 10,
"prefConsecutiveOffdays": 15,
"carryoverConsecutiveOffdays": 1,
"maxDailyWorkingMinutes": 600,
"minFreeSaturdays": 4,
"minFreeSundays": 5,
"maxWeeklyWorkingMinutes": 3000,
"carryoverWorkingMinutesLastWeek": 50,
"maxTwoWeekWorkingMinutes": 4800,
"carryoverWorkingMinutesSecondLastWeek": 2100,
"dontVary": true,
"costsPerMinute": 1.123,
"costsInitial": 100.12,
"precNightShifts": 2,
"maxOrderedGroups": 2,
"maxDesiredOrderedGroups": 1,
"maxNightShifts": 3,
"maxDesiredNightShifts": 2,
"minFreeWeekends": 2,
"minDesiredFreeWeekends": 1
}


The JSON-Schema of the unassigned shiftplanner worker is an extension of the JSON-Schema of an abstract worker.

The worker has both optional and required parameters as marked in the following table.

Parameter Required Type Description Depends on
workerID integer The unique ID of the worker.
externalID string A string to identify the worker in the solution. Cannot be used as identifier by other fields.
qualification integer The qualification of the worker. He or she is able to take over tasks with the same or lower qualifications. strict
categories Array<integer> The categories the workers can take over. strict
desiredCategory integer The worker has a strong preference towards tasks with this category.
prefCategories Array<integer> The task-categories preferred by the worker. workerPrefs
prefWeekCategories Array<integer> The task-categories preferred by the worker on any week day (Mon-Fri). workerPrefs
prefWeekendCategories Array<integer> The task-categories preferred by the worker on any weekend day (Sat, Sun). workerPrefs
prefWorkers Array<integer> The workers that this worker prefers to have simultanious shifts with. teamPrefs
antiWorkers Array<integer> The workers that this worker prefers to not have simultanious shifts with. teamPrefs
shifts Array<Shift> The time slots at which a worker can perform exactly one task each.
gender integer (gender) The gender type of the worker.
expectedWorkingMinutes integer The preferred amount of working time minutes for this worker in the final plan, deviation in both directions will be kept as low as possible. worktimePrefs
minWorkingMinutes integer The minimum amount of working time minutes for this worker in the final plan.
maxWorkingMinutes integer The maximum amount of working time minutes for this worker in the final plan.
maxConsecutiveWorkdays integer Maximum number of consecutive workdays. A day is a workday if any work is performed from 00:00 to 23:59. Default: no limit
minConsecutiveWorkdays v2.29.0 integer Minimum number of consecutive workdays. A day is a workday if any work is performed from 00:00 to 23:59. Default: 0
prefConsecutiveWorkdays integer The preferred number of working days in a row. worktimePrefs
carryoverConsecutiveWorkdays integer The current number of consecutive workdays at the start of the plan.
maxConsecutiveOffdays v2.29.0 integer Maximum number of consecutive offdays. A day is an offday if no work is performed from 00:00 to 23:59. Default: no limit
minConsecutiveOffdays integer Minimum number of consecutive offdays. A day is an offday if no work is performed from 00:00 to 23:59. Default: 0
prefConsecutiveOffdays integer The preferred number of non-working days in a row. worktimePrefs
carryoverConsecutiveOffdays integer The current number of consecutive offdays at the start of the plan.
minBreakMinutesBetweenTasks integer Minimum number of minutes break between two ShiftPlanner-Tasks. Default: 0 strict
maxDailyWorkingMinutes integer Maximum number of working minutes per day. Default: no limit
minFreeSaturdays integer Minimum number of work-free Saturdays for this worker between the earliest shiftStart of any ShiftPlanner-Worker and latest shiftEnd of any ShiftPlanner-Worker. strict from v2.32.0
minFreeSundays integer Minimum number of work-free Sundays for this worker between the earliest shiftStart of any ShiftPlanner-Worker and latest shiftEnd of any ShiftPlanner-Worker. strict from v2.32.0
maxWeeklyWorkingMinutes integer Maximum minutes working time for this worker each calendar week (Monday to Sunday). Please note that the week cycle is independent from the planning horizon, use carryoverWorkingMinutesLastWeek in conflicting cases.
carryoverWorkingMinutesLastWeek integer Minutes of worktime already performed by this worker in the week of the earliest shiftStart of any ShiftPlanner-Worker in this plan. The value is factored in by maxWeeklyWorkingMinutes and maxTwoWeekWorkingMinutes but not expectedWorkingMinutes!
maxTwoWeekWorkingMinutes integer Maximum minutes working time for this worker for every two consecutive calendar weeks (Monday to Sunday). Please note that the week cycle is independent from the planning horizon, use carryoverWorkingMinutesLastWeek and carryoverWorkingMinutesSecondLastWeek in conflicting cases.
carryoverWorkingMinutesSecondLastWeek integer Minutes of worktime already performed by this worker in the week prior to the earliest shiftStart of any ShiftPlanner-Worker in this plan. The value is factored in by maxWeeklyWorkingMinutes and maxTwoWeekWorkingMinutes but not expectedWorkingMinutes!
dontVary boolean Lock existing task assignment, see below for details. strict
costsPerMinute number The costs per minute working time (carrying out tasks) for this worker (e.g. monthly salary converted to minutes). profitability
costsInitial number Costs that occur if there is at least one task assigned to the worker. profitability
precTaskDate string (date) Date of the last task the worker carried out before the start of this plan.
precTaskScheduled string (time) Scheduled time of the last task the worker carried out before the start of this plan.
precTaskDuration integer Duration of the last task the worker carried out before the start of this plan.
precNightShifts integer Amount of consecutive "night shifts" the worker carried out directly before the start of this plan. Those are ShiftPlannerTasks that are scheduled in a way that they overlap with midnight. For more details see below.
maxOrderedGroups v2.29.0 integer The maximum number of task sets with same group and set group order that can be assigned to this worker. strict from v2.32.0
maxDesiredOrderedGroups v2.32.0 integer A preference for the maximum number of task sets with same group and set group order that can be assigned to this worker.
maxNightShifts v2.29.0 integer The maximum number of "night shifts" this worker can get assigned. strict from v2.32.0
maxDesiredNightShifts v2.32.0 integer A preference for the maximum number of "night shifts" this worker can get assigned.
minFreeWeekends v2.32.0 integer The minimum number of completely free weekends with no work on either Saturday or Sunday. See below for annotations. strict
minDesiredFreeWeekends v2.32.0 integer A preference for the minimum number of completely free weekends with no work on either Saturday or Sunday. See below for annotations.

A worker with dontVary set to true is "fixed" for the optimizer, meaning they get assigned all tasks that have a shift of this worker as their initassignedShift and nothing else. The worker and its tasks will still be considered in ShiftPlanner-Statistics and ShiftPlanner-Info.

Only one of carryoverConsecutiveWorkdays and carryoverConsecutiveOffdays may be set for each worker.

The parameter precNightShifts is used for carrying over the biorhythm between different, consecutive plans. As such, the tasks on the days directly before the plan start are relevant. As an example, let the plan start on 2020-05-01:

• If on 2020-04-30 no task was scheduled or a task was scheduled that did not overlap with the midnight to 2020-05-01, the value has to be 0.
• If on 2020-04-30 a task was scheduled that overlaps with midnight to 2020-05-01, the value has to be at least 1; exactly 1 if this is not true for 2020-04-29.
• If, additionally to the case above, on 2020-04-29 a task was scheduled that overlaps with midnight to 2020-04-30, the value has to be at least 2; exactly 2 if this is not true for 2020-04-28.
• And so on...

If either precTaskDate, precTaskScheduled, or precTaskDuration is set, all of the values have to be set. If precNightShifts is set, all of the three mentioned values have to be set as well.

(v2.32.0) Please note the following behvaviour regarding minFreeWeekends/minDesiredFreeWeekends: * If the last day of the plan is a Saturday, that weekend will not count as a "free weekend". * If the first day of the plan is a Sunday, data from precTaskDate will get used to determine if this starting weekend can be "free" or not. If precTaskDate if is earlier than the Saturday and nothing is assigned on Sunday, the weekend is considered a "free weekend" for this plan, if either the precTaskDate is the Saaturday or a task is assigned on Sunday, it is not. If no precTaskDate is given, the weekend will not count as a "free weekend" regardless.

## Assigned ShiftPlanner-Worker

The assigned worker - after the performed optimization - extends the unassigned workers with information in the info field.

The minimum required JSON-body of an assigned worker is identical to the minimum required JSON-body of an unassigned worker. The full JSON-body looks like this:

{
"workerID": 1,
"externalID": "id123",
"qualification": 1,
"categories": [
1,2
],
"desiredCategory": 12,
"prefCategories": [
3
],
"prefWeekCategories": [
2
],
"prefWeekendCategories" : [
3
],
"prefWorkers": [
5,43
],
"antiWorkers": [
5,43
],
"shifts": [
{
"shiftStart": "05:00",
"shiftEnd": "12:00",
"shiftDate": "2019-12-03"
}
],
"gender": 1,
"expectedWorkingMinutes": 9200,
"minWorkingMinutes": 8000,
"maxWorkingMinutes": 12000,
"maxConsecutiveWorkdays": 6,
"carryoverConsecutiveWorkdays": 0,
"maxConsecutiveOffdays": 2,
"minConsecutiveOffdays": 2,
"prefConsecutiveWorkdays": 10,
"prefConsecutiveOffdays": 15,
"carryoverConsecutiveOffdays": 1,
"maxDailyWorkingMinutes": 600,
"minFreeSaturdays": 4,
"minFreeSundays": 5,
"maxWeeklyWorkingMinutes": 3000,
"carryoverWorkingMinutesLastWeek": 50,
"maxTwoWeekWorkingMinutes": 4800,
"carryoverWorkingMinutesSecondLastWeek": 2100,
"dontVary": true,
"costsPerMinute": 1.123,
"costsInitial": 100.12,
"precNightShifts": 2,
"maxOrderedGroups": 2,
"maxDesiredOrderedGroups": 1,
"maxNightShifts": 3,
"maxDesiredNightShifts": 2,
"minFreeWeekends": 2,
"minDesiredFreeWeekends": 1
"info": ""
}


The JSON-Schema of the assigned shiftplanner worker is an extension of the JSON-Schema of an abstract worker.

Extension Parameter Required Type Description
workerID integer The unique ID of the worker.
externalID string A string to identify the worker in the solution. Cannot be used as identifier by other fields.
qualification integer The qualification of the worker. He or she is able to take over tasks with the same or lower qualifications.
categories Array<integer> The categories the workers can take over.
desiredCategory integer The worker has a strong preference towards tasks with this category.
prefCategories Array<integer> The task-categories preferred by the worker.
prefWeekCategories Array<integer> The task-categories preferred by the worker on any week day (Mon-Fri).
prefWeekendCategories Array<integer> The task-categories preferred by the worker on any weekend day (Sat, Sun).
prefWorkers Array<integer> The workers that this worker prefers to have simultanious shifts with.
antiWorkers Array<integer> The workers that this worker prefers to not have simultanious shifts with.
shifts Array<Shift> The timeslots at which this worker can perform exactly one task each.
gender integer (gender) The gender type of the worker.
expectedWorkingMinutes integer The preferred amount of working time minutes for this worker in the final plan, deviation in both directions will be kept as low as possible.
minWorkingMinutes integer The minimum amount of working time minutes for this worker in the final plan.
maxWorkingMinutes integer The maximum amount of working time minutes for this worker in the final plan.
maxConsecutiveWorkdays integer Maximum number of consecutive workdays. A day is a workday if any work is performed from 00:00 to 23:59. Default: no limit
minConsecutiveWorkdays v2.29.0 integer Minimum number of consecutive workdays. A day is a workday if any work is performed from 00:00 to 23:59. Default: 0
prefConsecutiveWorkdays integer The preferred number of working days in a row.
carryoverConsecutiveWorkdays integer The current number of consecutive workdays at the start of the plan.
maxConsecutiveOffdays v2.29.0 integer Maximum number of consecutive offdays. A day is an offday if no work is performed from 00:00 to 23:59. Default: no limit
minConsecutiveOffdays integer Minimum number of consecutive offdays. A day is an offday if no work is performed from 00:00 to 23:59. Default: 0
prefConsecutiveOffdays integer The preferred number of non-working days in a row.
carryoverConsecutiveOffdays integer The current number of consecutive offdays at the start of the plan.
minBreakMinutesBetweenTasks integer Minimum number of minutes break between two ShiftPlanner-Tasks. Default: 0
maxDailyWorkingMinutes integer Maximum number of working minutes per day. Default: no limit
minFreeSaturdays integer Minimum number of work-free Saturdays for this worker between the earliest shiftStart of any ShiftPlanner-Worker and latest shiftEnd of any ShiftPlanner-Worker.
minFreeSundays integer Minimum number of work-free Sundays for this worker between the earliest shiftStart of any ShiftPlanner-Worker and latest shiftEnd of any ShiftPlanner-Worker.
maxWeeklyWorkingMinutes integer Maximum minutes working time for this worker each calendar week (Monday to Sunday). Please note that the week cycle is independent from the planning horizon, use carryoverWorkingMinutesLastWeek in conflicting cases.
carryoverWorkingMinutesLastWeek integer Minutes of worktime already performed by this worker in the week of the earliest shiftStart of any ShiftPlanner-Worker in this plan. The value is factored in by maxWeeklyWorkingMinutes and maxTwoWeekWorkingMinutes but not expectedWorkingMinutes!
maxTwoWeekWorkingMinutes integer Maximum minutes working time for this worker for every two consecutive calendar weeks (Monday to Sunday). Please note that the week cycle is independent from the planning horizon, use carryoverWorkingMinutesLastWeek and carryoverWorkingMinutesSecondLastWeek in conflicting cases.
carryoverWorkingMinutesSecondLastWeek integer Minutes of worktime already performed by this worker in the week prior to the earliest shiftStart of any ShiftPlanner-Worker in this plan. The value is factored in by maxWeeklyWorkingMinutes and maxTwoWeekWorkingMinutes but not expectedWorkingMinutes!
dontVary boolean Lock existing task assignment.
costsPerMinute number The costs per minute working time (carrying out tasks) for this worker (e.g. monthly salary converted to minutes).
costsInitial number Costs that occur if there is at least one task assigned to the worker.
precTaskDate string (date) Date of the last task the worker carried out before the start of this plan.
precTaskScheduled string (time) Scheduled time of the last task the worker carried out before the start of this plan.
precTaskDuration integer Duration of the last task the worker carried out before the start of this plan.
precNightShifts integer Amount of consecutive "night shifts" the worker carried out directly before the start of this plan.
maxOrderedGroups v2.29.0 integer The maximum number of task sets with same group and set group order that can be assigned to this worker.
maxDesiredOrderedGroups v2.32.0 integer A preference for the maximum number of task sets with same group and set group order that can be assigned to this worker.
maxNightShifts v2.29.0 integer The maximum number of "night shifts" this worker can get assigned.
maxDesiredNightShifts v2.32.0 integer A preference for the maximum number of "night shifts" this worker can get assigned.
minFreeWeekends v2.32.0 integer The minimum number of completely free weekends with no work on either Saturday or Sunday. See below for annotations.
minDesiredFreeWeekends v2.32.0 integer A preference for the minimum number of completely free weekends with no work on either Saturday or Sunday. See below for annotations.
info string Some textual information about the worker.

## ShiftPlanner-Statistics

The JSON-body of statistics for a calculated plan looks like this:

{
"impact": [
{
"label": "Minimum consecutive offdays",
"value": 0.777778
},
...
]
}


JSON-Schema

Parameter Type Required Description
impact Array<Object<label: string, value: number>> A number based summary of calculation results. See below for details.
unassignedTaskIDs Array<integer> taskIDs of all tasks that were not assigned during optimization. Only included if not empty.
unassignableTaskIDs Array<integer> taskIDs of all tasks that were not assigned during optimization because there is no assignment possible (meaning they would fail input validation if unassigned tasks were not allowed). Only included if not empty.

The array impact contains all restriction types and gives a percentage (0.0-1.0) evaluation of each restriction's final influence on the algorithmic optimization and plan result. This can be used to detect logical problems in the input data, i.e. too restrictive time windows, an unrealisic amount of free Saturday/ Sunday preferences or a large amount of worker preferences that just cannot be fulfilled. However, please note that when a restriction is listed in impact with a value greater zero, it does not mean that there even is a way to erase its impact. For instance, if costsPerMinute are set, worktime costs will always be featured unless the total amount of working time is zero or the profitability option is set to zero.

The following fields are getting written in impact. They get translated based on the language setting and are all required:

German label English label
Minimum freie Tage Minimum consecutive offdays
Präferierte freie Tage Preferred consecutive offdays
Ungültige Zuweisung Invalid assignment
Mitarbeiterpräferenz Worker preference
Anti-Mitarbeiter Antiworker
Wunschmitarbeiter Desired worker
Geschlechterpräferenz Gender preference
Schichtverletzung Shift time window violation
Arbeitszeitkosten Worktime costs
Initiale Kosten Initial costs
Erwartete Gesamtarbeitszeit Expected total worktime
Minimale Gesamtarbeitszeit Minimum total worktime
Maximale Gesamtarbeitszeit Maximum total worktime
Freie Samstage Free Saturdays
Freie Sonntage Free Sundays
Gruppierung Groups
Kategoriepräferenz Preferred categories
Maximale Arbeitszeiten Maximum worktimes
Ausgeglichener Plan Fair distribution
Mitarbeiterreduzierung Worker reduction
Maximale Arbeitstage Maximum workdays
Präferierte Arbeitstage Preferred workdays
Präferenzen zwischen Mitarbeitern Preferences between workers
Anti-Präferenzen zwischen Mitarbeitern Anti-preferences between workers
Qualifikationsabdeckung Qualification coverage
Kategorieabdeckung Category coverage
Wunschkategorie Desired category
Nicht-erbrachter Ertrag Missing revenue
Biorhythmusabweichungen Biorhythm deviations
Minimale Arbeitstage v2.29.0 Minimum workdays v2.29.0
Maximale freie Tage v2.29.0 Maximum consecutive offdays v2.29.0
Maximale Nachtdienste v2.29.0 Maximum night shifts v2.29.0
Maximale Dienstgruppen v2.29.0 Maximum groups v2.29.0
Minimum freie Wochenenden v2.32.0 Minimum free weekends v2.32.0

## ShiftPlanner-Info

The JSON-body of info for a calculated plan looks like this:

{
"text": "\nBACKEND VERSION - rev: 872ae212cbb90ffa9fe39d5341f73a8e6d7786b9 - v2.14.0"
}


JSON-Schema (TODO)

Parameter Required Type Description
text string Some general information about the plan.

All text in text gets translated based on language setting.

# Authentication

To authorize, use this code:

const AmazonCognitoIdentity = require('amazon-cognito-identity-js');
const CognitoUserPool = AmazonCognitoIdentity.CognitoUserPool;
const poolData = {
UserPoolId: "eu-central-1_0nXRn1JFH", // Your user pool ID here
ClientId: "5n75tqsegshum2i9o0bgavmmuf" // Your client ID here
};
const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
const authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails({
});

const userData = {
Pool : userPool
};

const cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {
...
},
onFailure: function(err) {
console.log(err);
},
});


Make sure to replace with your authentication data.

We are using personlized accounts to provide access to the API. You can request an account by contacting us.

Through the authentication you get three tokens: the access-token, the ID-token and the refresh-token. The tokens are jwt-tokens (JSON Web Tokens). The access-token is currently not used in the API. The ID-token has to be proposed in every request in the header as follows:

Authorization: 'ID-token'

The ID-token contains a timestamp when the token has been authorized (auth_time) and when it will expire (exp). Currently an ID-token expires after one hour. With these parameters you are able to check if the token is still valid. If a request with an expired token is sent, it will be rejected with status code 401. If so, you can easily get a new ID-token by using the refresh-token without having to re-enter your credentials.

Currently the method SRP (Secure Remote Password protocol) is used for authentication. This method does not need to pass the password to the backend. Instead, a multiway handshake is used to proof the authentication. Implementations of this procedure can be found on the Wikipedia-Page.

The authentication is performed via AWS Cognito (Developer-Guide). AWS provides SDKs for some languages which simplifies the authentication process. For example, when you are using JavaScript you can use the amazon-cognito-identity-js to easily integrate the authentication. However, not all SDKs provide full support for this method.

Easily supported languages by AWS are:

If you are using a language that is not directly supported, feel free to contact us. Even if an AWS-SDK exists for your language, often the SRP-methods have to be implemented by yourself. Here you can try one of the implementations linked on Wikipedia.

## Configurations

Basing on your id-token you are able to determine wheter you have just a single user and no access to your limits or you have two users one for submitting plans and one for managing your clients.

In the first case the field cognito:groups in the id-token is not set. In the second case the field cognito:groups is set. For the submitting-account the entry hasMgmtUser is set and for the management-account the entry isMgmtUser is set.

The user and the management account are mapped to the same e-mail-address but have different passwords.

### User-Authentication

You authenticate yourself against this user pool with your account details to do calculations. When you have a managed account you have to provide an client id.

UserPoolId: "eu-central-1_0nXRn1JFH",
ClientId: "5n75tqsegshum2i9o0bgavmmuf"


### Management-User-Authentication

You authenticate yourself against this user pool with you account details to alter limitation for your clients.

UserPoolId: "eu-central-1_esw8SOukA",
ClientId: "7vqnjalt4k4op5ffhqf8uramvi"


# Plans

## Post a new plan

This endpoint is used to post a new problem description for obtaining an optimized plan based on it.

### HTTP-Endpoint

Type Endpoint
MixedPlanner POST https://jadnzfxwb3.execute-api.eu-central-1.amazonaws.com/dev/description
ShiftPlanner POST https://jadnzfxwb3.execute-api.eu-central-1.amazonaws.com/dev/shift-description

### MixedPlanner-Request

An example for a MixedPlanner request

{
"meta": {
"accuracyMode": 1,
"dateFrom": "2019-12-03",
"dateTo": "2019-12-03",
"postProcessing": true,
"resCapacity": false,
"resCategory": false,
"resQualification": false
},
"parameters": {
"fairDistribution": 4,
"localityClustering": 2,
"shortPaths": 7,
"timeliness": 5,
"travelTimeRelax": 0,
"workerPrefs": 5,
"workerReduction": 1,
"workTimeRelax": 0
},
{
"date": "2019-12-03",
"duration": 65,
"location": {
"lat": 50.878847,
"lng": 6.964728400000013
},
"timeEarliest": "10:00",
"timeLatest": "12:00"
},
{
"date": "2019-12-03",
"duration": 25,
"location": {
"lat": 50.9333412,
"lng": 6.972426400000018
},
"timeEarliest": "16:00",
"timeLatest": "17:00"
},
...
],
"workers": [
{
"workerID": 1,
"endLocation": {
"lat":50.9357092,
"lng":6.974585599999955
},
"shiftDate": "2019-12-03",
"shiftEnd": "14:00",
"shiftStart": "06:00",
"startLocation": {
"lat": 50.9357092,
"lng": 6.974585599999955
}
},
...
],
"locationSites": [
{
"locationSiteID": 1,
"location": {
"lat": 50.878847,
"lng": 6.964728400000013
}
},
{
"locationSiteID": 2,
"location": {
"lat": 12.878847,
"lng": -13.964728400000013
}
},
...
],
"obstacles": [
{
"type": "polyline",
"factor": 2.5,
"description": "This is a line",
"points": [
{
"lat": 51.46149994737996,
"lng": 7.850463381293338
},
{
"lat": 51.66914967977792,
"lng": 9.753747625087499
},
...
]
},
{
"type": "polygon",
"factor": 2.5,
"points": [
{
"lat": 51.46149994737996,
"lng": 7.850463381293338
},
{
"lat": 51.66914967977792,
"lng": 9.753747625087499
},
...
]
},
...
],
"client": {
"clientID": "{1234-5678-9123}"
},
"history": {
{
"clientID": 100,
"scheduling": [
{
"date": "2000-01-01",
"baseScheduleTime": "00:00",
"baseWorker": 1,
"timeScheduled": "00:00",
"assignedWorker": 0,
"timeVariance": 0,
"timePriority": 0,
"timeScheduledAutomatically": "00:00",
"assignedWorkerAutomatically": 0,
"actualStartTime": "00:00",
"actualWorker": 0,
},
...
]
},
...
],
"workers": [
{
"workerID": 0,
"gender": 1,
"qualification": 1,
"categories": [ 1,2 ]
},
...
]
},
"travelOverride": {
"sparse": [
{
"vehicleTypes": [0,2],
"sourceIDs": [12,13,1,12],
"targetIDs": [14,11,12,1],
"travelTime": [3,4,1,1],
"travelDistance": [2.83,1.5,2.01,3.12]
},
{
"vehicleTypes": [1],
"sourceIDs": [12,13,1,12],
"targetIDs": [14,11,12,1],
"travelTime": [3,4,1,1],
"travelDistance": [2.83,1.5,2.01,3.12]
},
...
],
"dense": [
{
"travelTime": [0,2,3,4,0,2,12,5,0],
"travelDistance": [0,1.123,2.123,3.456,0,4.5,2.123,10.11,4.9,0],
"vehicleTypes": [0,3]
},
{
"travelTime": [0,2,3,4,0,2,12,5,0],
"travelDistance": [0,1.123,2.123,3.456,0,4.5,2.123,10.11,4.9,0],
"vehicleTypes": [2]
},
...
]
}
}


The JSON-schema is named unassigned plan

Parameter Required Type Description
client client Contains information about the client, which sends this request.
meta meta Meta-information about what to consider in the optimization.
parameters parameters Parameters for the optimizer.
tasks Array<task> Array of MixedPlanner-Tasks that have to be planned.
workers Array<unassigned worker> Array of available MixedPlanner-Workers.
locationSites Array<LocationSite> Array of available location sites.
obstacles Array<Obstacle> Array of additional obstacles.
history MixedPlanner-History History data.
travelOverride v2.31.0 Travel Override Travel override data

The client field is required when you have a separate management account. It is used to determine the different client and their specific limits.

### ShiftPlanner-Request

An example for a ShiftPlanner request

{
"meta": {
"accuracyMode": 1,
"dateFrom": "2019-12-03",
"dateTo": "2019-12-03",
"resCategory": false,
"resQualification": false
},
"parameters": {
"fairDistribution": 4,
"timeliness": 5,
"workerPrefs": 5,
"workerReduction": 1
},
{
"date": "2019-12-03",
"duration": 65,
"timeEarliest": "10:00",
"timeLatest": "12:00"
},
{
"date": "2019-12-03",
"duration": 25,
"timeEarliest": "16:00",
"timeLatest": "17:00"
},
...
],
"workers": [
{
"workerID": 1,
"shifts": [
{
"shiftStart": "08:00",
"shiftEnd": "20:00",
"shiftDate": "2019-12-03",
"shiftID": 1
},
...
]
},
...
],
"client": {
"clientID": "{1234-5678-9123}"
}
}


The JSON-schema is named unassigned plan.

Parameter Required Type Description
client client Contains information about the client, which sends this request.
meta meta Meta-information about what to consider in the optimization.
parameters parameters Parameters for the optimizer.
tasks Array<task> Array of ShiftPlanner-Tasks that have to be planned.
workers Array<unassigned worker> Array of available ShiftPlanner-Workers.

The client field is required if you have a separate management account. It is used to determine the different client and their specific limits.

### Result

As a result an ID will be given which can be used to check the result of the computation

AAAAAAAAABBBBBBBBBBBBBBBEEEEEEEEEEEEEEEEEDDDDDDDDDD


As result an ID will be returned which identifies the planning. You can use the function Retrieve a plan/status to check the planning status or whether the plan result exists.

### Status-Codes

Number Code Description
200 OK The plan has already been submitted, everything is fine!
201 CREATED The plan was accepted and is currently processed by the optimization procedures.
403 FORBIDDEN Your account is setup to use different clients. The clientID was not given or the clientID was not registered yet.
409 CONFLICT The limit for the user or client has been exceeded.
500 INTERNAL SERVER ERROR The given data produces a failure in the backend, please check your input data for consistency.

## Check status/retrieve a Plan

This endpoint is used to get the status of a plan or retrieve the plan, when the calculation already is finished.

### HTTP-Endpoint

The HTTP-Endpoint to check status or receive the plan is identical for MixedPlanner and ShiftPlanner.

GET https://jadnzfxwb3.execute-api.eu-central-1.amazonaws.com/dev/plan/<ID>

### Request

In the header of the request the field Accept must be set to application/json. The <ID> which was delivered as a result of the post request needs to be given in the URL.

### MixedPlanner-Result

When the calculation is finished you get a calculated plan, which can look like this:

{
"requestID": "id2103",
"meta": {
"dateFrom": "2019-12-03",
"dateTo": "2019-12-03",
"resCapacity": false,
"resQualification": false,
"resCategory": false,
"accuracyMode": 1,
"postProcessing": false
},
"parameters": {
"shortPaths": 7,
"workerPrefs": 5,
"fairDistribution": 4,
"localityClustering": 2,
"timeliness": 5,
"workerReduction": 1,
"travelTimeRelax": 0,
"workTimeRelax": 0
},
"locationSites": [
{
"locationSiteID": 3,
"location": {
"lat": 50.3232323,
"lng": 7.23122212
}
}
],
"workers": [
{
"workerID": 1,
"startLocation": {
"lat": 50.9357092,
"lng": 6.974585599999955
},
"endLocation": {
"lat": 50.9357092,
"lng": 6.974585599999955
},
"shiftStart": "06:00",
"shiftEnd": "14:00",
"info": "",
"shiftDate": "2019-12-03"
},
{
"workerID": 2,
"startLocationSiteID": 3,
"shiftStart": "05:00",
"shiftEnd": "16:00",
"shiftDate": "2019-12-03"
}
],
{
"date": "2019-12-03",
"duration": 65,
"timeEarliest": "10:00",
"timeLatest": "12:00",
"location": {
"lat": 50.878847,
"lng": 6.964728400000013
},
"description": "",
"timeScheduled": "11:01",
"travelTime": 3,
"travelDistance": 2.83061,
"assignedWorker": 2,
"info": "This task assignment causes negative arrival slack: -6"
},
...
],
"info": {
...
},
"statistics": {
...
},
"backendVersion": {
"schema": "v0.49.9",
"version": "v2.25.12",
"rev": "abcde12"
}
}


The JSON-schema is called assigned plan.

Parameter Required Type Description
requestID string A unique id to identify the plan.
client client Contains information about the client, which sent this request.
meta meta Meta-information about what to consider in the optimization.
parameters parameters Parameters for the optimization.
tasks Array<task> Array of assigned tasks.
workers Array<assigned worker> Array of available workers.
locationSites Array<LocationSite> Array of available location sites.
obstacles Array<Obstacle> Array of additional obstacles.
statistics statistics Some statistics about the plan.
info info Some textual information about the plan.
backendVersion v2.35.0 Backend Version Used validation/ calculation version.

### ShiftPlanner-Result

The JSON-schema is called assigned plan (TODO).

Parameter Required Type Description
requestID string A unique id to identify the plan.
client client Contains information about the client, which sent this request.
meta meta Meta-information about what to consider in the optimization.
parameters parameters Parameters for the optimization.
tasks Array<task> Array of assigned tasks.
workers Array<assigned worker> Array of available workers.
statistics statistics Some statistics about the plan.
info info Some textual information about the plan.
backendVersion v2.35.0 Backend Version Used validation/ calculation version.

### Error-result

{
"requestID": "id32013",
"error_msg": " |-| ERROR: Task #12 has itself assigned as preceding task. (129) |-| contact email: support@adiutabyte.de",
"version": "1.0.0",
"type": "error",
"errorID": 129,
"backendVersion": {
"schema": "v0.49.9",
"version": "v2.25.12",
"rev": "abcde12"
}
}


The JSON-schema is named error plan

Parameter Required Type Description
requestID string A unique id to identify the plan request.
error_msg string Contains a textual description of the error.
version string Currently always set to "1.0.0".
type string Currently always set to "error".
errorID integer A unique id for identifying the error cause.
taskID integer If the error occurred by a specific task, its ID will be referenced.
workerID integer If the error occurred by a specific worker, their ID will be referenced.
backendVersion v2.35.0 Backend Version Used validation/ calculation version.

The error_msg gets translated based on language settings.

### Error Codes

Error message and id depend on what caused the problem. In some cases a notify-devs suffix gets added to the message, the English one being "Please contact the developers!". Both error message and dev-notification suffix get translated based on language settings specified.

For an error solution to be created the algorithm has to be able to

• determine input file type to mirror it
• read meta and parameters field in input file to determine language settings.

Should the program fail without being able to perform these steps, it will exit without an error solution being created.

Below are the currently used error ids and a short description as to what is the problem. Internal errors are most likely caused by bugs and can generally only be solved with a developer on our side (especially any Error Code > 249), the in the following listed errors are mainly caused by errors in the input processing and may also be solved by users directly by correcting their sent input.

The column additional output refers to the parameter taskID/workerID in the error result. Additional properties get used in the error_msg section of the result but don't get written to a designated field.

Error Code Range Error Category
0 – 99 Server side error
100 – 109 Miscellaneous errors
110 – 119, 900 – 949 Invalid object in input data
120 – 199 Input data validation fail
200 – 249 Error while priming input data
250 – 899, 950 – 999 Internal errors for the developers
Error Code Description Error name (internal) notify devs? internal? additional output additional properties
99 Process crashed
100 invalid error code InvalidError
101 error was not caught via manual checks or exception was thrown by c++ or external code UncaughtException text
102 Error solution could not be created due to initial id InvalidErrorSolutionSave
103 Timeout prevented a plan solution. Disable disjunct plan optimization! DisjunctTimeout
104 Invalid system state InvalidSystemStatus
105 System was terminated via signal SignalError signal id, signal type
110 invalid worker in input (missing required data) InvalidWorker workerID
112 invalid LocationSite in input (missing required data) InvalidLocationSite locationSiteID
113 invalid Shift in input (missing required data) InvalidShift
114 missing corner points on polygon InvalidPolygon
115 missing corner points on polyline InvalidPolyLine
116 invalid obstacle in input (missing required data) InvalidObstacle
117 input file contains no worker field NoWorkersInInput
119 invalid history assignment in input data (missing required data) InvalidHistoryAssignment
120 sum of task capacity exceeds sum of worker capacity but no resets TaskCapacityExceedsWorkerCapacity
121 sum of task weights exceeds sum of worker weight limits but no resets TaskWeightExceedsWorkerWeight
122 sum of task volume exceeds sum of worker volume limits but no resets TaskVolumeExceedsWorkerVolume
124 a worker set as initassignedWorker to a task does not exist in the input data InitWorkerDoesNotExist taskID workerID
125 initassignedOrder is set but neither initassignedWorker not preassignedWorker are set InitOrderButNotInitWorker taskID
126 two tasks have the same initial order on same worker ConflictingInitialOrder taskID 1&2
127 isAllowedToTakeOver fails for this task on every worker in plan (MixedPlanner version) NoSuitableWorkerAvailable_MP taskID task earliest, latest, duration, coordinates
128 isAllowedToTakeOver fails for this task on every worker in plan (ShiftPlanner version) NoSuitableWorkerAvailable_SP taskID task earliest, latest, duration
133 The task and every of its predecessor tasks have no common worker that is isAllowedToTakeOver NoSuitableWorkerPredecessor taskID
135 two workers have the same id DuplicateWorkerID workerID
137 initial capacity is greater than worker capacity WorkerInitiallyOverfilledCap workerID
138 initial weight is greater than worker weight limit WorkerInitiallyOverfilledWeight workerID
139 initial volume is greater than worker volume limit WorkerInitiallyOverfilledVol workerID
140 reset duration is set but reset locations are missing CapacityResetInformationInvalid workerID
141 shift end is before shift start NegativeLengthShift workerID
143 break start earliest is missing when other break values are set MissingBreakEarliest workerID
144 break end latest is missing when other break values are set MissingBreakLatest workerID
145 break duration is missing when other break values are set MissingBreakDuration workerID
146 break duration is greater than time between break earliest start and break latest end BreakTimeSlotTooSmall workerID
147 break end latest is before break start earliest NegativeBreakTimeWindow workerID
148 break is not inside worker shift BreakOutsideWorkerShift workerID
149 two multishifts on worker overlap OverlappingMultishifts workerID
150 both startLocation and startLocationSiteID on worker RedundantStartLocationSiteID workerID
151 both endLocation and endLocationSiteID on worker RedundantEndLocationSiteID workerID
152 locationSite set in startLocationSiteID does not exist InvalidStartLocationID workerID
153 locationSite set in endLocationSiteID does not exist InvalidEndLocationID workerID
154 one of the locationSites for resets does not exist InvalidCapacityResetLocationID workerID
157 circle in preceding tasks PrecedingCircle
159 Qualification coverage is expected but no worker has enough qual QualificationCoverageNotPossible
160 Category coverage is expected but no worker has this category CategoryCoverageNotPossible category
161 a worker with multishifts has tasks that have it as initassigned worker. This is not allowed InvalidMultishift workerID
162 a worker with multishifts is set as dontVary worker. This is not allowed InvalidDontVary workerID
163 sum of negative capacities is greater than sum of positive capacities MoreNegCapacitiesThanPos
164 sum of negative weights is greater than sum of positive weights MoreNegWeightThanPos
165 sum of negative volumes is greater than sum of positive volumes MoreNegVolumeThanPos
168 task is assigned to dontVary worker but has no initassigned order NoInitAssignedOrderDontVary taskID
169 task is assigned to dontVary worker but has same initassignedOrder as another task on same worker DontVaryInitassignedOrderNotUnique workerID
173 a set of tasks that have to be performed by the same worker don't have any worker that can do so InvalidRelationGroup taskIDs of group
174 Input parameter out of range InvalidParameter
176 groupOrder is set but group is not MissingGroupData taskID
177 initassignedShift does not exist InvalidInitassignedShift taskID
178 Two tasks have the same initassigned shift on a dontVary worker ConflictingDontVaryAssignment taskID 1, taskID 2
179 Two shifts have the same id ShiftIDNotUnique shiftID
180 No shift on a suitable worker overlaps with the task time window NoPotentialShift taskID
181 A worker shift has a duration of 0 minutes. Contrary to the internal error name this is not multishift related. InvalidMultishiftLength workerID
182 Tasks in a strict order and assignment (replacement) have different dontVary assignments. ConflictingDontVaryReplacement taskID other task id
183 Tasks in a strict order and assignment (replacement) has a dontVary assignment but invalid order. ConflictingDontVaryOrder taskID
184 Task has either forbTimeEarliest or forbTimeLatest set but not both MissingForbiddenTimeWindowData taskID
185 The task's forbidden time window has a negative length InvalidForbiddenTimeWindow taskID
186 The task's forbidden time window is not fully included within its time window ForbiddenTimeWindowNotIncluded taskID
187 The time before or after the forbidden time window is too short to carry out the task ForbiddenTimeWindowTooLarge taskID
188 Worker has both dontVary and dontAlter set to true ConflictingDontAlterDontVary workerID
189 Worker has set one of precTaskDate/precTaskScheduled/precTaskDuration but not all of them PrecTaskDataIncomplete workerID
190 v2.29.9 Worker has a prefWorker/antiWorker set which has a dontVary flag ConflictingWithDontVaryWorker workerID
191 v2.29.9 Worker contributes to qualification or category coverage but has a dontVary flag ConflictingDontVaryCoverage workerID
200 time window is too small for duration even after reducing work time multiplicator TimeSlotTooSmallAfterCheck
206 Same workerID exists in history and plan WorkerBothPlannedAndHistorical
207 Same workerID exists multiple times in history DuplicateWorkerHistory
209 Given workerID for history assignment does not exist in plan or history HistoryAssignmentMissingWorker
210 Task has no clientID set MissingClientID
211 A history task has multiple assignments on same day DuplicateHistoryDate
212 Invalid date on history assignments FutureHistoryAssignments
900 invalid history worker in input data (missing required data) InvalidHistoryWorker
902 history does not contain a worker array NoWorkersInHistory

### Status-Codes

Number Code Description
200 OK The plan will be delivered.
406 NOT ACCEPTABLE The given Accept parameter in the header could not be used.
423 LOCKED The plan is currently optimized. Try again later to check if the calculation has finished.

# Client-Limits

If your account is set up to support different clients you have to submit the clientID in every request. Before you are able to use a new client you have to specify a limit of tasks a client is able to plan every month.

For these kind of request you have to use the management user. So you have to authenticate against the cognito pool mentioned in Management-User-Authentication

## Set default client-limit

### HTTP-Endpoint

POST https://jadnzfxwb3.execute-api.eu-central-1.amazonaws.com/dev/client-limit

### Request

The JSON-body for setting the a default client limit looks like this:

{
"clientID": "{12345-678-90}",
"limit": 3000
}

Parameter Required Type Description
clientID string The identifier which identifies a client.
limit number The number of tasks a client is allowed to plan within a month.

### Result

Parameter Type Description
message string Text: 'default limit successfully set'.

### Status-Codes

Number Code Description
200 OK The limit was successfully set.
401 UNAUTHORIZED No credentials given in the header or they are not valid.
403 FORBIDDEN The access was not allowed for this user.

## Get the default client-limit

### HTTP-Endpoint

GET https://jadnzfxwb3.execute-api.eu-central-1.amazonaws.com/dev/client-limit/<client-id>

### Result

{
}

Parameter Type Description

### Status-Codes

Number Code Description
200 OK The default task limit.
204 NO CONTENT No default task limit is set.

## Set client-limit for a specific month

### HTTP-Endpoint

POST https://jadnzfxwb3.execute-api.eu-central-1.amazonaws.com/dev/client-limit

### Request

The JSON-body for setting the a specific client limit looks like this:

{
"clientID": "{12345-678-90}",
"limit": 3000,
"year": 2020,
"month": 1
}

Parameter Required Type Description
clientID string The identifier which identifies a client.
year number The year for the limit.
month number The corresponding month for the limit.
limit number The number of tasks a client is allowed to plan within a month.

### Result

Parameter Type Description
message string Text for which month the limit was set.

### Status-Codes

Number Code Description
200 OK The limit was successfully set.
401 UNAUTHORIZED No credentials given in the header or they are not valid.
403 FORBIDDEN The access was not allowed for this user.
409 CONFLICT The client was not registered yet.

## Get the client-limit for a specific month

### HTTP-Endpoint

GET https://jadnzfxwb3.execute-api.eu-central-1.amazonaws.com/dev/client-limit/<client-id>/<year>/<month>

### Result

{
}

Parameter Type Description

### Status-Codes

Number Code Description
200 OK Everything fine, the limit and usage of tasks.
204 NO CONTENT No task limit is set for this month.

# Known Bugs

## integrateGermanBreakDuration does not work properly sometimes

When the setting integrateGermanBreakRegulations is set to true, it is possible for a worker to have the wrong kind of break assigned, with one of the following mistakes:

• a break being assigned even though the working time does not warrant one,
• a break not being assigned even though the work time requirement is met,
• the break having the wrong length, being too short or too long.

This can be caused by a mathematical paradoxon, that it is technically not possible to assign breaks based on working time while also using dynamic travel time information. An added break due to working time might push back the starting time of a trip, resulting in shorter travel times (e.g. because the rush hour is less fierce now), which decreases work time below the amount that would warrant a break in the first place. In such a situation it is actually impossible to determine whether or not a break should happen, it will always be wrong.

Fixed: never, not possible.

## Time windows of tasks with timePriority 5 violated when using integrateGermanBreakDuration

When using integrateGermanBreakRegulations tasks with timePriority 5 that are scheduled after one of the automatically assigned pauses (meaning the worker the task is assigned to did not have a break in the input data) have a chance to violate their time window. The cause is similar to the problem above, that you cannot know if a pause is necessary until after calculating the schedule for the worker. Retroactively adding a pause to the plan causes the tasks after the pause to be moved backwards in their scheduled time, resulting them being scheduled later than originally calculated, potentially violating the time window. While this does not just concern timePriority 5 tasks, it is considered a bug in these cases since their time window is considered strict.

Fixed: TBA

## Disabling features does not remove them from info/statistics

When disabling features via the MixedPlanner-Metainformation/ShiftPlanner-Metainformation flags resQualification, resCategory, resCapacity the supposedly removed values will still influence impact values in MixedPlanner-Statistics/ShiftPlanner-Statistics as well as any text in MixedPlanner-Info/ShiftPlanner-Info. Please note that this is a "visual" bug only, the values really are removed from the optimization, plan results are unaffected from this.

Fixed: TBA

# Changelog

## 2022-08-25

• Updated Json examples and schemata to v0.59.0.
• In VehicleType: Added json schema.
• In Travel Override: Changed tag to v2.31.0.
• In MixedPlanner Request: Changed tag of travelOverride to v2.31.0.

## 2022-07-12

• Updated Json examples and schemata to v0.58.0.
• In Error Codes: Added error code 190, 191 with tag v2.29.9.

## 2022-07-09

• In MixedPlanner-Statistics: Added impact field Kapazitäten/Capacities with tag v2.30.0.

## 2022-05-10

• In MixedPlanner-Statistics: Fixed error vehicleTypeDistance to correct parameter vehicleTypeDistances.

## 2022-04-12

• In MixedPlanner-Statistics: Added impact label "Präferenz-Wunschzuweisung Kombination"/"Preference-Desired combination" as WIP.
• In MixedPlanner-Statistics: Changed all impact labels to optional (WIP).

## 2022-04-04

• In Obstacle: Changed factor to be not required anymore.
• In Obstacle: Added travelTimeIncrease as WIP.
• In MixedPlanner-Statistics: Added vehicleTypeDistance as WIP.

## 2021-12-02

• Updated Json schemata.
• In Error Codes: Added error id 181.

## 2021-09-28

• Updated Json schemata.
• In MixedPlanner-Request: Removed request_id.
• In ShiftPlanner-Request: Removed request_id.
• In MixedPlanner-Result: Renamed request_id to requestID and changed type from integer to string.
• In ShiftPlanner-Result: Renamed request_id to requestID and changed type from integer to string.
• In Error-Result: Renamed request_id to requestID and updated description.