Docs
  • Solver
  • Models
    • Field Service Routing
    • Employee Shift Scheduling
    • Pick-up and Delivery Routing
  • Platform
Try models
  • Pick-up and Delivery Routing
  • Recommendations
  • Job time window recommendations

Pick-up and Delivery Routing

    • Introduction
    • Getting started: Hello world
    • User guide
      • Terminology
      • Use case guide
      • Planning AI concepts
      • Integration
      • Constraints
      • Understanding the API
      • Demo datasets
      • Input datasets
        • Model configuration
        • Model input
        • Planning window
      • Input validation
      • Output datasets
        • Metadata
        • Model output
        • Input metrics
        • Key performance indicators (KPIs)
      • Routing with Timefold’s maps service
      • Metrics and optimization goals
    • Driver resource constraints
      • Lunch breaks and personal appointments
      • Route optimization
      • Shift hours and overtime
    • Job service constraints
      • Time windows and opening hours
      • Skills
      • Movable stops and multi-day schedules
      • Dependencies between stops
      • Priority jobs and optional jobs
      • Stop service level agreement (SLA)
      • Job requirements and tags
        • Job required drivers
        • Job pooling
        • Prohibit job combinations
        • Maximum time burden
        • Driver capacity
        • Tags
    • Recommendations
      • Job time window recommendations
      • Stop time window recommendations
    • Real-time planning
      • Real-time planning: pinning stops
    • Changelog
    • Upgrading to the latest versions
    • Feature requests

Job time window recommendations

Recommendations are a useful way of populating a draft plan.

This guide explains recommendations with the following examples:

  • 1. Recommendations for unsolved route plans
  • 2. Recommendations for unsolved route plans with existing jobs
  • 3. Recommendations for solved route plans

1. Recommendations for unsolved route plans

Learn how to configure an API Key to run the examples in this guide:
  1. Log in to Timefold Platform: app.timefold.ai

  2. From the Dashboard, click your tenant, and from the drop-down menu select Manage tenant, then choose API Keys.

  3. 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.

Continuous planning includes four stages:

  1. Historic
    The historic stage includes schedules that have already been executed and cannot be changed.

  2. Published
    The published stage includes schedules that have been shared with your customers and drivers and should only be changed in special circumstances.

  3. Draft
    The draft stage includes schedules that can change without impacting customers or drivers. At some point, draft schedules will be solved and moved to the published stage.

  4. Unplanned
    The unplanned stage is too far away to start planning schedules.

When customers request work during a time period that is still in the draft phase, you can use recommendations to provide the customer with time windows to choose from. The customer’s chosen time window can be added to the draft schedule, which will be optimized before being published.

1.1. The recommendation input dataset

A recommendation input dataset includes the following:

1.1.1. Max number of recommendations per time window

The maximum number of recommendations to make per time window is specified in the input dataset.

The recommendation will consider the drivers whose shifts overlap with the specified time window and make the number of recommendations specified in maxNumberOfRecommendationsPerTimeWindow.

Each recommendation relates to a driver shift. If there are five drivers and the maxNumberOfRecommendationsPerTimeWindow is set to 2, up to two driver shifts will be included in the recommendations per time window.

{
  "maxNumberOfRecommendationsPerTimeWindow": 2
}

1.1.2. Fit job ID

The ID of the job to make the recommendations for. The provided fitJobId must match an ID from a job in the modelInput.

{
  "fitJobId": "Job A"
}

1.1.3. Time windows

The time windows to be considered for the recommendation. For instance, 09:00 to 13:00 on February 1, 2027, and 13:00 to 17:00 on February 1, 2027.

Time windows can cover an entire day or even longer, but as time windows get longer, you reduce the number of recommendations and the customer’s options.

The time windows indicate the potential periods in which the whole job needs to be scheduled, i.e. all of the stops of the job must fit within the time window.

{
  "timeWindows": [
    {
      "startTime": "2027-02-01T09:00:00Z",
      "endTime": "2027-02-01T13:00:00Z"
    },
    {
      "startTime": "2027-02-01T13:00:00Z",
      "endTime": "2027-02-01T17:00:00Z"
    }
  ]
}

1.1.4. Model input

The model input must include the drivers and shifts and the job the recommendations are for.

To learn more about driver shifts and stops, see Shift hours and overtime.

{
  "modelInput": {
    "drivers": [
      {
        "id": "Ann",
        "shifts": [
          {
            "id": "Ann-2027-02-01",
            "startLocation": [33.68786, -84.18487],
            "minStartTime": "2027-02-01T09:00:00Z",
            "maxEndTime": "2027-02-01T17:00:00Z"
          }
        ]
      },
      {
        "id": "Beth",
        "shifts": [
          {
            "id": "Beth-2027-02-01",
            "startLocation": [33.70474, -84.06508],
            "minStartTime": "2027-02-01T09:00:00Z",
            "maxEndTime": "2027-02-01T17:00:00Z"
          }
        ]
      }
    ],
    "jobs": [
      {
        "id": "Job A",
        "stops": [
            {
                "id": "stop-1",
                "location": [33.84475, -84.63649],
                "serviceDuration": "PT10M"
            },
            {
                "id": "stop-2",
                "location": [33.57448, -84.94636],
                "serviceDuration": "PT10M",
                "stopDependencies": [
                  {
                    "id": "prev-stop-2",
                    "precedingStop": "stop-1"
                  }
                ]
            }
        ]
      }
    ]
  }
}

1.2. Submit the input dataset

Submit the recommendations input dataset to the API endpoint: /v1/route-plans/recommendations/job-recommend-time-windows.

If you want individual constraint match justifications included in the response, you can specify an optional boolean includeJustifications query parameter: /v1/route-plans/recommendations/job-recommend-time-windows?includeJustifications=true.

The HTTP response provides the recommendations.

  • Input

  • Output (without justifications)

  • Output (with justifications)

Try this example in Timefold Platform by saving this JSON into a file called sample.json and make the following API call:

To get recommendations without constraint match justifications (default):

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/recommendations/job-recommend-time-windows [email protected]

To get recommendations with constraint match justifications:

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/recommendations/job-recommend-time-windows?includeJustifications=true [email protected]
{
  "maxNumberOfRecommendationsPerTimeWindow": 2,
  "fitJobId": "Job A",
  "timeWindows": [
    {
      "minStartTime": "2027-02-01T09:00:00Z",
      "maxEndTime": "2027-02-01T13:00:00Z"
    },
    {
      "minStartTime": "2027-02-01T13:00:00Z",
      "maxEndTime": "2027-02-01T17:00:00Z"
    }
  ],
  "modelInput": {
    "drivers": [
      {
        "id": "Ann",
        "shifts": [
          {
            "id": "Ann-2027-02-01",
            "startLocation": [
              33.68786,
              -84.18487
            ],
            "minStartTime": "2027-02-01T09:00:00Z",
            "maxEndTime": "2027-02-01T17:00:00Z"
          }
        ]
      },
      {
        "id": "Beth",
        "shifts": [
          {
            "id": "Beth-2027-02-01",
            "startLocation": [
              33.70474,
              -84.06508
            ],
            "minStartTime": "2027-02-01T09:00:00Z",
            "maxEndTime": "2027-02-01T17:00:00Z"
          }
        ]
      }
    ],
    "jobs": [
      {
        "id": "Job A",
        "stops": [
          {
            "id": "stop-1",
            "location": [
              33.84475,
              -84.63649
            ],
            "duration": "PT10M"
          },
          {
            "id": "stop-2",
            "location": [
              33.57448,
              -84.94636
            ],
            "duration": "PT10M",
            "stopDependencies": [
              {
                "id": "prev-stop-2",
                "precedingStop": "stop-1"
              }
            ]
          }
        ]
      }
    ]
  }
}
{
  "recommendations": [
    {
      "scoreDiff": "0hard/20000medium/-11405soft",
      "constraintDiffs": [
        {
          "score": "0hard/0medium/-11405soft",
          "constraintName": "Minimize travel time",
          "matchCountDiff": 2
        },
        {
          "score": "0hard/20000medium/0soft",
          "constraintName": "Require scheduling mandatory stops",
          "matchCountDiff": -2
        }
      ],
      "timeWindow": {
        "minStartTime": "2027-02-01T09:00:00Z",
        "maxEndTime": "2027-02-01T13:00:00Z"
      },
      "driverShift": {
        "id": "Ann-2027-02-01",
        "startTime": "2027-02-01T09:00:00Z",
        "itinerary": [
          {
            "id": "stop-1",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:54:18Z",
            "startServiceTime": "2027-02-01T09:54:18Z",
            "departureTime": "2027-02-01T10:04:18Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT54M18S",
            "travelDistanceMetersFromPreviousStandstill": 45245,
            "load": []
          },
          {
            "id": "stop-2",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:54:08Z",
            "startServiceTime": "2027-02-01T10:54:08Z",
            "departureTime": "2027-02-01T11:04:08Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT49M50S",
            "travelDistanceMetersFromPreviousStandstill": 41530,
            "load": []
          }
        ],
        "metrics": {
          "totalTravelTime": "PT3H10M5S",
          "travelTimeFromStartLocationToFirstStop": "PT54M18S",
          "travelTimeBetweenStops": "PT49M50S",
          "travelTimeFromLastStopToEndLocation": "PT1H25M57S",
          "totalTravelDistanceMeters": 158394,
          "travelDistanceFromStartLocationToFirstStopMeters": 45245,
          "travelDistanceBetweenStopsMeters": 41530,
          "travelDistanceFromLastStopToEndLocationMeters": 71619,
          "endLocationArrivalTime": "2027-02-01T12:30:05Z"
        }
      },
      "kpis": {
        "totalTravelTime": "PT3H10M5S",
        "totalTravelDistanceMeters": 158394,
        "totalActivatedDrivers": 1,
        "totalUnassignedJobs": 0,
        "totalAssignedJobs": 1,
        "assignedMandatoryJobs": 1,
        "totalUnassignedStops": 0,
        "totalAssignedStops": 2,
        "assignedMandatoryStops": 2,
        "travelTimeFromStartLocationToFirstStop": "PT54M18S",
        "travelTimeBetweenStops": "PT49M50S",
        "travelTimeFromLastStopToEndLocation": "PT1H25M57S",
        "travelDistanceFromStartLocationToFirstStopMeters": 45245,
        "travelDistanceBetweenStopsMeters": 41530,
        "travelDistanceFromLastStopToEndLocationMeters": 71619
      }
    },
    {
      "scoreDiff": "0hard/20000medium/-11405soft",
      "constraintDiffs": [
        {
          "score": "0hard/0medium/-11405soft",
          "constraintName": "Minimize travel time",
          "matchCountDiff": 2
        },
        {
          "score": "0hard/20000medium/0soft",
          "constraintName": "Require scheduling mandatory stops",
          "matchCountDiff": -2
        }
      ],
      "timeWindow": {
        "minStartTime": "2027-02-01T13:00:00Z",
        "maxEndTime": "2027-02-01T17:00:00Z"
      },
      "driverShift": {
        "id": "Ann-2027-02-01",
        "startTime": "2027-02-01T09:00:00Z",
        "itinerary": [
          {
            "id": "stop-1",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:54:18Z",
            "startServiceTime": "2027-02-01T13:00:00Z",
            "departureTime": "2027-02-01T13:10:00Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT54M18S",
            "travelDistanceMetersFromPreviousStandstill": 45245,
            "load": []
          },
          {
            "id": "stop-2",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T13:59:50Z",
            "startServiceTime": "2027-02-01T13:59:50Z",
            "departureTime": "2027-02-01T14:09:50Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT49M50S",
            "travelDistanceMetersFromPreviousStandstill": 41530,
            "load": []
          }
        ],
        "metrics": {
          "totalTravelTime": "PT3H10M5S",
          "travelTimeFromStartLocationToFirstStop": "PT54M18S",
          "travelTimeBetweenStops": "PT49M50S",
          "travelTimeFromLastStopToEndLocation": "PT1H25M57S",
          "totalTravelDistanceMeters": 158394,
          "travelDistanceFromStartLocationToFirstStopMeters": 45245,
          "travelDistanceBetweenStopsMeters": 41530,
          "travelDistanceFromLastStopToEndLocationMeters": 71619,
          "endLocationArrivalTime": "2027-02-01T15:35:47Z"
        }
      },
      "kpis": {
        "totalTravelTime": "PT3H10M5S",
        "totalTravelDistanceMeters": 158394,
        "totalActivatedDrivers": 1,
        "totalUnassignedJobs": 0,
        "totalAssignedJobs": 1,
        "assignedMandatoryJobs": 1,
        "totalUnassignedStops": 0,
        "totalAssignedStops": 2,
        "assignedMandatoryStops": 2,
        "travelTimeFromStartLocationToFirstStop": "PT54M18S",
        "travelTimeBetweenStops": "PT49M50S",
        "travelTimeFromLastStopToEndLocation": "PT1H25M57S",
        "travelDistanceFromStartLocationToFirstStopMeters": 45245,
        "travelDistanceBetweenStopsMeters": 41530,
        "travelDistanceFromLastStopToEndLocationMeters": 71619
      }
    },
    {
      "scoreDiff": "0hard/20000medium/-12920soft",
      "constraintDiffs": [
        {
          "score": "0hard/0medium/-12920soft",
          "constraintName": "Minimize travel time",
          "matchCountDiff": 2
        },
        {
          "score": "0hard/20000medium/0soft",
          "constraintName": "Require scheduling mandatory stops",
          "matchCountDiff": -2
        }
      ],
      "timeWindow": {
        "minStartTime": "2027-02-01T09:00:00Z",
        "maxEndTime": "2027-02-01T13:00:00Z"
      },
      "driverShift": {
        "id": "Beth-2027-02-01",
        "startTime": "2027-02-01T09:00:00Z",
        "itinerary": [
          {
            "id": "stop-1",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:06:04Z",
            "startServiceTime": "2027-02-01T10:06:04Z",
            "departureTime": "2027-02-01T10:16:04Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT1H6M4S",
            "travelDistanceMetersFromPreviousStandstill": 55061,
            "load": []
          },
          {
            "id": "stop-2",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T11:05:54Z",
            "startServiceTime": "2027-02-01T11:05:54Z",
            "departureTime": "2027-02-01T11:15:54Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT49M50S",
            "travelDistanceMetersFromPreviousStandstill": 41530,
            "load": []
          }
        ],
        "metrics": {
          "totalTravelTime": "PT3H35M20S",
          "travelTimeFromStartLocationToFirstStop": "PT1H6M4S",
          "travelTimeBetweenStops": "PT49M50S",
          "travelTimeFromLastStopToEndLocation": "PT1H39M26S",
          "totalTravelDistanceMeters": 179450,
          "travelDistanceFromStartLocationToFirstStopMeters": 55061,
          "travelDistanceBetweenStopsMeters": 41530,
          "travelDistanceFromLastStopToEndLocationMeters": 82859,
          "endLocationArrivalTime": "2027-02-01T12:55:20Z"
        }
      },
      "kpis": {
        "totalTravelTime": "PT3H35M20S",
        "totalTravelDistanceMeters": 179450,
        "totalActivatedDrivers": 1,
        "totalUnassignedJobs": 0,
        "totalAssignedJobs": 1,
        "assignedMandatoryJobs": 1,
        "totalUnassignedStops": 0,
        "totalAssignedStops": 2,
        "assignedMandatoryStops": 2,
        "travelTimeFromStartLocationToFirstStop": "PT1H6M4S",
        "travelTimeBetweenStops": "PT49M50S",
        "travelTimeFromLastStopToEndLocation": "PT1H39M26S",
        "travelDistanceFromStartLocationToFirstStopMeters": 55061,
        "travelDistanceBetweenStopsMeters": 41530,
        "travelDistanceFromLastStopToEndLocationMeters": 82859
      }
    },
    {
      "scoreDiff": "0hard/20000medium/-12920soft",
      "constraintDiffs": [
        {
          "score": "0hard/0medium/-12920soft",
          "constraintName": "Minimize travel time",
          "matchCountDiff": 2
        },
        {
          "score": "0hard/20000medium/0soft",
          "constraintName": "Require scheduling mandatory stops",
          "matchCountDiff": -2
        }
      ],
      "timeWindow": {
        "minStartTime": "2027-02-01T13:00:00Z",
        "maxEndTime": "2027-02-01T17:00:00Z"
      },
      "driverShift": {
        "id": "Beth-2027-02-01",
        "startTime": "2027-02-01T09:00:00Z",
        "itinerary": [
          {
            "id": "stop-1",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:06:04Z",
            "startServiceTime": "2027-02-01T13:00:00Z",
            "departureTime": "2027-02-01T13:10:00Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT1H6M4S",
            "travelDistanceMetersFromPreviousStandstill": 55061,
            "load": []
          },
          {
            "id": "stop-2",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T13:59:50Z",
            "startServiceTime": "2027-02-01T13:59:50Z",
            "departureTime": "2027-02-01T14:09:50Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT49M50S",
            "travelDistanceMetersFromPreviousStandstill": 41530,
            "load": []
          }
        ],
        "metrics": {
          "totalTravelTime": "PT3H35M20S",
          "travelTimeFromStartLocationToFirstStop": "PT1H6M4S",
          "travelTimeBetweenStops": "PT49M50S",
          "travelTimeFromLastStopToEndLocation": "PT1H39M26S",
          "totalTravelDistanceMeters": 179450,
          "travelDistanceFromStartLocationToFirstStopMeters": 55061,
          "travelDistanceBetweenStopsMeters": 41530,
          "travelDistanceFromLastStopToEndLocationMeters": 82859,
          "endLocationArrivalTime": "2027-02-01T15:49:16Z"
        }
      },
      "kpis": {
        "totalTravelTime": "PT3H35M20S",
        "totalTravelDistanceMeters": 179450,
        "totalActivatedDrivers": 1,
        "totalUnassignedJobs": 0,
        "totalAssignedJobs": 1,
        "assignedMandatoryJobs": 1,
        "totalUnassignedStops": 0,
        "totalAssignedStops": 2,
        "assignedMandatoryStops": 2,
        "travelTimeFromStartLocationToFirstStop": "PT1H6M4S",
        "travelTimeBetweenStops": "PT49M50S",
        "travelTimeFromLastStopToEndLocation": "PT1H39M26S",
        "travelDistanceFromStartLocationToFirstStopMeters": 55061,
        "travelDistanceBetweenStopsMeters": 41530,
        "travelDistanceFromLastStopToEndLocationMeters": 82859
      }
    }
  ]
}
{
  "recommendations": [
    {
      "scoreDiff": "0hard/20000medium/-11405soft",
      "constraintDiffs": [
        {
          "score": "0hard/0medium/-11405soft",
          "constraintName": "Minimize travel time",
          "matchesDiff": [
            {
              "score": "0hard/0medium/-8147soft",
              "justification": {
                "stopId": "stop-2",
                "travelTime": "PT2H15M47S",
                "description": "Stop (stop-2) has travel time of 'PT2H15M47S'."
              }
            },
            {
              "score": "0hard/0medium/-3258soft",
              "justification": {
                "stopId": "stop-1",
                "travelTime": "PT54M18S",
                "description": "Stop (stop-1) has travel time of 'PT54M18S'."
              }
            }
          ],
          "matchCountDiff": 2
        },
        {
          "score": "0hard/20000medium/0soft",
          "constraintName": "Require scheduling mandatory stops",
          "matchesDiff": [
            {
              "score": "0hard/10000medium/0soft",
              "justification": {
                "stopId": "stop-1",
                "description": "Mandatory stop (stop-1) has been left unassigned."
              }
            },
            {
              "score": "0hard/10000medium/0soft",
              "justification": {
                "stopId": "stop-2",
                "description": "Mandatory stop (stop-2) has been left unassigned."
              }
            }
          ],
          "matchCountDiff": -2
        }
      ],
      "timeWindow": {
        "minStartTime": "2027-02-01T09:00:00Z",
        "maxEndTime": "2027-02-01T13:00:00Z"
      },
      "driverShift": {
        "id": "Ann-2027-02-01",
        "startTime": "2027-02-01T09:00:00Z",
        "itinerary": [
          {
            "id": "stop-1",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:54:18Z",
            "startServiceTime": "2027-02-01T09:54:18Z",
            "departureTime": "2027-02-01T10:04:18Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT54M18S",
            "travelDistanceMetersFromPreviousStandstill": 45245,
            "load": []
          },
          {
            "id": "stop-2",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:54:08Z",
            "startServiceTime": "2027-02-01T10:54:08Z",
            "departureTime": "2027-02-01T11:04:08Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT49M50S",
            "travelDistanceMetersFromPreviousStandstill": 41530,
            "load": []
          }
        ],
        "metrics": {
          "totalTravelTime": "PT3H10M5S",
          "travelTimeFromStartLocationToFirstStop": "PT54M18S",
          "travelTimeBetweenStops": "PT49M50S",
          "travelTimeFromLastStopToEndLocation": "PT1H25M57S",
          "totalTravelDistanceMeters": 158394,
          "travelDistanceFromStartLocationToFirstStopMeters": 45245,
          "travelDistanceBetweenStopsMeters": 41530,
          "travelDistanceFromLastStopToEndLocationMeters": 71619,
          "endLocationArrivalTime": "2027-02-01T12:30:05Z"
        }
      },
      "kpis": {
        "totalTravelTime": "PT3H10M5S",
        "totalTravelDistanceMeters": 158394,
        "totalActivatedDrivers": 1,
        "totalUnassignedJobs": 0,
        "totalAssignedJobs": 1,
        "assignedMandatoryJobs": 1,
        "totalUnassignedStops": 0,
        "totalAssignedStops": 2,
        "assignedMandatoryStops": 2,
        "travelTimeFromStartLocationToFirstStop": "PT54M18S",
        "travelTimeBetweenStops": "PT49M50S",
        "travelTimeFromLastStopToEndLocation": "PT1H25M57S",
        "travelDistanceFromStartLocationToFirstStopMeters": 45245,
        "travelDistanceBetweenStopsMeters": 41530,
        "travelDistanceFromLastStopToEndLocationMeters": 71619
      }
    },
    {
      "scoreDiff": "0hard/20000medium/-11405soft",
      "constraintDiffs": [
        {
          "score": "0hard/0medium/-11405soft",
          "constraintName": "Minimize travel time",
          "matchesDiff": [
            {
              "score": "0hard/0medium/-8147soft",
              "justification": {
                "stopId": "stop-2",
                "travelTime": "PT2H15M47S",
                "description": "Stop (stop-2) has travel time of 'PT2H15M47S'."
              }
            },
            {
              "score": "0hard/0medium/-3258soft",
              "justification": {
                "stopId": "stop-1",
                "travelTime": "PT54M18S",
                "description": "Stop (stop-1) has travel time of 'PT54M18S'."
              }
            }
          ],
          "matchCountDiff": 2
        },
        {
          "score": "0hard/20000medium/0soft",
          "constraintName": "Require scheduling mandatory stops",
          "matchesDiff": [
            {
              "score": "0hard/10000medium/0soft",
              "justification": {
                "stopId": "stop-1",
                "description": "Mandatory stop (stop-1) has been left unassigned."
              }
            },
            {
              "score": "0hard/10000medium/0soft",
              "justification": {
                "stopId": "stop-2",
                "description": "Mandatory stop (stop-2) has been left unassigned."
              }
            }
          ],
          "matchCountDiff": -2
        }
      ],
      "timeWindow": {
        "minStartTime": "2027-02-01T13:00:00Z",
        "maxEndTime": "2027-02-01T17:00:00Z"
      },
      "driverShift": {
        "id": "Ann-2027-02-01",
        "startTime": "2027-02-01T09:00:00Z",
        "itinerary": [
          {
            "id": "stop-1",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:54:18Z",
            "startServiceTime": "2027-02-01T13:00:00Z",
            "departureTime": "2027-02-01T13:10:00Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT54M18S",
            "travelDistanceMetersFromPreviousStandstill": 45245,
            "load": []
          },
          {
            "id": "stop-2",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T13:59:50Z",
            "startServiceTime": "2027-02-01T13:59:50Z",
            "departureTime": "2027-02-01T14:09:50Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT49M50S",
            "travelDistanceMetersFromPreviousStandstill": 41530,
            "load": []
          }
        ],
        "metrics": {
          "totalTravelTime": "PT3H10M5S",
          "travelTimeFromStartLocationToFirstStop": "PT54M18S",
          "travelTimeBetweenStops": "PT49M50S",
          "travelTimeFromLastStopToEndLocation": "PT1H25M57S",
          "totalTravelDistanceMeters": 158394,
          "travelDistanceFromStartLocationToFirstStopMeters": 45245,
          "travelDistanceBetweenStopsMeters": 41530,
          "travelDistanceFromLastStopToEndLocationMeters": 71619,
          "endLocationArrivalTime": "2027-02-01T15:35:47Z"
        }
      },
      "kpis": {
        "totalTravelTime": "PT3H10M5S",
        "totalTravelDistanceMeters": 158394,
        "totalActivatedDrivers": 1,
        "totalUnassignedJobs": 0,
        "totalAssignedJobs": 1,
        "assignedMandatoryJobs": 1,
        "totalUnassignedStops": 0,
        "totalAssignedStops": 2,
        "assignedMandatoryStops": 2,
        "travelTimeFromStartLocationToFirstStop": "PT54M18S",
        "travelTimeBetweenStops": "PT49M50S",
        "travelTimeFromLastStopToEndLocation": "PT1H25M57S",
        "travelDistanceFromStartLocationToFirstStopMeters": 45245,
        "travelDistanceBetweenStopsMeters": 41530,
        "travelDistanceFromLastStopToEndLocationMeters": 71619
      }
    },
    {
      "scoreDiff": "0hard/20000medium/-12920soft",
      "constraintDiffs": [
        {
          "score": "0hard/0medium/-12920soft",
          "constraintName": "Minimize travel time",
          "matchesDiff": [
            {
              "score": "0hard/0medium/-3964soft",
              "justification": {
                "stopId": "stop-1",
                "travelTime": "PT1H6M4S",
                "description": "Stop (stop-1) has travel time of 'PT1H6M4S'."
              }
            },
            {
              "score": "0hard/0medium/-8956soft",
              "justification": {
                "stopId": "stop-2",
                "travelTime": "PT2H29M16S",
                "description": "Stop (stop-2) has travel time of 'PT2H29M16S'."
              }
            }
          ],
          "matchCountDiff": 2
        },
        {
          "score": "0hard/20000medium/0soft",
          "constraintName": "Require scheduling mandatory stops",
          "matchesDiff": [
            {
              "score": "0hard/10000medium/0soft",
              "justification": {
                "stopId": "stop-1",
                "description": "Mandatory stop (stop-1) has been left unassigned."
              }
            },
            {
              "score": "0hard/10000medium/0soft",
              "justification": {
                "stopId": "stop-2",
                "description": "Mandatory stop (stop-2) has been left unassigned."
              }
            }
          ],
          "matchCountDiff": -2
        }
      ],
      "timeWindow": {
        "minStartTime": "2027-02-01T09:00:00Z",
        "maxEndTime": "2027-02-01T13:00:00Z"
      },
      "driverShift": {
        "id": "Beth-2027-02-01",
        "startTime": "2027-02-01T09:00:00Z",
        "itinerary": [
          {
            "id": "stop-1",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:06:04Z",
            "startServiceTime": "2027-02-01T10:06:04Z",
            "departureTime": "2027-02-01T10:16:04Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT1H6M4S",
            "travelDistanceMetersFromPreviousStandstill": 55061,
            "load": []
          },
          {
            "id": "stop-2",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T11:05:54Z",
            "startServiceTime": "2027-02-01T11:05:54Z",
            "departureTime": "2027-02-01T11:15:54Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT49M50S",
            "travelDistanceMetersFromPreviousStandstill": 41530,
            "load": []
          }
        ],
        "metrics": {
          "totalTravelTime": "PT3H35M20S",
          "travelTimeFromStartLocationToFirstStop": "PT1H6M4S",
          "travelTimeBetweenStops": "PT49M50S",
          "travelTimeFromLastStopToEndLocation": "PT1H39M26S",
          "totalTravelDistanceMeters": 179450,
          "travelDistanceFromStartLocationToFirstStopMeters": 55061,
          "travelDistanceBetweenStopsMeters": 41530,
          "travelDistanceFromLastStopToEndLocationMeters": 82859,
          "endLocationArrivalTime": "2027-02-01T12:55:20Z"
        }
      },
      "kpis": {
        "totalTravelTime": "PT3H35M20S",
        "totalTravelDistanceMeters": 179450,
        "totalActivatedDrivers": 1,
        "totalUnassignedJobs": 0,
        "totalAssignedJobs": 1,
        "assignedMandatoryJobs": 1,
        "totalUnassignedStops": 0,
        "totalAssignedStops": 2,
        "assignedMandatoryStops": 2,
        "travelTimeFromStartLocationToFirstStop": "PT1H6M4S",
        "travelTimeBetweenStops": "PT49M50S",
        "travelTimeFromLastStopToEndLocation": "PT1H39M26S",
        "travelDistanceFromStartLocationToFirstStopMeters": 55061,
        "travelDistanceBetweenStopsMeters": 41530,
        "travelDistanceFromLastStopToEndLocationMeters": 82859
      }
    },
    {
      "scoreDiff": "0hard/20000medium/-12920soft",
      "constraintDiffs": [
        {
          "score": "0hard/0medium/-12920soft",
          "constraintName": "Minimize travel time",
          "matchesDiff": [
            {
              "score": "0hard/0medium/-3964soft",
              "justification": {
                "stopId": "stop-1",
                "travelTime": "PT1H6M4S",
                "description": "Stop (stop-1) has travel time of 'PT1H6M4S'."
              }
            },
            {
              "score": "0hard/0medium/-8956soft",
              "justification": {
                "stopId": "stop-2",
                "travelTime": "PT2H29M16S",
                "description": "Stop (stop-2) has travel time of 'PT2H29M16S'."
              }
            }
          ],
          "matchCountDiff": 2
        },
        {
          "score": "0hard/20000medium/0soft",
          "constraintName": "Require scheduling mandatory stops",
          "matchesDiff": [
            {
              "score": "0hard/10000medium/0soft",
              "justification": {
                "stopId": "stop-1",
                "description": "Mandatory stop (stop-1) has been left unassigned."
              }
            },
            {
              "score": "0hard/10000medium/0soft",
              "justification": {
                "stopId": "stop-2",
                "description": "Mandatory stop (stop-2) has been left unassigned."
              }
            }
          ],
          "matchCountDiff": -2
        }
      ],
      "timeWindow": {
        "minStartTime": "2027-02-01T13:00:00Z",
        "maxEndTime": "2027-02-01T17:00:00Z"
      },
      "driverShift": {
        "id": "Beth-2027-02-01",
        "startTime": "2027-02-01T09:00:00Z",
        "itinerary": [
          {
            "id": "stop-1",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:06:04Z",
            "startServiceTime": "2027-02-01T13:00:00Z",
            "departureTime": "2027-02-01T13:10:00Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT1H6M4S",
            "travelDistanceMetersFromPreviousStandstill": 55061,
            "load": []
          },
          {
            "id": "stop-2",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T13:59:50Z",
            "startServiceTime": "2027-02-01T13:59:50Z",
            "departureTime": "2027-02-01T14:09:50Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT49M50S",
            "travelDistanceMetersFromPreviousStandstill": 41530,
            "load": []
          }
        ],
        "metrics": {
          "totalTravelTime": "PT3H35M20S",
          "travelTimeFromStartLocationToFirstStop": "PT1H6M4S",
          "travelTimeBetweenStops": "PT49M50S",
          "travelTimeFromLastStopToEndLocation": "PT1H39M26S",
          "totalTravelDistanceMeters": 179450,
          "travelDistanceFromStartLocationToFirstStopMeters": 55061,
          "travelDistanceBetweenStopsMeters": 41530,
          "travelDistanceFromLastStopToEndLocationMeters": 82859,
          "endLocationArrivalTime": "2027-02-01T15:49:16Z"
        }
      },
      "kpis": {
        "totalTravelTime": "PT3H35M20S",
        "totalTravelDistanceMeters": 179450,
        "totalActivatedDrivers": 1,
        "totalUnassignedJobs": 0,
        "totalAssignedJobs": 1,
        "assignedMandatoryJobs": 1,
        "totalUnassignedStops": 0,
        "totalAssignedStops": 2,
        "assignedMandatoryStops": 2,
        "travelTimeFromStartLocationToFirstStop": "PT1H6M4S",
        "travelTimeBetweenStops": "PT49M50S",
        "travelTimeFromLastStopToEndLocation": "PT1H39M26S",
        "travelDistanceFromStartLocationToFirstStopMeters": 55061,
        "travelDistanceBetweenStopsMeters": 41530,
        "travelDistanceFromLastStopToEndLocationMeters": 82859
      }
    }
  ]
}

1.3. The recommendations

In this example, there are a maximum of two recommendations per time window. Each recommendation relates to a driver shift. We have two time windows for a total of four recommendations for the job.

recommendations job time window unsolved

Each recommendation includes the following:

1.3.1. ScoreDiff

The score diff is based on the difference before the new job has been scheduled and after the new job has been scheduled.

{
  "scoreDiff": "0hard/20000medium/-11405soft"
}

1.3.2. Constraint scores without justifications

The score for each constraint that has changed, for instance:

{
  "score": "0hard/0medium/-11405soft",
  "constraintName": "Minimize travel time",
  "matchCountDiff": 2
}

1.3.3. Constraint scores with justifications

The score and justification for each constraint that has changed, for instance:

{
  "score": "0hard/0medium/-12920soft",
  "constraintName": "Minimize travel time",
  "matchesDiff": [
    {
      "score": "0hard/0medium/-3964soft",
      "justification": {
        "stopId": "stop-1",
        "travelTime": "PT1H6M4S",
        "description": "Stop (stop-1) has travel time of 'PT1H6M4S'."
      }
    },
    {
      "score": "0hard/0medium/-8956soft",
      "justification": {
        "stopId": "stop-2",
        "travelTime": "PT2H29M16S",
        "description": "Stop (stop-2) has travel time of 'PT2H29M16S'."
      }
    }
  ],
  "matchCountDiff": 2
}

1.3.4. The time window

The time window the recommendation is for:

{
  "timeWindow": {
    "minStartTime": "2027-02-01T09:00:00Z",
    "maxEndTime": "2027-02-01T13:00:00Z"
  }
}

1.3.5. The driver shift

The driver shift the recommendation applies to and the shift itinerary, metrics, and KPIs.

{
  "driverShift": {
    "id": "Ann-2027-02-01",
    "startTime": "2027-02-01T09:00:00Z",
    "itinerary": [
        {
            "id": "stop-1",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:54:18Z",
            "startServiceTime": "2027-02-01T09:54:18Z",
            "departureTime": "2027-02-01T10:04:18Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT54M18S",
            "travelDistanceMetersFromPreviousStandstill": 45245,
            "load": []
        },
        {
            "id": "stop-2",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:54:08Z",
            "startServiceTime": "2027-02-01T10:54:08Z",
            "departureTime": "2027-02-01T11:04:08Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT49M50S",
            "travelDistanceMetersFromPreviousStandstill": 41530,
            "load": []
        }
    ],
    "metrics": {
        "totalTravelTime": "PT3H10M5S",
        "travelTimeFromStartLocationToFirstStop": "PT54M18S",
        "travelTimeBetweenStops": "PT49M50S",
        "travelTimeFromLastStopToEndLocation": "PT1H25M57S",
        "totalTravelDistanceMeters": 158394,
        "travelDistanceFromStartLocationToFirstStopMeters": 45245,
        "travelDistanceBetweenStopsMeters": 41530,
        "travelDistanceFromLastStopToEndLocationMeters": 71619,
        "endLocationArrivalTime": "2027-02-01T12:30:05Z"
    }
  },
  "kpis": {
    "totalTravelTime": "PT3H10M5S",
    "totalTravelDistanceMeters": 158394,
    "totalActivatedDrivers": 1,
    "totalUnassignedJobs": 0,
    "totalAssignedJobs": 1,
    "assignedMandatoryJobs": 1,
    "totalUnassignedStops": 0,
    "totalAssignedStops": 2,
    "assignedMandatoryStops": 2,
    "travelTimeFromStartLocationToFirstStop": "PT54M18S",
    "travelTimeBetweenStops": "PT49M50S",
    "travelTimeFromLastStopToEndLocation": "PT1H25M57S",
    "travelDistanceFromStartLocationToFirstStopMeters": 45245,
    "travelDistanceBetweenStopsMeters": 41530,
    "travelDistanceFromLastStopToEndLocationMeters": 71619
  }
}

1.4. Implementing the recommendation

The recommendation output for this example includes four recommendations:

  1. Between 09:00 and 13:00 on February 1st with driver Ann.

  2. Between 13:00 and 17:00 on February 1st with driver Ann.

  3. Between 09:00 and 13:00 on February 1st with driver Beth.

  4. Between 13:00 and 17:00 on February 1st with driver Beth.

The recommendations include specific times, however, the plan is still a draft and those times will likely change as additional jobs are added to the plan.

If the customer agrees to one of the time windows, it must be added to the recommendation input dataset (the draft plan).

In this instance, the customer accepted the second recommendation:

  • Between 13:00 and 17:00 on February 1st with driver Ann.

First, add the job to Ann’s itinerary:

{
  "id": "Ann",
  "shifts": [
    {
      "id": "Ann-2027-02-01",
      "startLocation": [33.68786, -84.18487],
      "minStartTime": "2027-02-01T09:00:00Z",
      "maxEndTime": "2027-02-01T17:00:00Z",
      "itinerary": [
        {
          "id": "stop-1",
          "kind": "STOP"
        },
        {
          "id": "stop-2",
          "kind": "STOP"
        }
      ]
    }
  ]
}

Next, add the time window to the stops of the job:

{
  "id": "Job A",
  "stops": [
    {
      "id": "stop-1",
      "location": [
        33.84475,
        -84.63649
      ],
      "duration": "PT10M",
      "timeWindows": [
        {
          "minStartTime": "2027-02-01T13:00:00Z",
          "maxEndTime": "2027-02-01T17:00:00Z"
        }
      ]
    },
    {
      "id": "stop-2",
      "location": [
        33.57448,
        -84.94636
      ],
      "duration": "PT10M",
      "stopDependencies": [
        {
          "id": "prev-stop-2",
          "precedingStop": "stop-1"
        }
      ],
      "timeWindows": [
        {
          "minStartTime": "2027-02-01T13:00:00Z",
          "maxEndTime": "2027-02-01T17:00:00Z"
        }
      ]
    }
  ]
}
It is important to decide how to manage concurrent requests. If multiple requests are made for recommendations, which recommendation is added to the input dataset and what happens to other recommendations?

2. Recommendations for unsolved route plans with existing jobs

When additional customers call to request drivers for pick-up and delivery jobs, their requests can be added to the recommendation input dataset.

In the following example, a customer has called and needs a time window for Job B:

  • 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/recommendations/job-recommend-time-windows [email protected]
{
  "maxNumberOfRecommendationsPerTimeWindow": 2,
  "fitJobId": "Job B",
  "timeWindows": [
    {
      "minStartTime": "2027-02-01T09:00:00Z",
      "maxEndTime": "2027-02-01T13:00:00Z"
    },
    {
      "minStartTime": "2027-02-01T13:00:00Z",
      "maxEndTime": "2027-02-01T17:00:00Z"
    }
  ],
  "modelInput": {
    "drivers": [
      {
        "id": "Ann",
        "shifts": [
          {
            "id": "Ann-2027-02-01",
            "startLocation": [
              33.68786,
              -84.18487
            ],
            "minStartTime": "2027-02-01T09:00:00Z",
            "maxEndTime": "2027-02-01T17:00:00Z",
            "itinerary": [
              {
                "id": "stop-1",
                "kind": "STOP"
              },
              {
                "id": "stop-2",
                "kind": "STOP"
              }
            ]
          }
        ]
      },
      {
        "id": "Beth",
        "shifts": [
          {
            "id": "Beth-2027-02-01",
            "startLocation": [
              33.70474,
              -84.06508
            ],
            "minStartTime": "2027-02-01T09:00:00Z",
            "maxEndTime": "2027-02-01T17:00:00Z"
          }
        ]
      }
    ],
    "jobs": [
      {
        "id": "Job A",
        "stops": [
          {
            "id": "stop-1",
            "location": [
              33.84475,
              -84.63649
            ],
            "duration": "PT10M"
          },
          {
            "id": "stop-2",
            "location": [
              33.57448,
              -84.94636
            ],
            "duration": "PT10M",
            "stopDependencies": [
              {
                "id": "prev-stop-2",
                "precedingStop": "stop-1"
              }
            ]
          }
        ]
      },
      {
        "id": "Job B",
        "stops": [
          {
            "id": "stop-3",
            "location": [
              33.48574,
              -84.36969
            ],
            "duration": "PT10M"
          },
          {
            "id": "stop-4",
            "location": [
              33.78463,
              -84.35816
            ],
            "duration": "PT10M",
            "stopDependencies": [
              {
                "id": "prev-stop-4",
                "precedingStop": "stop-3"
              }
            ]
          }
        ]
      }
    ]
  }
}
{
  "recommendations": [
    {
      "scoreDiff": "0hard/20000medium/-2541soft",
      "constraintDiffs": [
        {
          "score": "0hard/0medium/-2541soft",
          "constraintName": "Minimize travel time",
          "matchCountDiff": 2
        },
        {
          "score": "0hard/20000medium/0soft",
          "constraintName": "Require scheduling mandatory stops",
          "matchCountDiff": -2
        }
      ],
      "timeWindow": {
        "minStartTime": "2027-02-01T13:00:00Z",
        "maxEndTime": "2027-02-01T17:00:00Z"
      },
      "driverShift": {
        "id": "Ann-2027-02-01",
        "startTime": "2027-02-01T09:00:00Z",
        "itinerary": [
          {
            "id": "stop-1",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:54:18Z",
            "startServiceTime": "2027-02-01T09:54:18Z",
            "departureTime": "2027-02-01T10:04:18Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT54M18S",
            "travelDistanceMetersFromPreviousStandstill": 45245,
            "load": []
          },
          {
            "id": "stop-2",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:54:08Z",
            "startServiceTime": "2027-02-01T10:54:08Z",
            "departureTime": "2027-02-01T11:04:08Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT49M50S",
            "travelDistanceMetersFromPreviousStandstill": 41530,
            "load": []
          },
          {
            "id": "stop-3",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T12:09:22Z",
            "startServiceTime": "2027-02-01T13:00:00Z",
            "departureTime": "2027-02-01T13:10:00Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT1H5M14S",
            "travelDistanceMetersFromPreviousStandstill": 54356,
            "load": []
          },
          {
            "id": "stop-4",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T13:49:54Z",
            "startServiceTime": "2027-02-01T13:49:54Z",
            "departureTime": "2027-02-01T13:59:54Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT39M54S",
            "travelDistanceMetersFromPreviousStandstill": 33252,
            "load": []
          }
        ],
        "metrics": {
          "totalTravelTime": "PT3H52M26S",
          "travelTimeFromStartLocationToFirstStop": "PT54M18S",
          "travelTimeBetweenStops": "PT2H34M58S",
          "travelTimeFromLastStopToEndLocation": "PT23M10S",
          "totalTravelDistanceMeters": 193685,
          "travelDistanceFromStartLocationToFirstStopMeters": 45245,
          "travelDistanceBetweenStopsMeters": 129138,
          "travelDistanceFromLastStopToEndLocationMeters": 19302,
          "endLocationArrivalTime": "2027-02-01T14:23:04Z"
        }
      },
      "kpis": {
        "totalTravelTime": "PT3H52M26S",
        "totalTravelDistanceMeters": 193685,
        "totalActivatedDrivers": 1,
        "totalUnassignedJobs": 0,
        "totalAssignedJobs": 2,
        "assignedMandatoryJobs": 2,
        "totalUnassignedStops": 0,
        "totalAssignedStops": 4,
        "assignedMandatoryStops": 4,
        "travelTimeFromStartLocationToFirstStop": "PT54M18S",
        "travelTimeBetweenStops": "PT2H34M58S",
        "travelTimeFromLastStopToEndLocation": "PT23M10S",
        "travelDistanceFromStartLocationToFirstStopMeters": 45245,
        "travelDistanceBetweenStopsMeters": 129138,
        "travelDistanceFromLastStopToEndLocationMeters": 19302
      }
    },
    {
      "scoreDiff": "0hard/20000medium/-3083soft",
      "constraintDiffs": [
        {
          "score": "0hard/0medium/-3083soft",
          "constraintName": "Minimize travel time",
          "matchCountDiff": 2
        },
        {
          "score": "0hard/20000medium/0soft",
          "constraintName": "Require scheduling mandatory stops",
          "matchCountDiff": -2
        }
      ],
      "timeWindow": {
        "minStartTime": "2027-02-01T09:00:00Z",
        "maxEndTime": "2027-02-01T13:00:00Z"
      },
      "driverShift": {
        "id": "Ann-2027-02-01",
        "startTime": "2027-02-01T09:00:00Z",
        "itinerary": [
          {
            "id": "stop-3",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:33:54Z",
            "startServiceTime": "2027-02-01T09:33:54Z",
            "departureTime": "2027-02-01T09:43:54Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT33M54S",
            "travelDistanceMetersFromPreviousStandstill": 28253,
            "load": []
          },
          {
            "id": "stop-4",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:23:48Z",
            "startServiceTime": "2027-02-01T10:23:48Z",
            "departureTime": "2027-02-01T10:33:48Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT39M54S",
            "travelDistanceMetersFromPreviousStandstill": 33252,
            "load": []
          },
          {
            "id": "stop-1",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T11:05:41Z",
            "startServiceTime": "2027-02-01T11:05:41Z",
            "departureTime": "2027-02-01T11:15:41Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT31M53S",
            "travelDistanceMetersFromPreviousStandstill": 26568,
            "load": []
          },
          {
            "id": "stop-2",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T12:05:31Z",
            "startServiceTime": "2027-02-01T12:05:31Z",
            "departureTime": "2027-02-01T12:15:31Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT49M50S",
            "travelDistanceMetersFromPreviousStandstill": 41530,
            "load": []
          }
        ],
        "metrics": {
          "totalTravelTime": "PT4H1M28S",
          "travelTimeFromStartLocationToFirstStop": "PT33M54S",
          "travelTimeBetweenStops": "PT2H1M37S",
          "travelTimeFromLastStopToEndLocation": "PT1H25M57S",
          "totalTravelDistanceMeters": 201222,
          "travelDistanceFromStartLocationToFirstStopMeters": 28253,
          "travelDistanceBetweenStopsMeters": 101350,
          "travelDistanceFromLastStopToEndLocationMeters": 71619,
          "endLocationArrivalTime": "2027-02-01T13:41:28Z"
        }
      },
      "kpis": {
        "totalTravelTime": "PT4H1M28S",
        "totalTravelDistanceMeters": 201222,
        "totalActivatedDrivers": 1,
        "totalUnassignedJobs": 0,
        "totalAssignedJobs": 2,
        "assignedMandatoryJobs": 2,
        "totalUnassignedStops": 0,
        "totalAssignedStops": 4,
        "assignedMandatoryStops": 4,
        "travelTimeFromStartLocationToFirstStop": "PT33M54S",
        "travelTimeBetweenStops": "PT2H1M37S",
        "travelTimeFromLastStopToEndLocation": "PT1H25M57S",
        "travelDistanceFromStartLocationToFirstStopMeters": 28253,
        "travelDistanceBetweenStopsMeters": 101350,
        "travelDistanceFromLastStopToEndLocationMeters": 71619
      }
    },
    {
      "scoreDiff": "0hard/20000medium/-7049soft",
      "constraintDiffs": [
        {
          "score": "0hard/0medium/-7049soft",
          "constraintName": "Minimize travel time",
          "matchCountDiff": 2
        },
        {
          "score": "0hard/20000medium/0soft",
          "constraintName": "Require scheduling mandatory stops",
          "matchCountDiff": -2
        }
      ],
      "timeWindow": {
        "minStartTime": "2027-02-01T09:00:00Z",
        "maxEndTime": "2027-02-01T13:00:00Z"
      },
      "driverShift": {
        "id": "Ann-2027-02-01",
        "startTime": "2027-02-01T09:00:00Z",
        "itinerary": [
          {
            "id": "stop-1",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:54:18Z",
            "startServiceTime": "2027-02-01T09:54:18Z",
            "departureTime": "2027-02-01T10:04:18Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT54M18S",
            "travelDistanceMetersFromPreviousStandstill": 45245,
            "load": []
          },
          {
            "id": "stop-3",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T11:00:38Z",
            "startServiceTime": "2027-02-01T11:00:38Z",
            "departureTime": "2027-02-01T11:10:38Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT56M20S",
            "travelDistanceMetersFromPreviousStandstill": 46939,
            "load": []
          },
          {
            "id": "stop-4",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T11:50:32Z",
            "startServiceTime": "2027-02-01T11:50:32Z",
            "departureTime": "2027-02-01T12:00:32Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT39M54S",
            "travelDistanceMetersFromPreviousStandstill": 33252,
            "load": []
          },
          {
            "id": "stop-2",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T13:11:37Z",
            "startServiceTime": "2027-02-01T13:11:37Z",
            "departureTime": "2027-02-01T13:21:37Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT1H11M5S",
            "travelDistanceMetersFromPreviousStandstill": 59231,
            "load": []
          }
        ],
        "metrics": {
          "totalTravelTime": "PT5H7M34S",
          "travelTimeFromStartLocationToFirstStop": "PT54M18S",
          "travelTimeBetweenStops": "PT2H47M19S",
          "travelTimeFromLastStopToEndLocation": "PT1H25M57S",
          "totalTravelDistanceMeters": 256286,
          "travelDistanceFromStartLocationToFirstStopMeters": 45245,
          "travelDistanceBetweenStopsMeters": 139422,
          "travelDistanceFromLastStopToEndLocationMeters": 71619,
          "endLocationArrivalTime": "2027-02-01T14:47:34Z"
        }
      },
      "kpis": {
        "totalTravelTime": "PT5H7M34S",
        "totalTravelDistanceMeters": 256286,
        "totalActivatedDrivers": 1,
        "totalUnassignedJobs": 0,
        "totalAssignedJobs": 2,
        "assignedMandatoryJobs": 2,
        "totalUnassignedStops": 0,
        "totalAssignedStops": 4,
        "assignedMandatoryStops": 4,
        "travelTimeFromStartLocationToFirstStop": "PT54M18S",
        "travelTimeBetweenStops": "PT2H47M19S",
        "travelTimeFromLastStopToEndLocation": "PT1H25M57S",
        "travelDistanceFromStartLocationToFirstStopMeters": 45245,
        "travelDistanceBetweenStopsMeters": 139422,
        "travelDistanceFromLastStopToEndLocationMeters": 71619
      }
    },
    {
      "scoreDiff": "0hard/20000medium/-7049soft",
      "constraintDiffs": [
        {
          "score": "0hard/0medium/-7049soft",
          "constraintName": "Minimize travel time",
          "matchCountDiff": 2
        },
        {
          "score": "0hard/20000medium/0soft",
          "constraintName": "Require scheduling mandatory stops",
          "matchCountDiff": -2
        }
      ],
      "timeWindow": {
        "minStartTime": "2027-02-01T13:00:00Z",
        "maxEndTime": "2027-02-01T17:00:00Z"
      },
      "driverShift": {
        "id": "Ann-2027-02-01",
        "startTime": "2027-02-01T09:00:00Z",
        "itinerary": [
          {
            "id": "stop-1",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:54:18Z",
            "startServiceTime": "2027-02-01T09:54:18Z",
            "departureTime": "2027-02-01T10:04:18Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT54M18S",
            "travelDistanceMetersFromPreviousStandstill": 45245,
            "load": []
          },
          {
            "id": "stop-3",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T11:00:38Z",
            "startServiceTime": "2027-02-01T13:00:00Z",
            "departureTime": "2027-02-01T13:10:00Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT56M20S",
            "travelDistanceMetersFromPreviousStandstill": 46939,
            "load": []
          },
          {
            "id": "stop-4",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T13:49:54Z",
            "startServiceTime": "2027-02-01T13:49:54Z",
            "departureTime": "2027-02-01T13:59:54Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT39M54S",
            "travelDistanceMetersFromPreviousStandstill": 33252,
            "load": []
          },
          {
            "id": "stop-2",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T15:10:59Z",
            "startServiceTime": "2027-02-01T15:10:59Z",
            "departureTime": "2027-02-01T15:20:59Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT1H11M5S",
            "travelDistanceMetersFromPreviousStandstill": 59231,
            "load": []
          }
        ],
        "metrics": {
          "totalTravelTime": "PT5H7M34S",
          "travelTimeFromStartLocationToFirstStop": "PT54M18S",
          "travelTimeBetweenStops": "PT2H47M19S",
          "travelTimeFromLastStopToEndLocation": "PT1H25M57S",
          "totalTravelDistanceMeters": 256286,
          "travelDistanceFromStartLocationToFirstStopMeters": 45245,
          "travelDistanceBetweenStopsMeters": 139422,
          "travelDistanceFromLastStopToEndLocationMeters": 71619,
          "endLocationArrivalTime": "2027-02-01T16:46:56Z"
        }
      },
      "kpis": {
        "totalTravelTime": "PT5H7M34S",
        "totalTravelDistanceMeters": 256286,
        "totalActivatedDrivers": 1,
        "totalUnassignedJobs": 0,
        "totalAssignedJobs": 2,
        "assignedMandatoryJobs": 2,
        "totalUnassignedStops": 0,
        "totalAssignedStops": 4,
        "assignedMandatoryStops": 4,
        "travelTimeFromStartLocationToFirstStop": "PT54M18S",
        "travelTimeBetweenStops": "PT2H47M19S",
        "travelTimeFromLastStopToEndLocation": "PT1H25M57S",
        "travelDistanceFromStartLocationToFirstStopMeters": 45245,
        "travelDistanceBetweenStopsMeters": 139422,
        "travelDistanceFromLastStopToEndLocationMeters": 71619
      }
    }
  ]
}

The recommendation output for this example includes four recommendations:

  1. Between 13:00 and 17:00 on February 1st with driver Ann.

  2. Between 09:00 and 13:00 on February 1st with driver Ann.

  3. Between 09:00 and 13:00 on February 1st with driver Ann.

  4. Between 13:00 and 17:00 on February 1st with driver Ann.

recommendations job time window unsolved 2

3. Recommendations for solved route plans

If a customer job needs to be added to a published schedule, the process for requesting recommendations is the same as above.

The following input dataset generated the schedule that is currently being executed:

  • 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": "Recommendations sample schedule"
    }
  },
  "modelInput": {
    "drivers": [
      {
        "id": "Ann",
        "shifts": [
          {
            "id": "Ann-2027-02-01",
            "startLocation": [
              33.68786,
              -84.18487
            ],
            "minStartTime": "2027-02-01T09:00:00Z",
            "maxEndTime": "2027-02-01T17:00:00Z"
          }
        ]
      },
      {
        "id": "Beth",
        "shifts": [
          {
            "id": "Beth-2027-02-01",
            "startLocation": [
              33.70474,
              -84.06508
            ],
            "minStartTime": "2027-02-01T09:00:00Z",
            "maxEndTime": "2027-02-01T17:00:00Z"
          }
        ]
      }
    ],
    "jobs": [
      {
        "id": "Job A",
        "stops": [
          {
            "id": "jobA-pickup",
            "name": "jobA-pickup",
            "location": [
              33.70701327565276,
              -84.32533338611672
            ],
            "duration": "PT10M"
          },
          {
            "id": "jobA-delivery",
            "name": "jobA-delivery",
            "location": [
              33.71731006962202,
              -84.37791873718393
            ],
            "duration": "PT5M",
            "stopDependencies": [
              {
                "id": "jobA-delivery_dep1",
                "precedingStop": "jobA-pickup"
              }
            ]
          }
        ]
      },
      {
        "id": "Job B",
        "stops": [
          {
            "id": "jobB-pickup",
            "name": "jobB-pickup",
            "location": [
              33.76284855890686,
              -84.30035807391094
            ],
            "duration": "PT10M"
          },
          {
            "id": "jobB-delivery",
            "name": "jobB-delivery",
            "location": [
              33.66913690724926,
              -84.40131814080493
            ],
            "duration": "PT5M",
            "stopDependencies": [
              {
                "id": "jobB-delivery_dep1",
                "precedingStop": "jobB-pickup"
              }
            ]
          }
        ]
      },
      {
        "id": "Job C",
        "stops": [
          {
            "id": "jobC-pickup",
            "name": "jobC-pickup",
            "location": [
              33.710952545550136,
              -84.32995136580453
            ],
            "duration": "PT10M"
          },
          {
            "id": "jobC-delivery",
            "name": "jobC-delivery",
            "location": [
              33.75503881265245,
              -84.41532534997714
            ],
            "duration": "PT5M",
            "stopDependencies": [
              {
                "id": "jobC-delivery_dep1",
                "precedingStop": "jobC-pickup"
              }
            ]
          }
        ]
      },
      {
        "id": "Job D",
        "stops": [
          {
            "id": "jobD-pickup",
            "name": "jobD-pickup",
            "location": [
              33.67152243761529,
              -84.25467147287567
            ],
            "duration": "PT10M"
          },
          {
            "id": "jobD-delivery",
            "name": "jobD-delivery",
            "location": [
              33.71070292968887,
              -84.42189409559566
            ],
            "duration": "PT5M",
            "stopDependencies": [
              {
                "id": "jobD-delivery_dep1",
                "precedingStop": "jobD-pickup"
              }
            ]
          }
        ]
      }
    ]
  }
}
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": "Recommendations sample schedule",
    "submitDateTime": "2026-02-03T14:37:18.647402+01:00",
    "startDateTime": "2026-02-03T14:37:18.717498+01:00",
    "activeDateTime": "2026-02-03T14:37:18.718545+01:00",
    "completeDateTime": "2026-02-03T14:37:48.737812+01:00",
    "shutdownDateTime": "2026-02-03T14:37:48.737817+01:00",
    "solverStatus": "SOLVING_COMPLETED",
    "score": "0hard/0medium/-4678soft",
    "validationResult": {
      "summary": "OK"
    }
  },
  "modelOutput": {
    "drivers": [
      {
        "id": "Ann",
        "shifts": [
          {
            "id": "Ann-2027-02-01",
            "startTime": "2027-02-01T09:00:00Z",
            "itinerary": [
              {
                "id": "jobD-pickup",
                "kind": "STOP",
                "arrivalTime": "2027-02-01T09:08:03Z",
                "startServiceTime": "2027-02-01T09:08:03Z",
                "departureTime": "2027-02-01T09:18:03Z",
                "effectiveServiceDuration": "PT10M",
                "travelTimeFromPreviousStandstill": "PT8M3S",
                "travelDistanceMetersFromPreviousStandstill": 6709,
                "load": []
              },
              {
                "id": "jobB-pickup",
                "kind": "STOP",
                "arrivalTime": "2027-02-01T09:31:15Z",
                "startServiceTime": "2027-02-01T09:31:15Z",
                "departureTime": "2027-02-01T09:41:15Z",
                "effectiveServiceDuration": "PT10M",
                "travelTimeFromPreviousStandstill": "PT13M12S",
                "travelDistanceMetersFromPreviousStandstill": 10999,
                "load": []
              },
              {
                "id": "jobA-pickup",
                "kind": "STOP",
                "arrivalTime": "2027-02-01T09:49:12Z",
                "startServiceTime": "2027-02-01T09:49:12Z",
                "departureTime": "2027-02-01T09:59:12Z",
                "effectiveServiceDuration": "PT10M",
                "travelTimeFromPreviousStandstill": "PT7M57S",
                "travelDistanceMetersFromPreviousStandstill": 6624,
                "load": []
              },
              {
                "id": "jobC-pickup",
                "kind": "STOP",
                "arrivalTime": "2027-02-01T09:59:56Z",
                "startServiceTime": "2027-02-01T09:59:56Z",
                "departureTime": "2027-02-01T10:09:56Z",
                "effectiveServiceDuration": "PT10M",
                "travelTimeFromPreviousStandstill": "PT44S",
                "travelDistanceMetersFromPreviousStandstill": 612,
                "load": []
              },
              {
                "id": "jobA-delivery",
                "kind": "STOP",
                "arrivalTime": "2027-02-01T10:15:19Z",
                "startServiceTime": "2027-02-01T10:15:19Z",
                "departureTime": "2027-02-01T10:20:19Z",
                "effectiveServiceDuration": "PT5M",
                "travelTimeFromPreviousStandstill": "PT5M23S",
                "travelDistanceMetersFromPreviousStandstill": 4493,
                "load": []
              },
              {
                "id": "jobC-delivery",
                "kind": "STOP",
                "arrivalTime": "2027-02-01T10:26:50Z",
                "startServiceTime": "2027-02-01T10:26:50Z",
                "departureTime": "2027-02-01T10:31:50Z",
                "effectiveServiceDuration": "PT5M",
                "travelTimeFromPreviousStandstill": "PT6M31S",
                "travelDistanceMetersFromPreviousStandstill": 5437,
                "load": []
              },
              {
                "id": "jobD-delivery",
                "kind": "STOP",
                "arrivalTime": "2027-02-01T10:37:48Z",
                "startServiceTime": "2027-02-01T10:37:48Z",
                "departureTime": "2027-02-01T10:42:48Z",
                "effectiveServiceDuration": "PT5M",
                "travelTimeFromPreviousStandstill": "PT5M58S",
                "travelDistanceMetersFromPreviousStandstill": 4967,
                "load": []
              },
              {
                "id": "jobB-delivery",
                "kind": "STOP",
                "arrivalTime": "2027-02-01T10:48:48Z",
                "startServiceTime": "2027-02-01T10:48:48Z",
                "departureTime": "2027-02-01T10:53:48Z",
                "effectiveServiceDuration": "PT5M",
                "travelTimeFromPreviousStandstill": "PT6M",
                "travelDistanceMetersFromPreviousStandstill": 4999,
                "load": []
              }
            ],
            "metrics": {
              "totalTravelTime": "PT1H17M58S",
              "travelTimeFromStartLocationToFirstStop": "PT8M3S",
              "travelTimeBetweenStops": "PT45M45S",
              "travelTimeFromLastStopToEndLocation": "PT24M10S",
              "totalTravelDistanceMeters": 64976,
              "travelDistanceFromStartLocationToFirstStopMeters": 6709,
              "travelDistanceBetweenStopsMeters": 38131,
              "travelDistanceFromLastStopToEndLocationMeters": 20136,
              "endLocationArrivalTime": "2027-02-01T11:17:58Z"
            }
          }
        ]
      },
      {
        "id": "Beth",
        "shifts": [
          {
            "id": "Beth-2027-02-01",
            "startTime": "2027-02-01T09:00:00Z",
            "itinerary": [],
            "metrics": {
              "totalTravelTime": "PT0S",
              "travelTimeFromStartLocationToFirstStop": "PT0S",
              "travelTimeBetweenStops": "PT0S",
              "travelTimeFromLastStopToEndLocation": "PT0S",
              "totalTravelDistanceMeters": 0,
              "travelDistanceFromStartLocationToFirstStopMeters": 0,
              "travelDistanceBetweenStopsMeters": 0,
              "travelDistanceFromLastStopToEndLocationMeters": 0
            }
          }
        ]
      }
    ],
    "unassignedJobs": []
  },
  "inputMetrics": {
    "jobs": 4,
    "stops": 8,
    "drivers": 2,
    "driverShifts": 2
  },
  "kpis": {
    "totalTravelTime": "PT1H17M58S",
    "totalTravelDistanceMeters": 64976,
    "totalActivatedDrivers": 1,
    "totalUnassignedJobs": 0,
    "totalAssignedJobs": 4,
    "assignedMandatoryJobs": 4,
    "totalUnassignedStops": 0,
    "totalAssignedStops": 8,
    "assignedMandatoryStops": 8,
    "travelTimeFromStartLocationToFirstStop": "PT8M3S",
    "travelTimeBetweenStops": "PT45M45S",
    "travelTimeFromLastStopToEndLocation": "PT24M10S",
    "travelDistanceFromStartLocationToFirstStopMeters": 6709,
    "travelDistanceBetweenStopsMeters": 38131,
    "travelDistanceFromLastStopToEndLocationMeters": 20136
  }
}

modelOutput contains Ann’s and Beth’s itineraries.

If a customer calls to request a driver on the same day, the following recommendations input dataset will return time window recommendations for the request (Job E):

  • 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/recommendations/job-recommend-time-windows [email protected]
{
  "maxNumberOfRecommendationsPerTimeWindow": 2,
  "fitJobId": "Job E",
  "timeWindows": [
    {
      "minStartTime": "2027-02-01T09:00:00Z",
      "maxEndTime": "2027-02-01T13:00:00Z"
    },
    {
      "minStartTime": "2027-02-01T13:00:00Z",
      "maxEndTime": "2027-02-01T17:00:00Z"
    }
  ],
  "modelInput": {
    "drivers": [
      {
        "id": "Ann",
        "shifts": [
          {
            "id": "Ann-2027-02-01",
            "startLocation": [
              33.68786,
              -84.18487
            ],
            "minStartTime": "2027-02-01T09:00:00Z",
            "maxEndTime": "2027-02-01T17:00:00Z",
            "itinerary": [
              {
                "id": "jobD-pickup",
                "kind": "STOP"
              },
              {
                "id": "jobB-pickup",
                "kind": "STOP"
              },
              {
                "id": "jobA-pickup",
                "kind": "STOP"
              },
              {
                "id": "jobC-pickup",
                "kind": "STOP"
              },
              {
                "id": "jobA-delivery",
                "kind": "STOP"
              },
              {
                "id": "jobC-delivery",
                "kind": "STOP"
              },
              {
                "id": "jobD-delivery",
                "kind": "STOP"
              },
              {
                "id": "jobB-delivery",
                "kind": "STOP"
              }
            ]
          }
        ]
      },
      {
        "id": "Beth",
        "shifts": [
          {
            "id": "Beth-2027-02-01",
            "startLocation": [
              33.70474,
              -84.06508
            ],
            "minStartTime": "2027-02-01T09:00:00Z",
            "maxEndTime": "2027-02-01T17:00:00Z"
          }
        ]
      }
    ],
    "jobs": [
      {
        "id": "Job A",
        "stops": [
          {
            "id": "jobA-pickup",
            "name": "jobA-pickup",
            "location": [
              33.70701327565276,
              -84.32533338611672
            ],
            "duration": "PT10M"
          },
          {
            "id": "jobA-delivery",
            "name": "jobA-delivery",
            "location": [
              33.71731006962202,
              -84.37791873718393
            ],
            "duration": "PT5M",
            "stopDependencies": [
              {
                "id": "jobA-delivery_dep1",
                "precedingStop": "jobA-pickup"
              }
            ]
          }
        ]
      },
      {
        "id": "Job B",
        "stops": [
          {
            "id": "jobB-pickup",
            "name": "jobB-pickup",
            "location": [
              33.76284855890686,
              -84.30035807391094
            ],
            "duration": "PT10M"
          },
          {
            "id": "jobB-delivery",
            "name": "jobB-delivery",
            "location": [
              33.66913690724926,
              -84.40131814080493
            ],
            "duration": "PT5M",
            "stopDependencies": [
              {
                "id": "jobB-delivery_dep1",
                "precedingStop": "jobB-pickup"
              }
            ]
          }
        ]
      },
      {
        "id": "Job C",
        "stops": [
          {
            "id": "jobC-pickup",
            "name": "jobC-pickup",
            "location": [
              33.710952545550136,
              -84.32995136580453
            ],
            "duration": "PT10M"
          },
          {
            "id": "jobC-delivery",
            "name": "jobC-delivery",
            "location": [
              33.75503881265245,
              -84.41532534997714
            ],
            "duration": "PT5M",
            "stopDependencies": [
              {
                "id": "jobC-delivery_dep1",
                "precedingStop": "jobC-pickup"
              }
            ]
          }
        ]
      },
      {
        "id": "Job D",
        "stops": [
          {
            "id": "jobD-pickup",
            "name": "jobD-pickup",
            "location": [
              33.67152243761529,
              -84.25467147287567
            ],
            "duration": "PT10M"
          },
          {
            "id": "jobD-delivery",
            "name": "jobD-delivery",
            "location": [
              33.71070292968887,
              -84.42189409559566
            ],
            "duration": "PT5M",
            "stopDependencies": [
              {
                "id": "jobD-delivery_dep1",
                "precedingStop": "jobD-pickup"
              }
            ]
          }
        ]
      },
      {
        "id": "Job E",
        "stops": [
          {
            "id": "jobE-pickup",
            "name": "jobE-pickup",
            "location": [
              33.76320212102979,
              -84.44574867672038
            ],
            "duration": "PT10M"
          },
          {
            "id": "jobE-delivery",
            "name": "jobE-delivery",
            "location": [
              33.68909752717026,
              -84.27707020988122
            ],
            "duration": "PT5M",
            "stopDependencies": [
              {
                "id": "jobE-delivery_dep1",
                "precedingStop": "jobE-pickup"
              }
            ]
          }
        ]
      }
    ]
  }
}
{
  "recommendations": [
    {
      "scoreDiff": "0hard/20000medium/-1243soft",
      "constraintDiffs": [
        {
          "score": "0hard/0medium/-1243soft",
          "constraintName": "Minimize travel time",
          "matchCountDiff": 2
        },
        {
          "score": "0hard/20000medium/0soft",
          "constraintName": "Require scheduling mandatory stops",
          "matchCountDiff": -2
        }
      ],
      "timeWindow": {
        "minStartTime": "2027-02-01T09:00:00Z",
        "maxEndTime": "2027-02-01T13:00:00Z"
      },
      "driverShift": {
        "id": "Ann-2027-02-01",
        "startTime": "2027-02-01T09:00:00Z",
        "itinerary": [
          {
            "id": "jobD-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:08:03Z",
            "startServiceTime": "2027-02-01T09:08:03Z",
            "departureTime": "2027-02-01T09:18:03Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT8M3S",
            "travelDistanceMetersFromPreviousStandstill": 6709,
            "load": []
          },
          {
            "id": "jobB-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:31:15Z",
            "startServiceTime": "2027-02-01T09:31:15Z",
            "departureTime": "2027-02-01T09:41:15Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT13M12S",
            "travelDistanceMetersFromPreviousStandstill": 10999,
            "load": []
          },
          {
            "id": "jobA-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:49:12Z",
            "startServiceTime": "2027-02-01T09:49:12Z",
            "departureTime": "2027-02-01T09:59:12Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT7M57S",
            "travelDistanceMetersFromPreviousStandstill": 6624,
            "load": []
          },
          {
            "id": "jobC-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:59:56Z",
            "startServiceTime": "2027-02-01T09:59:56Z",
            "departureTime": "2027-02-01T10:09:56Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT44S",
            "travelDistanceMetersFromPreviousStandstill": 612,
            "load": []
          },
          {
            "id": "jobA-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:15:19Z",
            "startServiceTime": "2027-02-01T10:15:19Z",
            "departureTime": "2027-02-01T10:20:19Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT5M23S",
            "travelDistanceMetersFromPreviousStandstill": 4493,
            "load": []
          },
          {
            "id": "jobC-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:26:50Z",
            "startServiceTime": "2027-02-01T10:26:50Z",
            "departureTime": "2027-02-01T10:31:50Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT6M31S",
            "travelDistanceMetersFromPreviousStandstill": 5437,
            "load": []
          },
          {
            "id": "jobD-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:37:48Z",
            "startServiceTime": "2027-02-01T10:37:48Z",
            "departureTime": "2027-02-01T10:42:48Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT5M58S",
            "travelDistanceMetersFromPreviousStandstill": 4967,
            "load": []
          },
          {
            "id": "jobB-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:48:48Z",
            "startServiceTime": "2027-02-01T10:48:48Z",
            "departureTime": "2027-02-01T10:53:48Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT6M",
            "travelDistanceMetersFromPreviousStandstill": 4999,
            "load": []
          },
          {
            "id": "jobE-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T11:07:17Z",
            "startServiceTime": "2027-02-01T11:07:17Z",
            "departureTime": "2027-02-01T11:17:17Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT13M29S",
            "travelDistanceMetersFromPreviousStandstill": 11238,
            "load": []
          },
          {
            "id": "jobE-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T11:38:27Z",
            "startServiceTime": "2027-02-01T11:38:27Z",
            "departureTime": "2027-02-01T11:43:27Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT21M10S",
            "travelDistanceMetersFromPreviousStandstill": 17642,
            "load": []
          }
        ],
        "metrics": {
          "totalTravelTime": "PT1H38M41S",
          "travelTimeFromStartLocationToFirstStop": "PT8M3S",
          "travelTimeBetweenStops": "PT1H20M24S",
          "travelTimeFromLastStopToEndLocation": "PT10M14S",
          "totalTravelDistanceMeters": 82252,
          "travelDistanceFromStartLocationToFirstStopMeters": 6709,
          "travelDistanceBetweenStopsMeters": 67011,
          "travelDistanceFromLastStopToEndLocationMeters": 8532,
          "endLocationArrivalTime": "2027-02-01T11:53:41Z"
        }
      },
      "kpis": {
        "totalTravelTime": "PT1H38M41S",
        "totalTravelDistanceMeters": 82252,
        "totalActivatedDrivers": 1,
        "totalUnassignedJobs": 0,
        "totalAssignedJobs": 5,
        "assignedMandatoryJobs": 5,
        "totalUnassignedStops": 0,
        "totalAssignedStops": 10,
        "assignedMandatoryStops": 10,
        "travelTimeFromStartLocationToFirstStop": "PT8M3S",
        "travelTimeBetweenStops": "PT1H20M24S",
        "travelTimeFromLastStopToEndLocation": "PT10M14S",
        "travelDistanceFromStartLocationToFirstStopMeters": 6709,
        "travelDistanceBetweenStopsMeters": 67011,
        "travelDistanceFromLastStopToEndLocationMeters": 8532
      }
    },
    {
      "scoreDiff": "0hard/20000medium/-1243soft",
      "constraintDiffs": [
        {
          "score": "0hard/0medium/-1243soft",
          "constraintName": "Minimize travel time",
          "matchCountDiff": 2
        },
        {
          "score": "0hard/20000medium/0soft",
          "constraintName": "Require scheduling mandatory stops",
          "matchCountDiff": -2
        }
      ],
      "timeWindow": {
        "minStartTime": "2027-02-01T13:00:00Z",
        "maxEndTime": "2027-02-01T17:00:00Z"
      },
      "driverShift": {
        "id": "Ann-2027-02-01",
        "startTime": "2027-02-01T09:00:00Z",
        "itinerary": [
          {
            "id": "jobD-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:08:03Z",
            "startServiceTime": "2027-02-01T09:08:03Z",
            "departureTime": "2027-02-01T09:18:03Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT8M3S",
            "travelDistanceMetersFromPreviousStandstill": 6709,
            "load": []
          },
          {
            "id": "jobB-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:31:15Z",
            "startServiceTime": "2027-02-01T09:31:15Z",
            "departureTime": "2027-02-01T09:41:15Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT13M12S",
            "travelDistanceMetersFromPreviousStandstill": 10999,
            "load": []
          },
          {
            "id": "jobA-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:49:12Z",
            "startServiceTime": "2027-02-01T09:49:12Z",
            "departureTime": "2027-02-01T09:59:12Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT7M57S",
            "travelDistanceMetersFromPreviousStandstill": 6624,
            "load": []
          },
          {
            "id": "jobC-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:59:56Z",
            "startServiceTime": "2027-02-01T09:59:56Z",
            "departureTime": "2027-02-01T10:09:56Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT44S",
            "travelDistanceMetersFromPreviousStandstill": 612,
            "load": []
          },
          {
            "id": "jobA-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:15:19Z",
            "startServiceTime": "2027-02-01T10:15:19Z",
            "departureTime": "2027-02-01T10:20:19Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT5M23S",
            "travelDistanceMetersFromPreviousStandstill": 4493,
            "load": []
          },
          {
            "id": "jobC-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:26:50Z",
            "startServiceTime": "2027-02-01T10:26:50Z",
            "departureTime": "2027-02-01T10:31:50Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT6M31S",
            "travelDistanceMetersFromPreviousStandstill": 5437,
            "load": []
          },
          {
            "id": "jobD-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:37:48Z",
            "startServiceTime": "2027-02-01T10:37:48Z",
            "departureTime": "2027-02-01T10:42:48Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT5M58S",
            "travelDistanceMetersFromPreviousStandstill": 4967,
            "load": []
          },
          {
            "id": "jobB-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:48:48Z",
            "startServiceTime": "2027-02-01T10:48:48Z",
            "departureTime": "2027-02-01T10:53:48Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT6M",
            "travelDistanceMetersFromPreviousStandstill": 4999,
            "load": []
          },
          {
            "id": "jobE-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T11:07:17Z",
            "startServiceTime": "2027-02-01T13:00:00Z",
            "departureTime": "2027-02-01T13:10:00Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT13M29S",
            "travelDistanceMetersFromPreviousStandstill": 11238,
            "load": []
          },
          {
            "id": "jobE-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T13:31:10Z",
            "startServiceTime": "2027-02-01T13:31:10Z",
            "departureTime": "2027-02-01T13:36:10Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT21M10S",
            "travelDistanceMetersFromPreviousStandstill": 17642,
            "load": []
          }
        ],
        "metrics": {
          "totalTravelTime": "PT1H38M41S",
          "travelTimeFromStartLocationToFirstStop": "PT8M3S",
          "travelTimeBetweenStops": "PT1H20M24S",
          "travelTimeFromLastStopToEndLocation": "PT10M14S",
          "totalTravelDistanceMeters": 82252,
          "travelDistanceFromStartLocationToFirstStopMeters": 6709,
          "travelDistanceBetweenStopsMeters": 67011,
          "travelDistanceFromLastStopToEndLocationMeters": 8532,
          "endLocationArrivalTime": "2027-02-01T13:46:24Z"
        }
      },
      "kpis": {
        "totalTravelTime": "PT1H38M41S",
        "totalTravelDistanceMeters": 82252,
        "totalActivatedDrivers": 1,
        "totalUnassignedJobs": 0,
        "totalAssignedJobs": 5,
        "assignedMandatoryJobs": 5,
        "totalUnassignedStops": 0,
        "totalAssignedStops": 10,
        "assignedMandatoryStops": 10,
        "travelTimeFromStartLocationToFirstStop": "PT8M3S",
        "travelTimeBetweenStops": "PT1H20M24S",
        "travelTimeFromLastStopToEndLocation": "PT10M14S",
        "travelDistanceFromStartLocationToFirstStopMeters": 6709,
        "travelDistanceBetweenStopsMeters": 67011,
        "travelDistanceFromLastStopToEndLocationMeters": 8532
      }
    },
    {
      "scoreDiff": "0hard/20000medium/-2105soft",
      "constraintDiffs": [
        {
          "score": "0hard/0medium/-2105soft",
          "constraintName": "Minimize travel time",
          "matchCountDiff": 2
        },
        {
          "score": "0hard/20000medium/0soft",
          "constraintName": "Require scheduling mandatory stops",
          "matchCountDiff": -2
        }
      ],
      "timeWindow": {
        "minStartTime": "2027-02-01T09:00:00Z",
        "maxEndTime": "2027-02-01T13:00:00Z"
      },
      "driverShift": {
        "id": "Ann-2027-02-01",
        "startTime": "2027-02-01T09:00:00Z",
        "itinerary": [
          {
            "id": "jobD-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:08:03Z",
            "startServiceTime": "2027-02-01T09:08:03Z",
            "departureTime": "2027-02-01T09:18:03Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT8M3S",
            "travelDistanceMetersFromPreviousStandstill": 6709,
            "load": []
          },
          {
            "id": "jobB-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:31:15Z",
            "startServiceTime": "2027-02-01T09:31:15Z",
            "departureTime": "2027-02-01T09:41:15Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT13M12S",
            "travelDistanceMetersFromPreviousStandstill": 10999,
            "load": []
          },
          {
            "id": "jobA-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:49:12Z",
            "startServiceTime": "2027-02-01T09:49:12Z",
            "departureTime": "2027-02-01T09:59:12Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT7M57S",
            "travelDistanceMetersFromPreviousStandstill": 6624,
            "load": []
          },
          {
            "id": "jobC-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:59:56Z",
            "startServiceTime": "2027-02-01T09:59:56Z",
            "departureTime": "2027-02-01T10:09:56Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT44S",
            "travelDistanceMetersFromPreviousStandstill": 612,
            "load": []
          },
          {
            "id": "jobA-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:15:19Z",
            "startServiceTime": "2027-02-01T10:15:19Z",
            "departureTime": "2027-02-01T10:20:19Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT5M23S",
            "travelDistanceMetersFromPreviousStandstill": 4493,
            "load": []
          },
          {
            "id": "jobC-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:26:50Z",
            "startServiceTime": "2027-02-01T10:26:50Z",
            "departureTime": "2027-02-01T10:31:50Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT6M31S",
            "travelDistanceMetersFromPreviousStandstill": 5437,
            "load": []
          },
          {
            "id": "jobE-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:35:23Z",
            "startServiceTime": "2027-02-01T10:35:23Z",
            "departureTime": "2027-02-01T10:45:23Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT3M33S",
            "travelDistanceMetersFromPreviousStandstill": 2955,
            "load": []
          },
          {
            "id": "jobE-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T11:06:33Z",
            "startServiceTime": "2027-02-01T11:06:33Z",
            "departureTime": "2027-02-01T11:11:33Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT21M10S",
            "travelDistanceMetersFromPreviousStandstill": 17642,
            "load": []
          },
          {
            "id": "jobD-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T11:27:53Z",
            "startServiceTime": "2027-02-01T11:27:53Z",
            "departureTime": "2027-02-01T11:32:53Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT16M20S",
            "travelDistanceMetersFromPreviousStandstill": 13611,
            "load": []
          },
          {
            "id": "jobB-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T11:38:53Z",
            "startServiceTime": "2027-02-01T11:38:53Z",
            "departureTime": "2027-02-01T11:43:53Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT6M",
            "travelDistanceMetersFromPreviousStandstill": 4999,
            "load": []
          }
        ],
        "metrics": {
          "totalTravelTime": "PT1H53M3S",
          "travelTimeFromStartLocationToFirstStop": "PT8M3S",
          "travelTimeBetweenStops": "PT1H20M50S",
          "travelTimeFromLastStopToEndLocation": "PT24M10S",
          "totalTravelDistanceMeters": 94217,
          "travelDistanceFromStartLocationToFirstStopMeters": 6709,
          "travelDistanceBetweenStopsMeters": 67372,
          "travelDistanceFromLastStopToEndLocationMeters": 20136,
          "endLocationArrivalTime": "2027-02-01T12:08:03Z"
        }
      },
      "kpis": {
        "totalTravelTime": "PT1H53M3S",
        "totalTravelDistanceMeters": 94217,
        "totalActivatedDrivers": 1,
        "totalUnassignedJobs": 0,
        "totalAssignedJobs": 5,
        "assignedMandatoryJobs": 5,
        "totalUnassignedStops": 0,
        "totalAssignedStops": 10,
        "assignedMandatoryStops": 10,
        "travelTimeFromStartLocationToFirstStop": "PT8M3S",
        "travelTimeBetweenStops": "PT1H20M50S",
        "travelTimeFromLastStopToEndLocation": "PT24M10S",
        "travelDistanceFromStartLocationToFirstStopMeters": 6709,
        "travelDistanceBetweenStopsMeters": 67372,
        "travelDistanceFromLastStopToEndLocationMeters": 20136
      }
    },
    {
      "scoreDiff": "0hard/20000medium/-2105soft",
      "constraintDiffs": [
        {
          "score": "0hard/0medium/-2105soft",
          "constraintName": "Minimize travel time",
          "matchCountDiff": 2
        },
        {
          "score": "0hard/20000medium/0soft",
          "constraintName": "Require scheduling mandatory stops",
          "matchCountDiff": -2
        }
      ],
      "timeWindow": {
        "minStartTime": "2027-02-01T13:00:00Z",
        "maxEndTime": "2027-02-01T17:00:00Z"
      },
      "driverShift": {
        "id": "Ann-2027-02-01",
        "startTime": "2027-02-01T09:00:00Z",
        "itinerary": [
          {
            "id": "jobD-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:08:03Z",
            "startServiceTime": "2027-02-01T09:08:03Z",
            "departureTime": "2027-02-01T09:18:03Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT8M3S",
            "travelDistanceMetersFromPreviousStandstill": 6709,
            "load": []
          },
          {
            "id": "jobB-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:31:15Z",
            "startServiceTime": "2027-02-01T09:31:15Z",
            "departureTime": "2027-02-01T09:41:15Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT13M12S",
            "travelDistanceMetersFromPreviousStandstill": 10999,
            "load": []
          },
          {
            "id": "jobA-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:49:12Z",
            "startServiceTime": "2027-02-01T09:49:12Z",
            "departureTime": "2027-02-01T09:59:12Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT7M57S",
            "travelDistanceMetersFromPreviousStandstill": 6624,
            "load": []
          },
          {
            "id": "jobC-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T09:59:56Z",
            "startServiceTime": "2027-02-01T09:59:56Z",
            "departureTime": "2027-02-01T10:09:56Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT44S",
            "travelDistanceMetersFromPreviousStandstill": 612,
            "load": []
          },
          {
            "id": "jobA-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:15:19Z",
            "startServiceTime": "2027-02-01T10:15:19Z",
            "departureTime": "2027-02-01T10:20:19Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT5M23S",
            "travelDistanceMetersFromPreviousStandstill": 4493,
            "load": []
          },
          {
            "id": "jobC-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:26:50Z",
            "startServiceTime": "2027-02-01T10:26:50Z",
            "departureTime": "2027-02-01T10:31:50Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT6M31S",
            "travelDistanceMetersFromPreviousStandstill": 5437,
            "load": []
          },
          {
            "id": "jobE-pickup",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T10:35:23Z",
            "startServiceTime": "2027-02-01T13:00:00Z",
            "departureTime": "2027-02-01T13:10:00Z",
            "effectiveServiceDuration": "PT10M",
            "travelTimeFromPreviousStandstill": "PT3M33S",
            "travelDistanceMetersFromPreviousStandstill": 2955,
            "load": []
          },
          {
            "id": "jobE-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T13:31:10Z",
            "startServiceTime": "2027-02-01T13:31:10Z",
            "departureTime": "2027-02-01T13:36:10Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT21M10S",
            "travelDistanceMetersFromPreviousStandstill": 17642,
            "load": []
          },
          {
            "id": "jobD-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T13:52:30Z",
            "startServiceTime": "2027-02-01T13:52:30Z",
            "departureTime": "2027-02-01T13:57:30Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT16M20S",
            "travelDistanceMetersFromPreviousStandstill": 13611,
            "load": []
          },
          {
            "id": "jobB-delivery",
            "kind": "STOP",
            "arrivalTime": "2027-02-01T14:03:30Z",
            "startServiceTime": "2027-02-01T14:03:30Z",
            "departureTime": "2027-02-01T14:08:30Z",
            "effectiveServiceDuration": "PT5M",
            "travelTimeFromPreviousStandstill": "PT6M",
            "travelDistanceMetersFromPreviousStandstill": 4999,
            "load": []
          }
        ],
        "metrics": {
          "totalTravelTime": "PT1H53M3S",
          "travelTimeFromStartLocationToFirstStop": "PT8M3S",
          "travelTimeBetweenStops": "PT1H20M50S",
          "travelTimeFromLastStopToEndLocation": "PT24M10S",
          "totalTravelDistanceMeters": 94217,
          "travelDistanceFromStartLocationToFirstStopMeters": 6709,
          "travelDistanceBetweenStopsMeters": 67372,
          "travelDistanceFromLastStopToEndLocationMeters": 20136,
          "endLocationArrivalTime": "2027-02-01T14:32:40Z"
        }
      },
      "kpis": {
        "totalTravelTime": "PT1H53M3S",
        "totalTravelDistanceMeters": 94217,
        "totalActivatedDrivers": 1,
        "totalUnassignedJobs": 0,
        "totalAssignedJobs": 5,
        "assignedMandatoryJobs": 5,
        "totalUnassignedStops": 0,
        "totalAssignedStops": 10,
        "assignedMandatoryStops": 10,
        "travelTimeFromStartLocationToFirstStop": "PT8M3S",
        "travelTimeBetweenStops": "PT1H20M50S",
        "travelTimeFromLastStopToEndLocation": "PT24M10S",
        "travelDistanceFromStartLocationToFirstStopMeters": 6709,
        "travelDistanceBetweenStopsMeters": 67372,
        "travelDistanceFromLastStopToEndLocationMeters": 20136
      }
    }
  ]
}

The recommendation output for this example includes four recommendations for Job E:

  1. Between 09:00 and 13:00 on February 1st with driver Ann

  2. Between 13:00 and 17:00 on February 1st with driver Ann

  3. Between 09:00 and 13:00 on February 1st with driver Ann

  4. Between 13:00 and 17:00 on February 1st with driver Ann

As configured with maxNumberOfRecommendationsPerTimeWindow there are two recommendations for each requested time window. By looking at the actual routes, the differences between these recommendations become noticeable:

  • Recommendation 1

  • Recommendation 2

  • Recommendation 3

  • Recommendation 4

Route of recommendation 1 with the start service time and the stop ID:

09:08:03    jobD-pickup
09:31:15    jobB-pickup
09:49:12    jobA-pickup
09:59:56    jobC-pickup
10:15:19    jobA-delivery
10:26:50    jobC-delivery
10:37:48    jobD-delivery
10:48:48    jobB-delivery
11:07:17    jobE-pickup
11:38:27    jobE-delivery

Route of recommendation 2 with the start service time and the stop ID:

09:08:03    jobD-pickup
09:31:15    jobB-pickup
09:49:12    jobA-pickup
09:59:56    jobC-pickup
10:15:19    jobA-delivery
10:26:50    jobC-delivery
10:37:48    jobD-delivery
10:48:48    jobB-delivery
13:00:00    jobE-pickup
13:31:10    jobE-delivery

Route of recommendation 3 with the start service time and the stop ID:

09:08:03    jobD-pickup
09:31:15    jobB-pickup
09:49:12    jobA-pickup
09:59:56    jobC-pickup
10:15:19    jobA-delivery
10:26:50    jobC-delivery
10:35:23    jobE-pickup
11:06:33    jobE-delivery
11:27:53    jobD-delivery
11:38:53    jobB-delivery

Route of recommendation 4 with the start service time and the stop ID:

09:08:03    jobD-pickup
09:31:15    jobB-pickup
09:49:12    jobA-pickup
09:59:56    jobC-pickup
10:15:19    jobA-delivery
10:26:50    jobC-delivery
13:00:00    jobE-pickup
13:31:10    jobE-delivery
13:52:30    jobD-delivery
14:03:30    jobB-delivery

After the customer has accepted one of the time windows, include the job in the optimized plan for the day as shown above. Failure to update the real-time plan will lead to errors with Job E not being included if there are further updates to the plan throughout the day.

Next

  • See the full API spec or try the online API.

  • Learn about Stop time window recommendations.

  • © 2026 Timefold BV
  • Timefold.ai
  • Documentation
  • Changelog
  • Send feedback
  • Privacy
  • Legal
    • Light mode
    • Dark mode
    • System default