Docs
  • Solver
  • Models
    • Field Service Routing
    • Employee Shift Scheduling
    • Pick-up and Delivery Routing
  • Platform
Try models
  • Pick-up and Delivery Routing
  • Upgrading to the latest versions

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
      • Driver capacity
    • Job service constraints
      • Time windows and opening hours
      • Skills
      • Multi-day schedules and movable stops
      • 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
        • 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

Upgrading to the latest versions

From 0.65.0 to 0.66.0

Renaming constraints for clarity

To improve clarity and consistency in the API, we have renamed some constraints in the Pick-up and Delivery Routing model. This includes changes to constraint weight names in the OpenAPI specification.

Below is an overview of the old and updated constraint weight names. If you are using any of the old constraint weight names in your API calls, please update them to the new names.

Old constraint weight name Updated constraint weight name

matchPreferredDriversWeight

assignPreferredDriversWeight

maxSoftShiftEndTimeWeight

preferredShiftEndTimeWeight

maxSoftLastStopDepartureTimeWeight

preferredFinalStopDepartureTimeWeight

latestSlaEndTimeWeight

minimizeBreachingSlasWeight

Removing stop dependencies from the input API

The StopDependency type has been removed from the input API. The StopDependency type was used to define the dependencies between stops in a job. The order of the stops in the list of stops for a job is now considered as the required sequence of these stops, and therefore defines the dependencies between the stops.

In order to update your input to the new API, remove stopDependencies from your input and make sure the stops in the list of stops for each job are in the correct order.

From 0.60.0 to 0.61.0

Made the output clearer for unreachable locations

The unreachable driver shifts no longer use +999999999-12-31T23:59:59.999999999-18:00 to represent an unreachable endLocationArrivalTime. The model output DriverShiftPlan no longer includes endLocationArrivalTime for output driver shifts that are unreachable on the map because endLocationArrivalTime value cannot be determined in that case.

The unreachable itinerary items no longer use +999999999-12-31T23:59:59.999999999-18:00 to represent an unreachable arrivalTime, startServiceTime or departureTime. The model output StopPlan no longer includes the above attributes for output driver shift itinerary items that are unreachable on the map.

The unreachable itinerary items no longer use 263-1 to represent the travel time or distance of an unreachable route, for instance in travelTimeFromPreviousStandstill and travelDistanceMetersFromPreviousStandstill.

The model output elements DriverShiftPlan, StopPlan and BreakPlan now contain the unreachable boolean attribute indicating:

  • DriverShiftPlan.unreachable = true: The driver shift itinerary contains a route between two locations that is unreachable on the map, such a route can be:

    • From the driver shift start location to the first stop or break with location.

    • From a break with location to the next break with location or the next stop.

    • From a stop to the next break with location or the next stop.

    • From the last stop or break with location to the driver shift end location.

  • StopPlan.unreachable = true: The previous itinerary item is unreachable or the route from the previous stop, location break, or driver shift start to the stop location is not reachable on the map.

  • BreakPlan.unreachable = true: The previous itinerary item is unreachable or the route from the previous stop, location break, or driver shift start to the break location is not reachable on the map.

The unreachable attribute is omitted when false to avoid increasing payload size.

Check the following example of a shift that assigned an unreachable stop and an unreachable break.

Before:

{
  "modelOutput": {
    "drivers": [
      {
        "shifts": [
          {
            "id": "Ann - Monday",
            "itinerary": [
              {
                "id": "Stop A",
                "kind": "STOP",
                "arrivalTime": "+999999999-12-31T23:59:59.999999999-18:00",
                "startServiceTime": "+999999999-12-31T23:59:59.999999999-18:00",
                "departureTime": "+999999999-12-31T23:59:59.999999999-18:00",
                "travelTimeFromPreviousStandstill": "PT2562047788015215H30M7S",
                "travelDistanceMetersFromPreviousStandstill": 9223372036854775807
              },
              {
                "id": "Break 1",
                "kind": "BREAK",
                "startTime": "2026-01-12T14:00:00-04:00",
                "endTime": "2026-01-12T15:00:00-04:00",
                "travelTimeFromPreviousStandstill": "PT2562047788015215H30M7S",
                "travelDistanceMetersFromPreviousStandstill": 9223372036854775807
              }
            ],
            "metrics": {
              "endLocationArrivalTime": "+999999999-12-31T23:59:59.999999999-18:00"
            }
          }
        ]
      }
    ]
  }
}

After:

{
  "modelOutput": {
    "drivers": [
      {
        "shifts": [
          {
            "id": "Ann - Monday",
            "itinerary": [
              {
                "id": "Stop A",
                "kind": "STOP",
                "unreachable": true
              },
              {
                "id": "Break 1",
                "kind": "BREAK",
                "startTime": "2026-01-12T14:00:00-04:00",
                "endTime": "2026-01-12T15:00:00-04:00",
                "unreachable": true
              }
            ],
            "unreachable": true,
            "metrics": {
              // "endLocationArrivalTime" not present for unreachable itineraries
            }
          }
        ]
      }
    ]
  }
}

From 0.58.0 to 0.59.0

Naming changes in the input API

To improve clarity and consistency in the input API, we have updated the way capacities and demands are defined for drivers and jobs. The following changes have been made:

Driver capacity

  • The field previously named capacityDefinitions in a driver shift has been renamed capacities.

  • The capacityName field in a capacity definition has been renamed type.

  • The providedCapacity field in a capacity definition has been renamed quantity.

Before:

{
  "capacityDefinitions": [
    {
      "capacityName": "Passenger",
      "providedCapacity": 5
    }
  ]
}

After:

{
  "capacities": [
    {
      "type": "Passenger",
      "quantity": 5
    }
  ]
}

Stop demands

  • The field previously named capacityRequirements in a stop has been renamed demands.

  • The capacityName field in a capacity requirement has been renamed type.

  • The requiredCapacity field in a capacity requirement has been renamed pickup.

  • The freedCapacity field in a capacity requirement has been renamed deliver.

Before:

{
  "capacityRequirements": [
    {
        "capacityName": "Passenger",
        "requiredCapacity": 5,
        "freedCapacity": 0
    }
  ]
}

After:

{
  "demands": [
    {
        "type": "Passenger",
        "pickup": 5,
        "deliver": 0
    }
  ]
}
  • © 2026 Timefold BV
  • Timefold.ai
  • Documentation
  • Changelog
  • Send feedback
  • Privacy
  • Legal
    • Light mode
    • Dark mode
    • System default