-> Optimizing Routes

We support the following modes of shipments:

  • Deliveries only
  • Pickups only
  • Deliveries before pickups
  • Mixed deliveries and pickups
  • All the above variants in a depot reload mode, i.e. a vehicle can have multiple routes with reloads at the depot
  • Directs: The delivery is picked up at a stop not at the depot

Routes optimization considers the following parameters:

  • The fix costs per vehicles as well as the variable costs per km
  • The time windows of the shipments
  • The expected length of stops calculated from fixed time per vehicle and variable times per shipment
  • The velocity profiles of the vehicles

Calculating the optimal route for deliveries with time windows is accessible via this link.

We also consider:

  • Load capacity of the vehicles (net load, pallet places, load meters, ADR)
  • Maximal duration of the route including breaks
  • Available vehicles (vehicles types) at a stop

Start optimizing

Now that we have addresses, vehicles and shipments, we can start optimizing routes.

import requests
import json

auth_header = {"Authorization": 'JWT ' + token}
api_url = "https://<your company name>.prod.smartlane.io/api/calcroute/optimized/timewindow"

payload = {
  "deliverydata": [
    {
      "custom_id": "id_1",
      "customercompany": "customer_1",
      "street": "Kraepelinstraße 8",
      "postalcode": "80804",
      "city": "München",
      "load": 5000,
      "load_2": 10,
      "load_3": 2000,
      "pdt_from": "2025-04-03T08:00:00+02:00",
      "pdt_to": "2025-04-03T16:00:00+02:00",
      "shipment_priority": "3",
      "shipment_type": "pickup"
    },
    {
      "custom_id": "id_2",
      "customercompany": "customer_2",
      "street": "Am Oberwiesenfeld 9",
      "postalcode": "80809",
      "city": "München",
      "load": 6000,
      "load_2": 9,
      "load_3": 0,
      "pdt_from": "2025-04-03T08:00:00+02:00",
      "pdt_to": "2025-04-03T16:00:00+02:00",
      "shipment_priority": "5",
      "shipment_type": "delivery"
    }
  ],
  "vehicles": [
    {
      "custom_id": "id_3",
      "name": "Vehicle_3",
      "vehicle_class": "truck",
      "capacity_1": 15000,
      "capacity_2": 30,
      "capacity_3": 99999,
      "daily_rate": 250,
      "km_rate": 0.35,
      "traveltime_factor": 1.4,
      "departure_time_from": "2025-04-03T06:00:00+02:00",
      "departure_time_to": "2025-04-03T07:00:00+02:00",
      "return_time_to": "2025-04-03T16:00:00+02:00",
      "max_tour_duration": 540,
      "depot_location": {
        "street": "Elsenheimerstraße",
        "housenumber": "45",
        "postalcode": "80687",
        "city": "München"
      }
    }
  ]
} 
response = requests.post(api_url, headers=auth_header, json=payload)
print (response.text)
print (response.status_code)

You should get a response that looks something like this:

{
	"status": "started",
	"message": "routing process is started",
	"process_id": "3b0ca0ae-17ea-11ed-9d00-ba8a33c5b309"
}

If your deliveries cannot be planned as a single route, it's automatically split up to multiple routes, provided you have enough vehicles.

Asynchronous routing

We recommend to set the async parameter to true.
Why is that so? The calculation of routes for real world scenarios with hundreds of deliveries can take some time. First of all we need to gather a lot of geo-information from external sources. A lot of processing power is needed for the optimization process. Therefore it runs as a background process. In order to get the results you start polling our API with the process ID until you get the result.

Handle possible 5xx http status codes

We highly recommend to implement a retry mechanism for all API calls and especially for

to avoid problems in case of a process returns a 5xx http status code at the first attempt.
This might happen in very rare cases. These errors can occur in the data transfer protocols or network infrastructure in the web. In most of the cases this can be resolved with a simple retry mechanism.