Real-time planning: driver ill
| This guide details the currently supported real-time planning features. If you are using the Patch (preview) feature, please see Real-time planning with patches |
There are many situations where Real-time planning is necessary.
Sometimes drivers become ill and must take the day off or, if they have already started work, go home part way through a shift.
Consider the following shift schedule:
Ann has three jobs assigned with two stops each: Stop E, Stop C, Stop A, Stop B, Stop D and Stop F. Carl has one job assigned with two stops: Stop G and Stop H.
If Ann calls in sick before the shift starts or goes home part way through the day due to illness, her stops must be reassigned to another driver or rescheduled for another day.
This guide explains real-time planning: driver ill with the following:
1. Batch schedule: driver ill
Learn how to configure an API Key to run the examples in this guide:
In the examples, replace |
The original schedule was generated from the following input dataset during the regular batch scheduling:
-
Input
-
Output
Try this example in Timefold Platform by saving this JSON into a file called sample.json and make the following API call:
|
curl -X POST -H "Content-type: application/json" -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/pickup-delivery-routing/v1/route-plans [email protected]
{
"config": {
"run": {
"name": "Original shift plan: driver ill example"
}
},
"modelInput": {
"drivers": [
{
"id": "Carl",
"shifts": [
{
"id": "Carl Mon",
"startLocation": [33.77284, -84.42989],
"minStartTime": "2027-02-01T09:00:00Z",
"maxEndTime": "2027-02-01T13:30:00Z"
}
]
},
{
"id": "Ann",
"shifts": [
{
"id": "Ann Mon",
"startLocation": [33.79426, -84.330114],
"minStartTime": "2027-02-01T09:00:00Z",
"maxEndTime": "2027-02-01T13:30:00Z"
}
]
}
],
"jobs": [
{
"id": "Job 1",
"stops": [
{
"id": "Stop A",
"name": "Stop A",
"location": [33.74648, -84.46461],
"duration": "PT30M"
},
{
"id": "Stop B",
"name": "Stop B",
"location": [33.65207, -84.46496],
"duration": "PT30M"
}
]
},
{
"id": "Job 2",
"stops": [
{
"id": "Stop C",
"name": "Stop C",
"location": [33.77911, -84.49644],
"duration": "PT30M"
},
{
"id": "Stop D",
"name": "Stop D",
"location": [33.65979, -84.46366],
"duration": "PT30M"
}
]
},
{
"id": "Job 3",
"stops": [
{
"id": "Stop E",
"name": "Stop E",
"location": [ 33.78468, -84.48469],
"duration": "PT30M"
},
{
"id": "Stop F",
"name": "Stop F",
"location": [ 33.67966, -84.30062 ],
"duration": "PT30M"
}
]
},
{
"id": "Job 4",
"stops": [
{
"id": "Stop G",
"name": "Stop G",
"location": [ 33.73698, -84.34712 ],
"duration": "PT30M"
},
{
"id": "Stop H",
"name": "Stop H",
"location": [ 33.74661, -84.47359 ],
"duration": "PT30M"
}
]
}
]
}
}
To request the solution, locate the ID from the response to the post operation and append it to the following API call:
|
curl -X GET -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/pickup-delivery-routing/v1/route-plans/<ID>
{
"metadata": {
"id": "ID",
"originId": "ID",
"name": "Original shift plan: driver ill example",
"submitDateTime": "2026-04-09T17:06:00.955838+02:00",
"startDateTime": "2026-04-09T17:06:01.006547+02:00",
"activeDateTime": "2026-04-09T17:06:01.008361+02:00",
"completeDateTime": "2026-04-09T17:06:31.02371+02:00",
"shutdownDateTime": "2026-04-09T17:06:31.023713+02:00",
"solverStatus": "SOLVING_COMPLETED",
"score": "0hard/0medium/-6136soft",
"validationResult": {
"summary": "OK"
}
},
"modelOutput": {
"drivers": [
{
"id": "Carl",
"shifts": [
{
"id": "Carl Mon",
"startTime": "2027-02-01T09:00:00Z",
"itinerary": [
{
"id": "Stop G",
"arrivalTime": "2027-02-01T09:10:21Z",
"startServiceTime": "2027-02-01T09:10:21Z",
"departureTime": "2027-02-01T09:40:21Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT10M21S",
"travelDistanceMetersFromPreviousStandstill": 8629,
"minStartTravelTime": "2027-02-01T00:00:00Z",
"load": [],
"kind": "STOP"
},
{
"id": "Stop H",
"arrivalTime": "2027-02-01T09:54:26Z",
"startServiceTime": "2027-02-01T09:54:26Z",
"departureTime": "2027-02-01T10:24:26Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT14M5S",
"travelDistanceMetersFromPreviousStandstill": 11743,
"minStartTravelTime": "2027-02-01T00:00:00Z",
"load": [],
"kind": "STOP"
}
],
"metrics": {
"totalTravelTime": "PT30M25S",
"travelTimeFromStartLocationToFirstStop": "PT10M21S",
"travelTimeBetweenStops": "PT14M5S",
"travelTimeFromLastStopToEndLocation": "PT5M59S",
"totalTravelDistanceMeters": 25355,
"travelDistanceFromStartLocationToFirstStopMeters": 8629,
"travelDistanceBetweenStopsMeters": 11743,
"travelDistanceFromLastStopToEndLocationMeters": 4983,
"endLocationArrivalTime": "2027-02-01T10:30:25Z"
}
}
]
},
{
"id": "Ann",
"shifts": [
{
"id": "Ann Mon",
"startTime": "2027-02-01T09:00:00Z",
"itinerary": [
{
"id": "Stop E",
"arrivalTime": "2027-02-01T09:17:11Z",
"startServiceTime": "2027-02-01T09:17:11Z",
"departureTime": "2027-02-01T09:47:11Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT17M11S",
"travelDistanceMetersFromPreviousStandstill": 14324,
"minStartTravelTime": "2027-02-01T00:00:00Z",
"load": [],
"kind": "STOP"
},
{
"id": "Stop C",
"arrivalTime": "2027-02-01T09:48:41Z",
"startServiceTime": "2027-02-01T09:48:41Z",
"departureTime": "2027-02-01T10:18:41Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT1M30S",
"travelDistanceMetersFromPreviousStandstill": 1250,
"minStartTravelTime": "2027-02-01T00:00:00Z",
"load": [],
"kind": "STOP"
},
{
"id": "Stop A",
"arrivalTime": "2027-02-01T10:24:17Z",
"startServiceTime": "2027-02-01T10:24:17Z",
"departureTime": "2027-02-01T10:54:17Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT5M36S",
"travelDistanceMetersFromPreviousStandstill": 4671,
"minStartTravelTime": "2027-02-01T00:00:00Z",
"load": [],
"kind": "STOP"
},
{
"id": "Stop B",
"arrivalTime": "2027-02-01T11:06:53Z",
"startServiceTime": "2027-02-01T11:06:53Z",
"departureTime": "2027-02-01T11:36:53Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT12M36S",
"travelDistanceMetersFromPreviousStandstill": 10498,
"minStartTravelTime": "2027-02-01T00:00:00Z",
"load": [],
"kind": "STOP"
},
{
"id": "Stop D",
"arrivalTime": "2027-02-01T11:37:55Z",
"startServiceTime": "2027-02-01T11:37:55Z",
"departureTime": "2027-02-01T12:07:55Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT1M2S",
"travelDistanceMetersFromPreviousStandstill": 867,
"minStartTravelTime": "2027-02-01T00:00:00Z",
"load": [],
"kind": "STOP"
},
{
"id": "Stop F",
"arrivalTime": "2027-02-01T12:26:13Z",
"startServiceTime": "2027-02-01T12:26:13Z",
"departureTime": "2027-02-01T12:56:13Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT18M18S",
"travelDistanceMetersFromPreviousStandstill": 15249,
"minStartTravelTime": "2027-02-01T00:00:00Z",
"load": [],
"kind": "STOP"
}
],
"metrics": {
"totalTravelTime": "PT1H11M51S",
"travelTimeFromStartLocationToFirstStop": "PT17M11S",
"travelTimeBetweenStops": "PT39M2S",
"travelTimeFromLastStopToEndLocation": "PT15M38S",
"totalTravelDistanceMeters": 59891,
"travelDistanceFromStartLocationToFirstStopMeters": 14324,
"travelDistanceBetweenStopsMeters": 32535,
"travelDistanceFromLastStopToEndLocationMeters": 13032,
"endLocationArrivalTime": "2027-02-01T13:11:51Z"
}
}
]
}
],
"unassignedJobs": []
},
"inputMetrics": {
"jobs": 4,
"stops": 8,
"drivers": 2,
"driverShifts": 2,
"pinnedStops": 0
},
"kpis": {
"totalTravelTime": "PT1H42M16S",
"totalTravelDistanceMeters": 85246,
"totalActivatedDrivers": 2,
"totalUnassignedJobs": 0,
"totalAssignedJobs": 4,
"assignedMandatoryJobs": 4,
"totalUnassignedStops": 0,
"totalAssignedStops": 8,
"assignedMandatoryStops": 8,
"travelTimeFromStartLocationToFirstStop": "PT27M32S",
"travelTimeBetweenStops": "PT53M7S",
"travelTimeFromLastStopToEndLocation": "PT21M37S",
"travelDistanceFromStartLocationToFirstStopMeters": 22953,
"travelDistanceBetweenStopsMeters": 44278,
"travelDistanceFromLastStopToEndLocationMeters": 18015
}
}
modelOutput contains Carl’s and Ann’s shift itinerary.
2. Real-time planning update: driver ill
When a driver becomes ill before a shift has started, they can be removed from the input dataset and the dataset can be resubmitted.
Timefold will reassign jobs that can be reassigned and leave any remaining jobs unassigned to be rescheduled for another day.
-
Input
-
Output
Try this example in Timefold Platform by saving this JSON into a file called sample.json and make the following API call:
|
curl -X POST -H "Content-type: application/json" -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/pickup-delivery-routing/v1/route-plans [email protected]
{
"config": {
"run": {
"name": "Original shift plan: driver ill example"
}
},
"modelInput": {
"drivers": [
{
"id": "Carl",
"shifts": [
{
"id": "Carl Mon",
"startLocation": [33.77284, -84.42989],
"minStartTime": "2027-02-01T09:00:00Z",
"maxEndTime": "2027-02-01T13:30:00Z"
}
]
}
],
"jobs": [
{
"id": "Job 1",
"stops": [
{
"id": "Stop A",
"name": "Stop A",
"location": [33.74648, -84.46461],
"duration": "PT30M"
},
{
"id": "Stop B",
"name": "Stop B",
"location": [33.65207, -84.46496],
"duration": "PT30M"
}
]
},
{
"id": "Job 2",
"stops": [
{
"id": "Stop C",
"name": "Stop C",
"location": [33.77911, -84.49644],
"duration": "PT30M"
},
{
"id": "Stop D",
"name": "Stop D",
"location": [33.65979, -84.46366],
"duration": "PT30M"
}
]
},
{
"id": "Job 3",
"stops": [
{
"id": "Stop E",
"name": "Stop E",
"location": [ 33.78468, -84.48469],
"duration": "PT30M"
},
{
"id": "Stop F",
"name": "Stop F",
"location": [ 33.67966, -84.30062 ],
"duration": "PT30M"
}
]
},
{
"id": "Job 4",
"stops": [
{
"id": "Stop G",
"name": "Stop G",
"location": [ 33.73698, -84.34712 ],
"duration": "PT30M"
},
{
"id": "Stop H",
"name": "Stop H",
"location": [ 33.74661, -84.47359 ],
"duration": "PT30M"
}
]
}
]
}
}
To request the solution, locate the ID from the response to the post operation and append it to the following API call:
|
curl -X GET -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/pickup-delivery-routing/v1/route-plans/<ID>
{
"metadata": {
"id": "ID",
"originId": "ID",
"name": "Original shift plan: driver ill example",
"submitDateTime": "2026-04-09T17:09:04.242218+02:00",
"startDateTime": "2026-04-09T17:09:04.39681+02:00",
"activeDateTime": "2026-04-09T17:09:04.398884+02:00",
"completeDateTime": "2026-04-09T17:09:34.414763+02:00",
"shutdownDateTime": "2026-04-09T17:09:34.414766+02:00",
"solverStatus": "SOLVING_COMPLETED",
"score": "0hard/-20000medium/-5073soft",
"validationResult": {
"summary": "OK"
}
},
"modelOutput": {
"drivers": [
{
"id": "Carl",
"shifts": [
{
"id": "Carl Mon",
"startTime": "2027-02-01T09:00:00Z",
"itinerary": [
{
"id": "Stop E",
"arrivalTime": "2027-02-01T09:06:17Z",
"startServiceTime": "2027-02-01T09:06:17Z",
"departureTime": "2027-02-01T09:36:17Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT6M17S",
"travelDistanceMetersFromPreviousStandstill": 5233,
"minStartTravelTime": "2027-02-01T00:00:00Z",
"load": [],
"kind": "STOP"
},
{
"id": "Stop F",
"arrivalTime": "2027-02-01T10:01:03Z",
"startServiceTime": "2027-02-01T10:01:03Z",
"departureTime": "2027-02-01T10:31:03Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT24M46S",
"travelDistanceMetersFromPreviousStandstill": 20642,
"minStartTravelTime": "2027-02-01T00:00:00Z",
"load": [],
"kind": "STOP"
},
{
"id": "Stop G",
"arrivalTime": "2027-02-01T10:40:17Z",
"startServiceTime": "2027-02-01T10:40:17Z",
"departureTime": "2027-02-01T11:10:17Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT9M14S",
"travelDistanceMetersFromPreviousStandstill": 7689,
"minStartTravelTime": "2027-02-01T00:00:00Z",
"load": [],
"kind": "STOP"
},
{
"id": "Stop H",
"arrivalTime": "2027-02-01T11:24:22Z",
"startServiceTime": "2027-02-01T11:24:22Z",
"departureTime": "2027-02-01T11:54:22Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT14M5S",
"travelDistanceMetersFromPreviousStandstill": 11743,
"minStartTravelTime": "2027-02-01T00:00:00Z",
"load": [],
"kind": "STOP"
},
{
"id": "Stop A",
"arrivalTime": "2027-02-01T11:55:22Z",
"startServiceTime": "2027-02-01T11:55:22Z",
"departureTime": "2027-02-01T12:25:22Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT1M",
"travelDistanceMetersFromPreviousStandstill": 830,
"minStartTravelTime": "2027-02-01T00:00:00Z",
"load": [],
"kind": "STOP"
},
{
"id": "Stop B",
"arrivalTime": "2027-02-01T12:37:58Z",
"startServiceTime": "2027-02-01T12:37:58Z",
"departureTime": "2027-02-01T13:07:58Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT12M36S",
"travelDistanceMetersFromPreviousStandstill": 10498,
"minStartTravelTime": "2027-02-01T00:00:00Z",
"load": [],
"kind": "STOP"
}
],
"metrics": {
"totalTravelTime": "PT1H24M33S",
"travelTimeFromStartLocationToFirstStop": "PT6M17S",
"travelTimeBetweenStops": "PT1H1M41S",
"travelTimeFromLastStopToEndLocation": "PT16M35S",
"totalTravelDistanceMeters": 70450,
"travelDistanceFromStartLocationToFirstStopMeters": 5233,
"travelDistanceBetweenStopsMeters": 51402,
"travelDistanceFromLastStopToEndLocationMeters": 13815,
"endLocationArrivalTime": "2027-02-01T13:24:33Z"
}
}
]
}
],
"unassignedJobs": [
{
"id": "Job 2",
"unassignedStops": [
"Stop C",
"Stop D"
]
}
]
},
"inputMetrics": {
"jobs": 4,
"stops": 8,
"drivers": 1,
"driverShifts": 1,
"pinnedStops": 0
},
"kpis": {
"totalTravelTime": "PT1H24M33S",
"totalTravelDistanceMeters": 70450,
"totalActivatedDrivers": 1,
"totalUnassignedJobs": 1,
"totalAssignedJobs": 3,
"assignedMandatoryJobs": 3,
"totalUnassignedStops": 2,
"totalAssignedStops": 6,
"assignedMandatoryStops": 6,
"travelTimeFromStartLocationToFirstStop": "PT6M17S",
"travelTimeBetweenStops": "PT1H1M41S",
"travelTimeFromLastStopToEndLocation": "PT16M35S",
"travelDistanceFromStartLocationToFirstStopMeters": 5233,
"travelDistanceBetweenStopsMeters": 51402,
"travelDistanceFromLastStopToEndLocationMeters": 13815
}
}
modelOutput contains Carl’s updated shift itinerary.
Jobs 1 and 3 were reassigned from Ann to Carl. Job 2 was left unassigned.
3. Real-time planning update: driver becomes ill
In this example, Ann becomes ill after starting her work day. After picking up her first job (Stop E), Ann realizes that she is ill and needs to go home. Instead of continuing with her remaining jobs, she delivers the first job (Stop F) and then goes home.
The plan must be updated part way through the day.
Include the itineraries for both Ann and Carl. As Ann will only complete her first job (Stop E and Stop F), her itinerary will only include that job. Ann’s itinerary should also be pinned to ensure that it isn’t changed during the real-time planning update. Carl’s itinerary should include all of his previously assigned jobs:
{
"drivers": [
{
"id": "Carl",
"shifts": [
{
"id": "Carl Mon",
"startLocation": [33.77284, -84.42989],
"minStartTime": "2027-02-01T09:00:00Z",
"maxEndTime": "2027-02-01T13:30:00Z",
"itinerary": [
{
"id": "STOP G",
"kind": "STOP"
},
{
"id": "STOP H",
"kind": "STOP"
}
]
}
]
},
{
"id": "Ann",
"shifts": [
{
"id": "Ann Mon",
"startLocation": [33.79426, -84.330114],
"minStartTime": "2027-02-01T09:00:00Z",
"maxEndTime": "2027-02-01T13:30:00Z",
"itinerary": [
{
"id": "STOP E",
"kind": "STOP"
},
{
"id": "STOP F",
"kind": "STOP"
}
],
"pinned": true
}
]
}
]
}
Add the minStartTravelTime from the most recent planning output dataset (batch or real-time) to each stop.
{
"jobs": [
{
"id": "Job 1",
"stops": [
{
"id": "Stop A",
"name": "Stop A",
"location": [33.74648, -84.46461],
"duration": "PT30M",
"minStartTravelTime": "2027-02-01T00:00:00Z"
},
{
"id": "Stop B",
"name": "Stop B",
"location": [33.65207, -84.46496],
"duration": "PT30M",
"minStartTravelTime": "2027-02-01T00:00:00Z"
}
]
},
{
"id": "Job 2",
"stops": [
{
"id": "Stop C",
"name": "Stop C",
"location": [33.77911, -84.49644],
"duration": "PT30M",
"minStartTravelTime": "2027-02-01T00:00:00Z"
},
{
"id": "Stop D",
"name": "Stop D",
"location": [33.65979, -84.46366],
"duration": "PT30M",
"minStartTravelTime": "2027-02-01T00:00:00Z"
}
]
},
{
"id": "Job 3",
"stops": [
{
"id": "Stop E",
"name": "Stop E",
"location": [ 33.78468, -84.48469],
"duration": "PT30M",
"minStartTravelTime": "2027-02-01T00:00:00Z"
},
{
"id": "Stop F",
"name": "Stop F",
"location": [ 33.67966, -84.30062 ],
"duration": "PT30M",
"minStartTravelTime": "2027-02-01T00:00:00Z"
}
]
},
{
"id": "Job 4",
"stops": [
{
"id": "Stop G",
"name": "Stop G",
"location": [ 33.73698, -84.34712 ],
"duration": "PT30M",
"minStartTravelTime": "2027-02-01T00:00:00Z"
},
{
"id": "Stop H",
"name": "Stop H",
"location": [ 33.74661, -84.47359 ],
"duration": "PT30M",
"minStartTravelTime": "2027-02-01T00:00:00Z"
}
]
}
]
}
Freeze the departure times for stops that have already occurred and that drivers have begun traveling to by adding freezeTime.
Ann finished Stop E at 09:47 when she realized that she was ill and needed to go home, so the freezeTime can be set to 09:47.
{
"modelInput": {
"freezeTime": "2027-02-01T09:47:00Z"
}
}
Submit the input dataset to generate the new real-time plan:
-
Input
-
Output
Try this example in Timefold Platform by saving this JSON into a file called sample.json and make the following API call:
|
curl -X POST -H "Content-type: application/json" -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/pickup-delivery-routing/v1/route-plans [email protected]
{
"config": {
"run": {
"name": "Original shift plan: driver ill example"
}
},
"modelInput": {
"freezeTime": "2027-02-01T09:47:00Z",
"drivers": [
{
"id": "Carl",
"shifts": [
{
"id": "Carl Mon",
"startLocation": [33.77284, -84.42989],
"minStartTime": "2027-02-01T09:00:00Z",
"maxEndTime": "2027-02-01T13:30:00Z",
"itinerary": [
{
"id": "Stop G",
"kind": "STOP"
},
{
"id": "Stop H",
"kind": "STOP"
}
]
}
]
},
{
"id": "Ann",
"shifts": [
{
"id": "Ann Mon",
"startLocation": [33.79426, -84.330114],
"minStartTime": "2027-02-01T09:00:00Z",
"maxEndTime": "2027-02-01T13:30:00Z",
"itinerary": [
{
"id": "Stop E",
"kind": "STOP"
},
{
"id": "Stop F",
"kind": "STOP"
}
],
"pinned": true
}
]
}
],
"jobs": [
{
"id": "Job 1",
"stops": [
{
"id": "Stop A",
"name": "Stop A",
"location": [33.74648, -84.46461],
"duration": "PT30M",
"minStartTravelTime": "2027-02-01T00:00:00Z"
},
{
"id": "Stop B",
"name": "Stop B",
"location": [33.65207, -84.46496],
"duration": "PT30M",
"minStartTravelTime": "2027-02-01T00:00:00Z"
}
]
},
{
"id": "Job 2",
"stops": [
{
"id": "Stop C",
"name": "Stop C",
"location": [33.77911, -84.49644],
"duration": "PT30M",
"minStartTravelTime": "2027-02-01T00:00:00Z"
},
{
"id": "Stop D",
"name": "Stop D",
"location": [33.65979, -84.46366],
"duration": "PT30M",
"minStartTravelTime": "2027-02-01T00:00:00Z"
}
]
},
{
"id": "Job 3",
"stops": [
{
"id": "Stop E",
"name": "Stop E",
"location": [ 33.78468, -84.48469],
"duration": "PT30M",
"minStartTravelTime": "2027-02-01T00:00:00Z"
},
{
"id": "Stop F",
"name": "Stop F",
"location": [ 33.67966, -84.30062 ],
"duration": "PT30M",
"minStartTravelTime": "2027-02-01T00:00:00Z"
}
]
},
{
"id": "Job 4",
"stops": [
{
"id": "Stop G",
"name": "Stop G",
"location": [ 33.73698, -84.34712 ],
"duration": "PT30M",
"minStartTravelTime": "2027-02-01T00:00:00Z"
},
{
"id": "Stop H",
"name": "Stop H",
"location": [ 33.74661, -84.47359 ],
"duration": "PT30M",
"minStartTravelTime": "2027-02-01T00:00:00Z"
}
]
}
]
}
}
To request the solution, locate the ID from the response to the post operation and append it to the following API call:
|
curl -X GET -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/pickup-delivery-routing/v1/route-plans/<ID>
{
"metadata": {
"id": "ID",
"originId": "ID",
"name": "Original shift plan: driver ill example",
"submitDateTime": "2026-04-10T09:42:31.757761+02:00",
"startDateTime": "2026-04-10T09:42:31.886929+02:00",
"activeDateTime": "2026-04-10T09:42:31.888494+02:00",
"completeDateTime": "2026-04-10T09:43:01.906806+02:00",
"shutdownDateTime": "2026-04-10T09:43:01.906811+02:00",
"solverStatus": "SOLVING_COMPLETED",
"score": "0hard/0medium/-8647soft",
"validationResult": {
"summary": "OK"
}
},
"modelOutput": {
"drivers": [
{
"id": "Carl",
"shifts": [
{
"id": "Carl Mon",
"startTime": "2027-02-01T09:00:00Z",
"itinerary": [
{
"id": "Stop G",
"arrivalTime": "2027-02-01T09:10:21Z",
"startServiceTime": "2027-02-01T09:10:21Z",
"departureTime": "2027-02-01T09:40:21Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT10M21S",
"travelDistanceMetersFromPreviousStandstill": 8629,
"minStartTravelTime": "2027-02-01T00:00:00Z",
"load": [],
"pinned": true,
"kind": "STOP"
},
{
"id": "Stop H",
"arrivalTime": "2027-02-01T09:54:26Z",
"startServiceTime": "2027-02-01T09:54:26Z",
"departureTime": "2027-02-01T10:24:26Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT14M5S",
"travelDistanceMetersFromPreviousStandstill": 11743,
"minStartTravelTime": "2027-02-01T00:00:00Z",
"load": [],
"pinned": true,
"kind": "STOP"
},
{
"id": "Stop C",
"arrivalTime": "2027-02-01T10:29:27Z",
"startServiceTime": "2027-02-01T10:29:27Z",
"departureTime": "2027-02-01T10:59:27Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT5M1S",
"travelDistanceMetersFromPreviousStandstill": 4186,
"minStartTravelTime": "2027-02-01T09:47:00Z",
"load": [],
"kind": "STOP"
},
{
"id": "Stop D",
"arrivalTime": "2027-02-01T11:15:47Z",
"startServiceTime": "2027-02-01T11:15:47Z",
"departureTime": "2027-02-01T11:45:47Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT16M20S",
"travelDistanceMetersFromPreviousStandstill": 13610,
"minStartTravelTime": "2027-02-01T09:47:00Z",
"load": [],
"kind": "STOP"
},
{
"id": "Stop A",
"arrivalTime": "2027-02-01T11:57:21Z",
"startServiceTime": "2027-02-01T11:57:21Z",
"departureTime": "2027-02-01T12:27:21Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT11M34S",
"travelDistanceMetersFromPreviousStandstill": 9640,
"minStartTravelTime": "2027-02-01T09:47:00Z",
"load": [],
"kind": "STOP"
},
{
"id": "Stop B",
"arrivalTime": "2027-02-01T12:39:57Z",
"startServiceTime": "2027-02-01T12:39:57Z",
"departureTime": "2027-02-01T13:09:57Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT12M36S",
"travelDistanceMetersFromPreviousStandstill": 10498,
"minStartTravelTime": "2027-02-01T09:47:00Z",
"load": [],
"kind": "STOP"
}
],
"metrics": {
"totalTravelTime": "PT1H26M32S",
"travelTimeFromStartLocationToFirstStop": "PT10M21S",
"travelTimeBetweenStops": "PT59M36S",
"travelTimeFromLastStopToEndLocation": "PT16M35S",
"totalTravelDistanceMeters": 72121,
"travelDistanceFromStartLocationToFirstStopMeters": 8629,
"travelDistanceBetweenStopsMeters": 49677,
"travelDistanceFromLastStopToEndLocationMeters": 13815,
"endLocationArrivalTime": "2027-02-01T13:26:32Z"
}
}
]
},
{
"id": "Ann",
"shifts": [
{
"id": "Ann Mon",
"startTime": "2027-02-01T09:00:00Z",
"pinned": true,
"itinerary": [
{
"id": "Stop E",
"arrivalTime": "2027-02-01T09:17:11Z",
"startServiceTime": "2027-02-01T09:17:11Z",
"departureTime": "2027-02-01T09:47:11Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT17M11S",
"travelDistanceMetersFromPreviousStandstill": 14324,
"minStartTravelTime": "2027-02-01T00:00:00Z",
"load": [],
"pinned": true,
"kind": "STOP"
},
{
"id": "Stop F",
"arrivalTime": "2027-02-01T10:11:57Z",
"startServiceTime": "2027-02-01T10:11:57Z",
"departureTime": "2027-02-01T10:41:57Z",
"effectiveServiceDuration": "PT30M",
"travelTimeFromPreviousStandstill": "PT24M46S",
"travelDistanceMetersFromPreviousStandstill": 20642,
"minStartTravelTime": "2027-02-01T00:00:00Z",
"load": [],
"pinned": true,
"kind": "STOP"
}
],
"metrics": {
"totalTravelTime": "PT57M35S",
"travelTimeFromStartLocationToFirstStop": "PT17M11S",
"travelTimeBetweenStops": "PT24M46S",
"travelTimeFromLastStopToEndLocation": "PT15M38S",
"totalTravelDistanceMeters": 47998,
"travelDistanceFromStartLocationToFirstStopMeters": 14324,
"travelDistanceBetweenStopsMeters": 20642,
"travelDistanceFromLastStopToEndLocationMeters": 13032,
"endLocationArrivalTime": "2027-02-01T10:57:35Z"
}
}
]
}
],
"unassignedJobs": []
},
"inputMetrics": {
"jobs": 4,
"stops": 8,
"drivers": 2,
"driverShifts": 2,
"pinnedStops": 4
},
"kpis": {
"totalTravelTime": "PT2H24M7S",
"totalTravelDistanceMeters": 120119,
"totalActivatedDrivers": 2,
"totalUnassignedJobs": 0,
"totalAssignedJobs": 4,
"assignedMandatoryJobs": 4,
"totalUnassignedStops": 0,
"totalAssignedStops": 8,
"assignedMandatoryStops": 8,
"travelTimeFromStartLocationToFirstStop": "PT27M32S",
"travelTimeBetweenStops": "PT1H24M22S",
"travelTimeFromLastStopToEndLocation": "PT32M13S",
"travelDistanceFromStartLocationToFirstStopMeters": 22953,
"travelDistanceBetweenStopsMeters": 70319,
"travelDistanceFromLastStopToEndLocationMeters": 26847
}
}
modelOutput contains Carl’s and Ann’s shift itineraries.
Ann completed Stop E and Stop F. Her other jobs (Job 1 and Job 4) were reassigned to Carl.
Next
-
See the full API spec or try the online API.
-
Learn about real-time planning.
-
Real-time planning with pinned stops.
-
Real-time planning with extended stops.