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.
Currently the API solely supports JSON formatted data with a schema that is used to validate the data. Non-valid requests are immediately rejected with an error message. In each section a downloadable corresponding JSON schema in the latest version is linked.
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
Deployment Status
.
Examples in this documentation will use all listed fields regardless of their introduced version, so please check availability before using them.
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:
qualification
) - 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:
timeEarliest
)
Contact us
If you notice issues or an 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.
Checking your requests for validity
To check your request json for validity you can download validation scripts here:
production | v1.7.0 | Validator Scripts |
develop | v1.7.0 | Validator Scripts |
experimental | v1.7.0 | Validator Scripts |
Post a new plan
HTTP-Endpoint
This endpoint is used to post a new problem description for obtaining an optimized plan based on it.
DEVEL | POST https://develop.compute-adiutabyte.de/floor-description |
PROD | POST https://production.compute-adiutabyte.de/floor-description |
Request
Example
{
"meta": {
"dateFrom": "2019-12-03",
"dateTo": "2019-12-03"
},
"parameters": {
"workerPrefs": 1
},
"tasks": [
{
"date": "2019-12-03",
"duration": 65,
"taskID": 200,
"timeEarliest": "10:00",
"timeLatest": "12:00"
},
{
"date": "2019-12-03",
"duration": 25,
"taskID": 201,
"timeEarliest": "16:00",
"timeLatest": "17:00"
}
],
"workers": [
{
"workerID": 1,
"shiftDate": "2019-12-03",
"shiftEnd": "14:00",
"shiftStart": "06:00"
},
{
"workerID": 1,
"shiftDate": "2019-12-03",
"shiftEnd": "20:00",
"shiftStart": "15:00"
},
{
"workerID": 2,
"shiftDate": "2019-12-03",
"shiftEnd": "14:00",
"shiftStart": "06:00"
}
],
"client": {
"clientID": "{1234-5678-9123}"
},
"history": {
"tasks": [
{
"taskID": 0,
"scheduling": [
{
"date": "2000-01-01"
}
]
}
],
"workers": [
{
"workerID": 0
}
]
}
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
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<Input Task> |
Array of Tasks to be planned by the optimizer. |
workers | ✔ | Array<Input Worker> |
Array of available Workers. |
history | History |
History data. |
Result
Example of an ID
AAAAAAAAABBBBBBBBBBBBBBBEEEEEEEEEEEEEEEEEDDDDDDDDDD
Posting a plan returns an ID to monitor the planning process and retrieve the solution.
Status-Codes
Number | Code | Description |
---|---|---|
200 | OK | The plan was accepted but has been submitted at least once before and is either finished or still in calculation. |
201 | CREATED | The plan was accepted and is going to be 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. |
422 | UNPROCESSABLE ENTITY | The plan generated by the backend does not match the JSON-schema. Please check the API documentation carefully or contact us to correct this failure. |
500 | INTERNAL SERVER ERROR | Backend failure, please contact us. |
Client Information
Examples:
{
"clientID": "{1234-5678-9123}"
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Type | Required | Description |
---|---|---|---|
clientID | string | ✔ | Identifies a specific client. |
Restrictions
- Minimum length: 1.
Meta Information
Examples:
{
"dateFrom": "2019-12-03",
"dateTo": "2019-12-03"
}
{
"dateFrom": "2019-12-03",
"dateTo": "2019-12-03",
"resCategory": true,
"resQualification": true,
"accuracyMode": 1.0,
"outputLanguage": 1,
"enablePlanSplitting": false,
"allowUnassignedTasks": true,
"minConcurrentSolutions": 1,
"minTaskDuration": 10
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Type | Required | Description |
---|---|---|---|
dateFrom | string (date) | ✔ | Planning horizon start, usually the earliest date on any of the tasks. |
dateTo | string (date) | ✔ | Planning horizon end, usually the latest date on any of the tasks. |
resCategory | boolean | Activate/Deactivate whether category types should be considered in the optimization. (Default: false) | |
resQualification | boolean | Activate/Deactivate whether qualifications should be considered in the optimization. (Default: false) | |
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) | |
enablePlanSplitting | boolean | (Default: true) Enables splitting the plan into disjunct plan parts. This can reduce runtime or improve pre-optimization data adjustment if the sent data can be split into smaller, self-contained sub-parts. | |
allowUnassignedTasks | boolean | (Default: false) This option enables an unassignment behavior 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 are 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 assignedWorker . The differences to an assigned task are noted in the description for the Output Task. Additionally, the info section will notify of unassignment and, if possible, the reason for it. |
|
minConcurrentSolutions | integer | Number of concurrently calculated solutions. Developer feature, use at your own risk! (Default: 1) | |
minTaskDuration | integer | Minimum value for an Input Task's duration . Task durations with a lower value are being overwritten before the optimization; breaks, travel or capacity resets are not influenced in any way. (Default: 0) |
Notes
- The options
res*
describe which fields from the dataset should be taken into account. More precisely those are:resCategories
:categories
(Task),categories
(Worker)resQualification
:qualification
(Task),qualification
(Worker)
Optimization Parameters
Examples:
{}
{
"fairDistribution": 1,
"workerPrefs": 1,
"qualificationFitting": 1,
"constancy": 1,
"groupPrefs": 1
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
All parameters (except preset
) 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 |
---|---|---|---|
fairDistribution | integer | Distribute the tasks fairly among the workers. | |
workerPrefs | integer | Try to satisfy any tasks' worker preferences. | |
qualificationFitting v0.2.0 | integer | Avoid assignments where the worker has a higher qualification than the task. Tasks without qualification count as having a qualification of 0. |
|
constancy v0.2.0 | integer | Prioritize data determined in history analysis. | |
groupPrefs v0.7.0 | integer | Keep tasks of the same groups on the same workers. |
Input Task
Examples:
{
"taskID": 200,
"date": "2019-12-03",
"duration": 65,
"timeEarliest": "10:00",
"timeLatest": "12:00"
}
{
"taskID": 200,
"externalID": "id123",
"clientID": 123,
"date": "2019-12-03",
"duration": 65,
"timeEarliest": "10:00",
"timeLatest": "12:00",
"timePriority": 2,
"prefWorkers": [1,2],
"qualification": 3,
"categories": [1],
"preassignedWorker": 2,
"initassignedWorker": 1,
"initassignedOrder": 1,
"initassignedShiftID": 1,
"precedingTasks": [1, 2],
"predecessorTasks": [3],
"assignmentPriority": 2,
"preferredGroup": 1,
"locationSiteID": 1,
"prefGender": 1
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The input task is the incoming task description for the optimizer outlining the restrictions for the optimization.
Parameter | Required | Type | Description | Depends on |
---|---|---|---|---|
taskID | ✔ | integer | The ID of this task. Task IDs need to be unique for all tasks in the input data. | |
externalID | string | A string to identify the task in the solution. Cannot be used for reference in the input data or the optimizer, it serves as a helping tool for integrations. | ||
clientID | integer | The ID of the client this task is assigned to. | ||
date | ✔ | string (date) | The date for the day to be planned. | |
duration | ✔ | integer | The time in minutes it takes to complete this task. | strict |
timeEarliest | ✔ | Time | The earliest possible starting time of this task. | |
timeLatest | ✔ | 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)
|
strict on value 5 | |
prefWorkers | Array<integer> |
The IDs of preferred workers. | workerPrefs | |
qualification | integer | The minimum qualification of the employee required to perform the task (e.g. years of experience). The algorithm tries to avoid high discrepancies between worker and task qualification. | strict / qualificationFitting v0.2.0 |
|
categories | Array<integer> |
A suitable worker has to fulfill all of these categories. | strict | |
preassignedWorker | integer | The ID of the worker who has to take over this task. This overrules any other strict restriction, for example, if the worker does not fulfil the qualification requirement, the task will still get assigned to them. | strict | |
initassignedWorker | integer | The 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 or a preassignedWorker . |
||
initassignedShiftID | integer | A shiftID to compliment either initassignedWorker or preassignedWorker in case the workerID is not unique. |
||
precedingTasks | Array<integer> |
Tasks in this list and this task will be performed by the same worker and all listed tasks 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 | |
assignmentPriority | integer | A priority for assignment (see allowUnassignedTasks ) ranging 0-5.
|
strict on value 5 | |
preferredGroup v0.7.0 | integer | Tasks with the same value in this field will be assigned to the same worker shift. | groupPrefs |
|
locationSiteID v1.0.0 | integer | An id for the position this task has to be carried out at. | ||
prefGender v0.10.0 | GenderType | The assigned worker needs to have this gender. |
Restrictions
initassignedOrder
requiresinitassignedWorker
orpreassignedWorker
.initassignedShiftID
requiresinitassignedWorker
orpreassignedWorker
.
Notes
- Regarding
qualification
: Not assigning a worker with a lower qualification is strict behavior, not assigning a worker with higher qualification depends on thequalificationFitting
parameter.
Input Worker
Examples:
{
"workerID": 1,
"shiftStart": "06:00",
"shiftEnd": "14:00",
"shiftDate": "2019-12-03"
}
{
"workerID": 1,
"shiftID": 10,
"externalID": "id123",
"shiftDate": "2019-12-03",
"shiftStart": "06:00",
"shiftEnd": "14:00",
"shiftPriority": 2,
"qualification": 1,
"categories": [4,5],
"dontAlter": true,
"dontVary": true,
"gender": 1
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The worker has both optional and required parameters as marked in the following table.
Parameter | Required | Type | Description | Depends on |
---|---|---|---|---|
workerID | ✔ | integer | The ID of the worker. Multiple workers with identical ID are allowed, those represent multiple "shifts" of the same person. | |
shiftID | integer | A second ID in case there are multiple workers with the same workerID . This one needs to be unique among all workers with the same workerID that this worker has. It can be referenced whenever a unique reference to this worker object is required. |
||
externalID | string | A string to identify the worker in the solution. Cannot be used for reference in the input data or the optimizer, it serves as a helping tool for integrations. | ||
shiftDate | ✔ | string (date) | The date of this shift. | |
shiftStart | ✔ | Time | The time this shift starts. | |
shiftEnd | ✔ | 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. | ||
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. | ||
dontVary | boolean | 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, as well as shiftID on the worker and initassignedShiftID on the task if the workerID is not unique. All assignments will be considered in Statistics and Info. |
strict | |
dontAlter | boolean | 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 . |
strict | |
gender v0.10.0 | GenderType | The gender of the worker. |
Restrictions
- Only one of
dontVary
anddontAlter
is allowed to be true
History
Examples:
{
"tasks": [
{
"taskID": 0,
"scheduling": [
{
"date": "2000-01-01"
}
]
}
],
"workers": [
{
"workerID": 0
}
]
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Required | Type | Description |
---|---|---|---|
tasks | ✔ | Array<History-Task> |
All tasks that are connected to Tasks in the optimization either by taskID or clientID . |
workers | ✔ | Array<History-Workers> |
Workers that are not included in the optimization but are referenced in History-Tasks, e.g. as assignedWorker . |
additionalTasks v0.8.0 | Array<Input Task> |
Tasks that are not part of this optimization but have historical relevance (for instance they were assigned to a plan worker). The date on those tasks can be set arbitrarily. |
History-Task
Examples:
{
"taskID": 0,
"scheduling": [
{
"date": "2000-01-01"
}
]
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Required | Type | Description |
---|---|---|---|
taskID | ✔ | integer | Task ID for referencing task in planning tasks. |
scheduling | ✔ | Array<History-Assignment> |
All considered historical assignments of this task. |
History-Assignment
Examples:
{
"date": "2000-01-01"
}
{
"date": "2000-01-01",
"locationSiteID": 1,
"timeScheduled": "00:00",
"assignedWorker": 0,
"assignedShiftID": 1,
"assignedOrder": 1,
"timeScheduledAutomatically": "00:00",
"assignedWorkerAutomatically": 0,
"assignedShiftIDAutomatically": 1,
"assignedOrderAutomatically": 1,
"actualStartTime": "00:00",
"actualWorker": 0,
"actualShiftID": 1,
"actualOrder": 1
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Required | Type | Description |
---|---|---|---|
date | ✔ | string (Date) | Date this assignment was on. |
locationSiteID v1.0.0 | integer | The id for the location the task was carried out at at the time. | |
timeScheduled | 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. | |
assignedShiftID v1.0.0 | integer | An id for the assigned shift of the assigned worker. | |
assignedOrder v1.0.0 | integer | The order number this task was assigned to the worker shift. | |
timeScheduledAutomatically | 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. | |
assignedShiftIDAutomatically v1.0.0 | integer | An id for the assigned shift of the assigned worker. | |
assignedOrderAutomatically v1.0.0 | integer | The order number this task was assigned to the worker shift. | |
actualStartTime | 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. | |
actualShiftID v1.0.0 | integer | An id for the assigned shift of the assigned worker. | |
actualOrder v1.0.0 | integer | The order number this task was assigned to the worker shift. |
History-Worker
Examples:
{
"workerID": 0
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Required | Type | Description |
---|---|---|---|
workerID | ✔ | integer | ID of a worker that is not present in the input data. Has to be unique among all History-Workers. |
Check status/retrieve a Plan
HTTP-Endpoint
This endpoint is used to get the status of a plan or retrieve the plan once the calculation has been finished.
DEVEL | GET https://develop.compute-adiutabyte.de/plan/<ID> |
PROD | GET https://production.compute-adiutabyte.de/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.
Status-Codes
Number | Code | Description |
---|---|---|
200 | OK | The plan will be delivered. |
404 | NOT FOUND | The requested ID does not exist. |
406 | NOT ACCEPTABLE | The given Accept parameter in the header could not be used. |
422 | UNPROCESSABLE ENTITY | The plan generated by the backend does not match the JSON-schema. Please contact us to correct this failure. |
423 | LOCKED | The plan is currently optimized. Try again later to check if the calculation has finished. |
500 | INTERNAL SERVER ERROR | An error occurred in the backend. Please contact us to check why this has happened. |
Result
Examples:
{
"requestID": "id2103",
"meta": {
"dateFrom": "2019-12-03",
"dateTo": "2019-12-03"
},
"parameters": {
"workerPrefs": 1
},
"workers": [
{
"workerID": 1,
"shiftStart": "06:00",
"shiftEnd": "14:00",
"info": "text",
"shiftDate": "2019-12-03"
},
{
"workerID": 2,
"shiftStart": "05:00",
"shiftEnd": "16:00",
"shiftDate": "2019-12-03",
"info": "text",
}
],
"tasks": [
{
"taskID": 200,
"date": "2019-12-03",
"duration": 65,
"timeEarliest": "10:00",
"timeLatest": "12:00",
"timeScheduled": "11:01",
"assignedWorker": 2,
"info": "This task assignment causes negative arrival slack: -6"
},
{
"taskID": 200,
"date": "2019-12-03",
"duration": 65,
"timeEarliest": "10:00",
"timeLatest": "12:00",
"info": "This task was unassigned"
}
],
"info": {
"feasible": false
},
"statistics": {
"impact": [
{
"label": "Anticategories",
"value": 0.123
}
],
"unassignedTaskIDs": [1,2,3],
"unassignableTaskIDs": [1,2,3]
},
"backendVersion": {
"schema": "v0.49.9",
"version": "v2.25.12",
"rev": "abcde12"
},
"client": {
"clientID": "{1234-5678-9123}"
}
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The resulting plan mostly extends the Request by the fields marked "Extension" below:
Extension | 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<Output Task> |
Array of output tasks. | |
workers | ✔ | Array<Output Worker> |
Array of available workers. | |
➞ | statistics | ✔ | statistics | Some statistics about the plan. |
➞ | info | ✔ | info | Some textual information about the plan. |
➞ | backendVersion | ✔ | Backend Version | Used validation/ calculation version. |
Error Result
Example
{
"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,
"taskID": 12,
"backendVersion": {
"schema": "v0.49.9",
"version": "v2.25.12",
"rev": "abcde12"
},
"additionalErrors": [
{
"errorID": 129,
"error_msg": " |-| ERROR: Task #13 has itself assigned as preceding task. (129) |-| contact email: support@adiutabyte.de",
"taskID": 13
}
]
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
If your request contains errors which leads to unsatisfiable plans, you will receive a error response instead of a 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. | |
taskExternalID v0.11.0 | string | The externalID corresponding to the taskID (if set). |
|
workerID | integer | If the error occurred by a specific worker, their ID will be referenced. | |
workerExternalID v0.11.0 | string | The externalID corresponding to the workerID (if set). |
|
backendVersion | ✔ | Backend Version | Used validation/ calculation version. |
additionalErrors v0.9.0 | Array<Object> |
During validation, errors do not necessarily terminate the program instantly. Instead they are collected and output in this list (the first validation error being output in the "main section" of the error result, each following in additionalErrors ). This is handy if there are multiple invalid tasks/workers/..., as all of these issues get caught during validation and output here. However, later entries in the additionalErrors list may be less reliable, since they could be based on an earlier failed validation and not be a problem with the input data (e.g. duplicated taskID s might lead to issues with precedingTasks ). |
The objects in additionalErrors
contain the following fields:
Parameter | Required | Type | Description |
---|---|---|---|
error_msg | ✔ | string | All fields exactly like in the "main" description above. |
errorID | ✔ | integer | |
taskID | integer | ||
taskExternalID v0.11.0 | string | ||
workerID | integer | ||
workerExternalID v0.11.0 | string |
The error_msg
gets translated based on language settings.
Type of error | errorID range |
---|---|
Internal errors (bugs). Please contact us so that we can fix the issue. |
|
Input object is missing required data or the given data is invalid for a required element. |
|
Input data fails validation (basic correctness or plausibility). Please check the error_msg for details! |
|
Error-ID
A list of errorID
values and explanations can be found here.
Backend Version
Examples:
{
"schema": "v0.0.0"
}
{
"schema": "v0.0.0",
"version": "v0.0.0",
"rev": "abde12"
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | 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. |
Output Task
Examples:
{
... // see Input Task
"info": "text"
}
{
... // see Input Task
"timeScheduled": "12:10",
"assignedWorker": 1,
"info": "text",
"finalassignedOrder": 4
}
{
... // see Input Task
"timeScheduled": "12:10",
"assignedWorker": 1,
"assignedShiftID": 2,
"info": "text",
"finalassignedOrder": 4
},
production | v1.7.0 | JSON-Schema (unassigned) |
JSON-Schema (assigned) | ||
develop | v1.7.0 | JSON-Schema (unassigned) |
JSON-Schema (assigned) | ||
experimental | v1.7.0 | JSON-Schema (unassigned) |
JSON-Schema (assigned) |
The json schema for the Output Task extends the schema of the Input Task by all the fields marked "Extension" in the table below. If allowUnassignedTasks
was set to true, an "unassigned version" of the output task can be returned which is missing all assignment data.
Extension | Parameter | Required if assigned | Required if unassigned | Type | Description |
---|---|---|---|---|---|
All fields unchanged from Input-Task. | |||||
➞ | timeScheduled | ✔ | Time | The planned time to start this task by the assigned worker. | |
➞ | assignedWorker | ✔ | integer | The ID (workerID ) of the assigned worker who will perform this task. |
|
➞ | assignedShiftID | integer | The shiftID to which the task is assigned to. |
||
➞ | finalassignedOrder | ✔ | integer | The order number within the assigned tour starting with number 1 . |
|
➞ | info | ✔ | ✔ | string | Additional information about the task. |
Output Worker
Examples:
{
... // See Input Worker
"info": "text"
}
{
... // See Input Worker
"info": "text",
"tourStart": "12:10",
"tourEnd": "12:30",
"totalTaskTime": 100
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The json schema for the Output Worker extends the schema of the Input Worker by all the fields marked "Extension" in the table below:
Extension | Parameter | Required | Type | Description |
---|---|---|---|---|
All fields unchanged from Input-Worker. | ||||
➞ | info | string | Some textual information about the worker, e.g. for delays. | |
➞ | tourStart | Time | The actual time this worker starts their tour. The value is set only if the worker has a task assigned. If the worker has a task assigned and tourStartsOnShiftStart is set to true, it will always be equal to shiftStart . |
|
➞ | tourEnd | Time | The actual time this worker ends their tour, including travel to its endLocation and any capacity resets. |
|
➞ | totalTaskTime | ✔ | integer | The sum of all task durations on this worker. Does not include breaks or capacity reset duration. |
Statistics
Examples:
{
"impact": [
{
"label": "Anticategories",
"value": 0.123
}
],
"unassignedTaskIDs": [1,2,3],
"unassignableTaskIDs": [1,2,3],
"timeWindowViolationTaskIDs": [1,2,3],
"history": {
"tasks": [
{
"taskID": 1,
"preassignedWorker": 1,
"preferences": [
{
"workerID": 0,
"value": 0.123
}
]
}
]
}
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The statistics
provide some general data for evaluating the result. They are based on the adjusted data that the optimization is performed on. Differences to the tasks'/workers' input data are noted in their respective info
fields.
Parameter | Type | Required | Description |
---|---|---|---|
impact | Array<Object<label: string, value: number>> |
✔ | 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. You can find all possible labels here. |
unassignedTaskIDs | Array<integer> |
taskIDs of all tasks that were not assigned during optimization. |
|
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). |
|
timeWindowViolationTaskIDs | Array<integer> |
taskIDs of all tasks are not assigned within their given time window. |
|
history v0.8.0 | Object | All data determined from the history. |
The history
entry contains the data from the history analysis:
Parameter | Type | Required | Description |
---|---|---|---|
tasks | Array | ✔ | Historical data for each task. |
Each entry in tasks
has the following fields:
Parameter | Type | Required | Description |
---|---|---|---|
taskID | integer | ✔ | Unique id to connect the task to a task in the tasks array of the request. |
preferences | Array<Object<workerID: integer, value: number>> |
For each relevant worker, the preference of this task towards the worker. Higher number means higher preference. | |
preassignedWorker | integer | The worker this task was preassigned to by history analysis. |
Info
Examples:
{
"feasible": false
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The info
texts provide some textual context to the solution. They are based on the adjusted data that the optimization is performed on. Differences to the tasks'/workers' input data are noted in their respective info
fields.
Parameter | Required | Type | Description |
---|---|---|---|
feasible | ✔ | boolean | Set to false if any strict requirements are violated in the solution. |
Additional Validation
Every request must adhere to the defined schemas or it cannot be processed. However, even if it does, there might still be issues with the contained data. For that reason, a content validation is performed after accepting the request, the details of which are listed below.
There are multiple times a validation is performed on the input data. If an issue is found, the corresponding error message will tell you exactly at which step the validation failed:
- Validation of raw input data, excluding data excluded by
resCategory
orresQualification
. - Validation of input data after removing all unassignable tasks (this is only relevant is
allowUnassignedTasks
is set to true). - Validation of history adjusted data (this is only relevant if a
history
is included in the input data) - Validation after adjusting data (if
enablePlanSplitting
is true, the error message will tell you which subset of data had the issue).
If allowUnassignedTasks
is set to true, the first of these validations is allowed to fail some validations (the list below will tell you which). In this case the task is simply removed from calculation. You can determine these unassignable tasks from their info
section in the output or the array unassignableTasks
in statistics
.
List of all content requirements
errorID | allowed to fail | Requirement |
---|---|---|
121 | taskID must be unique among all tasks. |
|
123 | Task time windows must be large enough that duration fits inside. |
|
124 | ✔ | Task sets which have to be assigned to the same worker must have a worker that is not forbidden for any of them via any strict restriction. |
126 | For certain task chains which have a fixed order (e.g. predecessorTasks chains), if one task in the chain is assigned to a dontVary- or dontAlter-Worker, all of them must be. |
|
127 | Task time windows must be large enough that minTaskDuration fits inside (if set). |
|
1200 | A worker with the workerID of each task's initassignedWorker must exist (if set). |
|
1201 | If an initassignedOrder is set, initassignedWorker must be set as well. |
|
1202 | ✔ | Tasks must have a worker that is not forbidden via any strict restriction. Exempt are tasks with an assignment to a dontVary-Worker. |
1203 | Tasks must not have themselves as one of their precedingTasks . |
|
1204 | For each entry in precedingTasks , a task with that taskID must exist. |
|
1205 | Tasks must not have themselves as one of their predecessorTasks . |
|
1206 | shiftEnd must not be before shiftStart . |
|
1207 | Shifts of workers with the same workerID must not overlap. |
|
1209 | Multishift-Workers with dontVary or dontAlter set to true must have a shiftID . |
|
1210 | It is not allowed for multiple task to have exactly one entry in predecessorTasks and have it be the same value. |
|
1211 | A task with set preassignedWorker and set initassignedWorker where one of the workers has dontVary or dontAlter set to true, must have preassignedWorker and initassignedWorker set in a way that they unambiguously refer to the same worker. |
|
1212 | A task assigned to a dontVary- or dontAlter-Worker via preassignedWorker or initassignedWorker must have an initassignedOrder . |
|
1213 | All tasks assigned to the same dontVary- or dontAlter-Worker via preassignedWorker or initassignedWorker must have a different initassignedOrder . |
|
1214 | For Multishift-Workers, shiftStart must not be equal to shiftEnd . |
|
1215 | Certain task chains which have a fixed order (e.g. predecessorTasks chains) and that are assigned to a dontVary- or dontAlter-Worker must have their chain order reflected in their initassignedOrder . |
|
1216 | Only one of dontVary and dontAlter can be set to true. |
|
1217 | shiftID must be unique for all workers with the same workerID . |
|
1218 | Tasks with preassignedWorker or initassignedWorker where at least one of the workers with that workerID has dontVary or dontAlter set to true, must have an initassignedShiftID . |
|
1219 removed in v1.0.6 | If timeliness is not set to zero, tasks with preassignedWorker and aninitassignedShiftID with the worker being a multishift-worker must have their task time window overlap with the worker's shift. |
|
1220 | (Worker) shiftStart and shiftEnd must not be earlier than dateFrom at 00:00, shiftDate must not be later than dateTo . (Task) timeEarliest and timeLatest must not be earlier than dateFrom at 00:00, date must not be later than dateTo . |
|
1221 v0.11.1 | If there is exactly one entry in predecessorTasks , a task with that ID must exist. |
|
1503 | workerID s of history workers must not be used in workers of the workers array. |
|
1504 | workerID s of history workers must be unique among all history workers. |
|
1505 | taskID s of history tasks must be unique among all history tasks. |
|
1506 | All workers referenced in history tasks must exist either in the workers array or among the history workers. |
|
1507 | History assignments of the same task must be on different dates. | |
1508 | No history data must be equal or later than dateFrom . |
|
1509 v0.8.0 | taskID s of history tasks have to refer to a task among the objects in tasks or the history tasks. |
|
1510 v0.8.0 | taskID s must be unique among the additional tasks. |
|
1511 v0.8.0 | There must not be two tasks from the additional tasks and planning tasks with the same taskID . |
Examples
The following examples shall provide a starting point to build from when using the API for the first time. If you'd like to see one added, please contact us.
Posting/ Retrieving a plan
The example to the right provides a simple javascript template to post/get a request/response. Authentication details can be found here.
require('cross-fetch/polyfill');
const fetch = require('cross-fetch');
const AmazonCognitoIdentity = require('amazon-cognito-identity-js');
// authentication
const userPool = new AmazonCognitoIdentity.CognitoUserPool({
UserPoolId: "[myUserPoolId]", // see authentication page
ClientId: "[myClientId]" // see authentication page
});
const authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails({
Username: "[myUserName]", // see login details of your adiutaByte account
Password: "[myPassword]"
});
const cognitoUser = new AmazonCognitoIdentity.CognitoUser({
Username: "[myUserName]", // see login details of your adiutaByte account
Pool: userPool
});
const token = await new Promise((resolve, reject) => cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {
const thisToken = result.getIdToken().getJwtToken();
resolve(thisToken);
},
onFailure: function (err) {
console.log(err);
reject();
}
}));
// posting a request
const headers = {
'Content-Type': 'application/json',
'Authorization': token
};
const request = {
meta: {
dateFrom: "2019-12-03",
dateTo: "2019-12-03"
},
parameters: {},
tasks: [
{
date: "2019-12-03",
duration: 65,
taskID: 200,
timeEarliest: "10:00",
timeLatest: "12:00"
}
],
workers: [
{
workerID: 1,
shiftStart: "03:00",
shiftEnd: "12:00",
shiftDate: "2019-12-03"
}
]
};
const postOptions = {
method: 'post',
headers: new Headers(headers),
body: JSON.stringify(request)
};
const postURL = `https://[env].compute-adiutabyte.de/floor-description`; // see endpoint section
const ID = await new Promise((resolve, reject) => fetch(postURL, postOptions)
.then(async res => {
if (res.ok) {
const data = await res.json();
console.log("Successfully posted request! ID:", data);
resolve(data);
}
else {
console.error("Error while posting request:", res.status);
reject();
}
}));
// get solution
let status = 423;
while (status === 423) {
const getURL = `https://[env].compute-adiutabyte.de/plan/${ID}`; // see endpoint section
const getOptions = {
method: 'get',
headers: new Headers(headers)
};
const solution = await new Promise((resolve, reject) => fetch(getURL, getOptions)
.then(async res => {
status = res.status;
resolve(res);
}));
if (status === 200) {
const solutionText = await solution.text();
console.log("Solution:", JSON.parse(solutionText));
break;
}
else if (status !== 423) {
console.error("Error while getting solution:", status);
break;
}
await new Promise(resolve => setTimeout(resolve, 5000));
}
Common data types
Integers/Numbers
Examples:
{
"integer_u32": 12,
"integer_s32": -12,
"number_u32" : 7.184535,
"number_s32" : -7.184535,
"number_u64" : 7.184535,
"number_s64" : -7.184535,
"fraction" : 0.2
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | 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$ |
fraction | number | $0 \leq x \leq 1$ |
Please refer to the respective linked json schema to determine which type of integer/number gets used.
Date
Examples:
"2018-01-10"
"2019-12-03"
"2020-05-23"
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | 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:
"06:59"
"15:59"
"1230:33"
"-39:12"
"03:01"
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
A string of either format "hh:mm"
or "-hh:mm"
:
"hh"
: hours, $ 0 \leq x \leq 10^{10} -1 $"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:
date
for any Time values in Input Task and Output Task.shiftDate
for any Time values in Input Worker and Output Worker.
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
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
An integer in the range $0 \leq x \leq 4$.
VehicleTypeID | Description |
---|---|
0 | Car |
1 | Bicycle |
2 | Pedestrian |
3 | Truck |
4 | Public Transport Approximation |
GenderType
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
An integer in the range $0 \leq x \leq 3$.
GenderTypeID | Description |
---|---|
0 | Not provided |
1 | Male |
2 | Female |
3 | Other |
LanguageType
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
An integer in the range $0 \leq x \leq 1$.
LanguageTypeID | Description |
---|---|
0 | German |
1 | English |
Weekday
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
An integer in the range $0 \leq x \leq 6$.
value | Description |
---|---|
0 | Sunday |
1 | Monday |
2 | Tuesday |
3 | Wednesday |
4 | Thursday |
5 | Friday |
6 | Saturday |
Conventions
- All number values of times (task durations, ...) use the unit minutes.
- Days start at 00:00 and end at 23:59.
Deployment Status
FloorPlanner Version | API Schema Validation Version | |
---|---|---|
production | v1.1.0 | v1.7.0 |
develop | v1.1.0 | v1.7.0 |
experimental | v1.1.0 | v1.7.0 |
Getting the deployed version
Aside from checking this page, you can also get the deployed versions via a GET request.
HTTP-Endpoint
DEVEL | GET https://develop.compute-adiutabyte.de/floor-version |
PROD | GET https://production.compute-adiutabyte.de/floor-version |
Result
{
"version": "v3.9.15",
"schema": "v0.78.0",
"meta-data": "v15",
"api-scripts": "v1.5.0"
}
Parameter | Type | Description |
---|---|---|
version | version | The backend version used for calculating results. |
schema | version | The json schema version used for validating input and output. |
meta_data | version | The meta data version used to determine client specific behavior. |
api_scripts | version | The api script version. |
Status-Codes
Number | Code | Description |
---|---|---|
200 | OK | The version data will be delivered. |
500 | INTERNAL SERVER ERROR | An error occurred in the backend. Please contact us to check why this has happened. |
Changelog
2024-01-23
- In Error Result: Added
workerExternalID
with tagv0.11.0
. - In Error Result: Added
taskExternalID
with tagv0.11.0
.
2024-01-07
- Added section Checking your requests for validity.
2023-12-13
- In Input Task: Added
prefGender
with tagv0.10.0
. - In Input Worker: Added
gender
with tagv0.10.0
. - In History Assignment: Added
assignedShiftID
with tagv1.0.0
. - In History Assignment: Added
assignedOrder
with tagv1.0.0
. - In History Assignment: Added
assignedShiftIDAutomatically
with tagv1.0.0
. - In History Assignment: Added
assignedOrderAutomatically
with tagv1.0.0
. - In History Assignment: Added
actualShiftID
with tagv1.0.0
. - In History Assignment: Added
actualOrder
with tagv1.0.0
.
2023-12-03
- In Input Task: Added
locationSiteID
with tagv1.0.0
. - In History Assignment: Added
locationSiteID
with tagv1.0.0
.
2023-11-11
- In Error Result: Added
additionalErrors
with tagv0.9.0
.
2023-10-21
- In Statistics: Added
history
with tagv0.8.0
. - In Additional Validation: Added validations 1509-1511 with tag
v0.8.0
.
2023-10-18
- In Optimization Parameter: Added description text to
constancy
. - In Additional Validation: Added validations 1503-1508.
2023-10-16
- Added Additional Validation.
2023-10-12
- In Optimization Parameters: Added
groupPrefs
with tagv0.7.0
. - In Input Task: Added
clientID
with tagv0.7.0
. - In Input Task: Added
preferredGroup
with tagv0.7.0
.
2023-09-19
- In Optimization Parameters: Added
qualificationFitting
with tagv0.2.0
. - In Optimization Parameters: Added
constancy
with tagv0.2.0
. - In Input Task: Changed "Depends on" entry of
qualification
, addedqualificationFitting
with tagv0.2.0
. - In Input Task: Added section "Notes".
2023-09-16
- Created documentation page.