Maximum time burden
In a pick-up and delivery routing, jobs are often combined to optimize the routes and use the available resources as efficiently as possible. However, this also means the time between the pick-up and the delivery for a job will increase as there are other stops in between (pick-ups and deliveries for other jobs).
This is often acceptable, but there are cases where the time between pick-up and delivery should be limited to a certain maximum, for instance, when people are being picked up and transported to their destination. The inconvenience of having a prolonged time on the vehicle should be limited to a certain maximum.
Prerequisites
Learn how to configure an API Key to run the examples in this guide:
-
Log in to Timefold Platform: app.timefold.ai
-
From the Dashboard, click your tenant, and from the drop-down menu select Tenant Settings, then choose API Keys.
-
Create a new API key or use an existing one. Ensure the list of models for the API key contains the Pick-up and Delivery Routing model.
In the examples, replace <API_KEY> with the API Key you just copied.
1. Define the maximum time burden
In order to limit the possible increase in time between pick-up and delivery, the parameter maximumTimeBurden can be added to the model configuration.
{
"config": {
"model": {
"overrides": {
"maximumTimeBurden": "PT10M"
}
}
}
}
The maximumTimeBurden parameter requires a duration in ISO 8601 duration format representing the maximum allowed time burden for the jobs.
Whenever the time to service a job (measured by the time between the start of the service of the first stop and the start of the service of the last stop of the job minus direct travel time) is increased by more than the maximumTimeBurden, the solution is penalized by the Maximum time burden hard constraint.
If assigning a job would break this constraint, the job will be left unassigned.
In the following example, the maximum time burden is set to PT5M.
Although Job A and Job B share the same starting location, they are assigned sequentially as mixing them would exceed the maximum time burden of 5 minutes.
-
Input
-
Output
Try this example in Timefold Platform by saving the JSON into a file called maximum-time-burden-input.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": "Maximum time burden example"
},
"model": {
"overrides": {
"maximumTimeBurden": "PT5M"
}
}
},
"modelInput": {
"drivers": [
{
"id": "Ann",
"shifts": [
{
"id": "Ann Mon",
"startLocation": [33.68786, -84.18487],
"endLocation": [33.68786, -84.18487],
"minStartTime": "2027-02-01T09:00:00Z",
"maxEndTime": "2027-02-01T17:00:00Z"
}
]
}
],
"jobs": [
{
"id": "Job A",
"stops": [
{
"id": "A1",
"location": [33.78592, -84.46136],
"duration": "PT20M"
},
{
"id": "A2",
"location": [33.72757, -83.96354],
"duration": "PT20M",
"stopDependencies": [
{
"id": "jobA_dep1",
"precedingStop": "A1"
}
]
}
]
},
{
"id": "Job B",
"prohibitedJobs": [],
"stops": [
{
"id": "B1",
"location": [33.78592, -84.46136],
"duration": "PT20M"
},
{
"id": "B2",
"location": [33.72757, -83.96354],
"duration": "PT20M",
"stopDependencies": [
{
"id": "jobB_dep1",
"precedingStop": "B1"
}
]
}
]
}
]
}
}
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": "Maximum time burden example",
"submitDateTime": "2025-10-07T11:50:34.286702+02:00",
"startDateTime": "2025-10-07T11:50:34.384342+02:00",
"activeDateTime": "2025-10-07T11:50:34.384876+02:00",
"completeDateTime": "2025-10-07T11:50:34.918612+02:00",
"shutdownDateTime": "2025-10-07T11:50:34.9232+02:00",
"solverStatus": "SOLVING_COMPLETED",
"score": "0hard/0medium/-13547soft",
"validationResult": {
"summary": "OK"
}
},
"modelOutput": {
"drivers": [
{
"id": "Ann",
"shifts": [
{
"id": "Ann Mon",
"startTime": "2027-02-01T09:00:00Z",
"itinerary": [
{
"id": "B1",
"arrivalTime": "2027-02-01T09:33:21Z",
"startServiceTime": "2027-02-01T09:33:21Z",
"departureTime": "2027-02-01T09:53:21Z",
"effectiveServiceDuration": "PT20M",
"kind": "STOP",
"travelTimeFromPreviousStandstill": "PT33M21S",
"travelDistanceMetersFromPreviousStandstill": 27795
},
{
"id": "B2",
"arrivalTime": "2027-02-01T10:49:07Z",
"startServiceTime": "2027-02-01T10:49:07Z",
"departureTime": "2027-02-01T11:09:07Z",
"effectiveServiceDuration": "PT20M",
"kind": "STOP",
"travelTimeFromPreviousStandstill": "PT55M46S",
"travelDistanceMetersFromPreviousStandstill": 46477
},
{
"id": "A1",
"arrivalTime": "2027-02-01T12:04:53Z",
"startServiceTime": "2027-02-01T12:04:53Z",
"departureTime": "2027-02-01T12:24:53Z",
"effectiveServiceDuration": "PT20M",
"kind": "STOP",
"travelTimeFromPreviousStandstill": "PT55M46S",
"travelDistanceMetersFromPreviousStandstill": 46477
},
{
"id": "A2",
"arrivalTime": "2027-02-01T13:20:39Z",
"startServiceTime": "2027-02-01T13:20:39Z",
"departureTime": "2027-02-01T13:40:39Z",
"effectiveServiceDuration": "PT20M",
"kind": "STOP",
"travelTimeFromPreviousStandstill": "PT55M46S",
"travelDistanceMetersFromPreviousStandstill": 46477
}
],
"metrics": {
"totalTravelTime": "PT3H45M47S",
"travelTimeFromStartLocationToFirstStop": "PT33M21S",
"travelTimeBetweenStops": "PT2H47M18S",
"travelTimeFromLastStopToEndLocation": "PT25M8S",
"totalTravelDistanceMeters": 188170,
"travelDistanceFromStartLocationToFirstStopMeters": 27795,
"travelDistanceBetweenStopsMeters": 139431,
"travelDistanceFromLastStopToEndLocationMeters": 20944,
"endLocationArrivalTime": "2027-02-01T14:05:47Z",
"overtime": "PT0S"
}
}
]
}
]
},
"inputMetrics": {
"stops": 4,
"drivers": 1,
"driverShifts": 1
},
"kpis": {
"totalTravelTime": "PT3H45M47S",
"travelTimeFromStartLocationToFirstStop": "PT33M21S",
"travelTimeBetweenStops": "PT2H47M18S",
"travelTimeFromLastStopToEndLocation": "PT25M8S",
"totalTravelDistanceMeters": 188170,
"travelDistanceFromStartLocationToFirstStopMeters": 27795,
"travelDistanceBetweenStopsMeters": 139431,
"travelDistanceFromLastStopToEndLocationMeters": 20944,
"totalUnassignedStops": 0,
"totalAssignedStops": 4,
"totalActivatedDrivers": 1,
"totalOvertime": "PT0S"
},
"run": {
"id": "f1e18fe0-6d4b-4f7f-b579-084ca4c7de29",
"originId": "f1e18fe0-6d4b-4f7f-b579-084ca4c7de29",
"name": "Maximum time burden example",
"submitDateTime": "2025-10-07T11:50:34.286702+02:00",
"startDateTime": "2025-10-07T11:50:34.384342+02:00",
"activeDateTime": "2025-10-07T11:50:34.384876+02:00",
"completeDateTime": "2025-10-07T11:50:34.918612+02:00",
"shutdownDateTime": "2025-10-07T11:50:34.9232+02:00",
"solverStatus": "SOLVING_COMPLETED",
"score": "0hard/0medium/-13547soft",
"validationResult": {
"summary": "OK"
}
}
}
Next
-
See the full API spec or try the online API.