Quick Start

With the Route Optimization service you can schedule and optimize the routes of your fleet. For this we provide two APIs:

  • The Plans API
    Use this API to transfer your locations, fleet and transports to the service. As a result you get a plan ID.

  • The Operations API
    Use this API to start the optimization process for the previously generated plan in a separate job.

The APIs are separated because the optimization can be a long lasting process, so your work is not blocked by the optimization.

The whole process of route optimization can be summarized by the following steps:

  • Step 1: Create a plan.

  • Step 2: Start the optimization process for that plan.

  • Step 3: Check the progress of the optimization process.

  • Step 4: Get the optimized plan.

Create a plan

Create a plan containing the fleet, all relevant transports and its associated locations. Use the following endpoint via POST to create and persist a plan.

https://api.dev.myptv.com/routeoptimization/v1/plans

The following simple plan with two vehicles and two transports is inserted into the request body in JSON representation:


{
  "locations": [
    {
      "id": "Depot",
      "type": "DEPOT",
      "latitude": 49.60804,
      "longitude": 6.113033,
      "openingIntervals": [
        {
          "start": "2020-12-06T08:00:00+00:00",
          "end": "2020-12-06T18:00:00+00:00"
        }
      ]
    },
    {
      "id": "Customer",
      "type": "CUSTOMER",
      "latitude": 49.609597,
      "longitude": 6.097412,
      "openingIntervals": [
        {
          "start": "2020-12-06T10:00:00+00:00",
          "end": "2020-12-06T10:00:10+00:00"
        }
      ]
    }
  ],
  "vehicles": [
    {
      "id": "Vehicle1",
      "profile": "EUR_TRUCK_40T",
      "capacities": [
        500
      ],
      "startLocationId": "Depot",
      "endLocationId": "Depot"
    },
    {
      "id": "Vehicle2",
      "profile": "EUR_TRUCK_40T",
      "capacities": [
        500
      ],
      "startLocationId": "Depot",
      "endLocationId": "Depot"
    }
  ],
  "transports": [
    {
      "id": "Transport1",
      "quantities": [
        100
      ],
      "pickupLocationId": "Customer",
      "pickupServiceTime": 60,
      "deliveryLocationId": "Depot",
      "deliveryServiceTime": 60
    },
    {
      "id": "Transport2",
      "quantities": [
        100
      ],
      "pickupLocationId": "Depot",
      "pickupServiceTime": 60,
      "deliveryLocationId": "Customer",
      "deliveryServiceTime": 60
    }
  ],
  "planningHorizon": {
    "start": "2020-12-06T00:00:00+00:00",
    "end": "2020-12-07T00:00:00+00:00"
  }
}

You can test the simple plan by choosing one of the following options.

cURL:

curl --location --request POST "https://api.dev.myptv.com/routeoptimization/v1/plans" --header "Content-Type: application/json" --header "ApiKey: YOUR_API_KEY" --data-raw "{ \"locations\": [ { \"id\": \"Depot\", \"type\": \"DEPOT\", \"latitude\": 49.60804, \"longitude\": 6.113033, \"openingIntervals\": [ { \"start\": \"2020-12-06T08:00:00+00:00\", \"end\": \"2020-12-06T18:00:00+00:00\" } ] }, { \"id\": \"Customer\", \"type\": \"CUSTOMER\", \"latitude\": 49.609597, \"longitude\": 6.097412, \"openingIntervals\": [ { \"start\": \"2020-12-06T10:00:00+00:00\", \"end\": \"2020-12-06T10:00:10+00:00\" } ] } ], \"vehicles\": [ { \"id\": \"Vehicle1\", \"profile\": \"EUR_TRUCK_40T\", \"capacities\": [ 500 ], \"startLocationId\": \"Depot\", \"endLocationId\": \"Depot\" }, { \"id\": \"Vehicle2\", \"profile\": \"EUR_TRUCK_40T\", \"capacities\": [ 500 ], \"startLocationId\": \"Depot\", \"endLocationId\": \"Depot\" } ], \"transports\": [ { \"id\": \"Transport1\", \"quantities\": [ 100 ], \"pickupLocationId\": \"Customer\", \"pickupServiceTime\": 60, \"deliveryLocationId\": \"Depot\", \"deliveryServiceTime\": 60 }, { \"id\": \"Transport2\", \"quantities\": [ 100 ], \"pickupLocationId\": \"Depot\", \"pickupServiceTime\": 60, \"deliveryLocationId\": \"Customer\", \"deliveryServiceTime\": 60 } ]}"

PowerShell:

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("ApiKey", "YOUR_API_KEY")
$headers.Add("Content-Type", "application/json")

$body='{ "locations": [ { "id": "Depot", "type": "DEPOT", "latitude": 49.60804, "longitude": 6.113033, "openingIntervals": [ { "start": "2020-12-06T08:00:00+00:00", "end": "2020-12-06T18:00:00+00:00" } ] }, { "id": "Customer", "type": "CUSTOMER", "latitude": 49.609597, "longitude": 6.097412, "openingIntervals": [ { "start": "2020-12-06T10:00:00+00:00", "end": "2020-12-06T10:00:10+00:00" } ] } ], "vehicles": [ { "id": "Vehicle1", "profile": "EUR_TRUCK_40T", "capacities": [ 500 ], "startLocationId": "Depot", "endLocationId": "Depot" }, { "id": "Vehicle2", "profile": "EUR_TRUCK_40T", "capacities": [ 500 ], "startLocationId": "Depot", "endLocationId": "Depot" } ], "transports": [ { "id": "Transport1", "quantities": [ 100 ], "pickupLocationId": "Customer", "pickupServiceTime": 60, "deliveryLocationId": "Depot", "deliveryServiceTime": 60 }, { "id": "Transport2", "quantities": [ 100 ], "pickupLocationId": "Depot", "pickupServiceTime": 60, "deliveryLocationId": "Customer", "deliveryServiceTime": 60 } ]}'

try
{
    $response = Invoke-RestMethod 'https://api.dev.myptv.com/routeoptimization/v1/plans' -Method 'POST' -Headers $headers -Body $body
    $response | ConvertTo-Json -Depth 10
}
catch
{
    $streamReader = [System.IO.StreamReader]::new($_.Exception.Response.GetResponseStream())
    $streamReader.ReadToEnd() | ConvertFrom-Json
    $streamReader.Close()
}

The result is an updated plan enriched by a generated unique ID.


{
  "id": "3dd870e6-be5e-40e7-8de3-eec3e06db8e0",
  "locations": 
  ...
}

This ID is used in the following steps in the URL path, indicated as {id}.

Start optimization

Now you can use the following endpoint via POST. This will start the optimization process for the previously generated plan.

https://api.dev.myptv.com/routeoptimization/v1/plans/{id}/operation/optimization

In case of success the request returns status code 202 (accepted). You can test the optimization process by choosing one of the following options.

cURL:

curl --location --request POST "https://api.dev.myptv.com/routeoptimization/v1/plans/{id}/operation/optimization" --header "Content-Type: application/json" --header "ApiKey: YOUR_API_KEY" --data-raw ""

PowerShell:

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("ApiKey", "YOUR_API_KEY")
$headers.Add("Content-Type", "application/json")

Invoke-RestMethod 'https://api.dev.myptv.com/routeoptimization/v1/plans/{id}/operation/optimization' -Method 'POST' -Headers $headers

Check progress

To check if the optimization process is already finished, the following endpoint is used via GET.

https://api.dev.myptv.com/routeoptimization/v1/plans/{id}/operation

The response contains a description of the current status of the optimization process:


{
  "name": "Optimization",
  "status": "SUCCEEDED",
  "startTime": "2020-11-20T11:19:28.5521174+00:00",
  "elapsedTime": 1
}

After the optimization is succeeded the results are stored in the associated plan.

Hint: You should check for the completion of the operation from time to time. The frequency depends on the size of the plan and the expected duration of the optimization.

You can test the process by choosing one of the following options.

cURL:

curl --location --request GET "https://api.dev.myptv.com/routeoptimization/v1/plans/{id}/operation" --header "ApiKey: YOUR_API_KEY"

PowerShell:

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("ApiKey", "YOUR_API_KEY")

$response = Invoke-RestMethod 'https://api.dev.myptv.com/routeoptimization/v1/plans/{id}/operation' -Method 'GET' -Headers $headers
$response | ConvertTo-Json -Depth 10	

Get plan

After successful completion of the optimization process, the plan is updated internally and can be recalled via GET from the following endpoint.

https://api.dev.myptv.com/routeoptimization/v1/plans/{id}

The response contains an updated version of the plan. For each vehicle a list of its routes is added. A route contains the sequence of stops and a report. The following JSON representation illustrates the relevant part of a plan which extends the original version:


{
  "id": "3dd870e6-be5e-40e7-8de3-eec3e06db8e0",
  ...
  "routes": [
    {
      "vehicleId": "Vehicle1",
      "stops": [
        {
          "locationId": "Depot",
          "tripId": "d12619c5-15fc-4a2a-a96f-3064b90b3a92",
          "deliveryIds": [],
          "pickupIds": [
            "Transport2"
          ],
          "reportForWayToStop": {
            "distance": 0,
            "drivingTime": 0,
            "waitingTime": 0,
            "breakTime": 0,
            "restTime": 0
          },
          "reportForStop": {
            "arrivalTime": "2020-12-06T09:54:05+00:00",
            "departureTime": "2020-12-06T09:55:05+00:00",
            "serviceTime": 60,
            "waitingTime": 0,
            "breakTime": 0,
            "restTime": 0,
            "quantities": [
              100
            ]
          },
          "eventsOnWayToStop": [],
          "eventsAtStop": [
            {
              "type": "ROUTE_START",
              "startTime": "2020-12-06T09:54:05+00:00",
              "duration": 0
            },
            {
              "type": "TRIP_START",
              "startTime": "2020-12-06T09:54:05+00:00",
              "duration": 0
            },
            {
              "type": "SERVICE",
              "startTime": "2020-12-06T09:54:05+00:00",
              "duration": 60,
              "transportId": "Transport2"
            }
          ],
          "violationsOnWayToStop": [],
          "violationsAtStop": []
        },
        {
          "locationId": "Customer",
          "tripId": "d12619c5-15fc-4a2a-a96f-3064b90b3a92",
          "deliveryIds": [
            "Transport2"
          ],
          "pickupIds": [
            "Transport1"
          ],
          "reportForWayToStop": {
            "distance": 1364,
            "drivingTime": 295,
            "waitingTime": 0,
            "breakTime": 0,
            "restTime": 0
          },
          "reportForStop": {
            "arrivalTime": "2020-12-06T10:00:00+00:00",
            "departureTime": "2020-12-06T10:02:00+00:00",
            "serviceTime": 120,
            "waitingTime": 0,
            "breakTime": 0,
            "restTime": 0,
            "quantities": [
              100
            ]
          },
          "eventsOnWayToStop": [
            {
              "type": "DRIVING",
              "startTime": "2020-12-06T09:55:05+00:00",
              "duration": 295
            }
          ],
          "eventsAtStop": [
            {
              "type": "SERVICE",
              "startTime": "2020-12-06T10:00:00+00:00",
              "duration": 60,
              "transportId": "Transport2"
            },
            {
              "type": "SERVICE",
              "startTime": "2020-12-06T10:01:00+00:00",
              "duration": 60,
              "transportId": "Transport1"
            }
          ],
          "violationsOnWayToStop": [],
          "violationsAtStop": []
        },
        {
          "locationId": "Depot",
          "tripId": "d12619c5-15fc-4a2a-a96f-3064b90b3a92",
          "deliveryIds": [
            "Transport1"
          ],
          "pickupIds": [],
          "reportForWayToStop": {
            "distance": 1364,
            "drivingTime": 295,
            "waitingTime": 0,
            "breakTime": 0,
            "restTime": 0
          },
          "reportForStop": {
            "arrivalTime": "2020-12-06T10:06:55+00:00",
            "departureTime": "2020-12-06T10:07:55+00:00",
            "serviceTime": 60,
            "waitingTime": 0,
            "breakTime": 0,
            "restTime": 0
          },
          "eventsOnWayToStop": [
            {
              "type": "DRIVING",
              "startTime": "2020-12-06T10:02:00+00:00",
              "duration": 295
            }
          ],
          "eventsAtStop": [
            {
              "type": "SERVICE",
              "startTime": "2020-12-06T10:06:55+00:00",
              "duration": 60,
              "transportId": "Transport1"
            },
            {
              "type": "TRIP_END",
              "startTime": "2020-12-06T10:07:55+00:00",
              "duration": 0
            },
            {
              "type": "ROUTE_END",
              "startTime": "2020-12-06T10:07:55+00:00",
              "duration": 0
            }
          ],
          "violationsOnWayToStop": [],
          "violationsAtStop": []
        }
      ],
      "report": {
        "startTime": "2020-12-06T09:54:05+00:00",
        "endTime": "2020-12-06T10:07:55+00:00",
        "travelTime": 830,
        "distance": 2728,
        "drivingTime": 590,
        "serviceTime": 240,
        "waitingTime": 0,
        "breakTime": 0,
        "restTime": 0
      }
    }
  ],
  ...
  "unplannedVehicleIds": [
    "Vehicle2"
  ],
  "unplannedTransportIds": []
}

You can retrieve the optimization results by choosing one of the following options.

cURL:

curl --location --request GET https://api.dev.myptv.com/routeoptimization/v1/plans/{id} --header "ApiKey: YOUR_API_KEY"

PowerShell:

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("ApiKey", "YOUR_API_KEY")

$response = Invoke-RestMethod 'https://api.dev.myptv.com/routeoptimization/v1/plans/{id}' -Method 'GET' -Headers $headers
$response | ConvertTo-Json -Depth 10