Use the API Client Library for Java to send requests

This quickstart shows how to solve the VRP example by sending an RPC request to the Cloud Fleet Routing service using the API Client Library for Java. This example uses the Google Geo Distance Matrix.

Before you begin

Follow these instructions to set up your Java development environment.

Download the Cloud Fleet Routing API Client Library

To send requests to the API by using the API Client Library for Java, you need to download it from the Cloud Fleet Routing's Cloud Storage bucket. To do so, enter the following command:

gcloud storage cp gs://api-client-staging/cloudoptimization-java-v1-20211110.tar.gz SAVE_TO_LOCATION

Install the Cloud Fleet Routing API Client Library

After you have downloaded the API Client Library tarball, install it with the following command:

tar -xzpf cloudoptimization-java-v1-20211110.tar.gz -C /path/to/library
cd /path/to/library
./gradlew clean install

Java code to send a synchronous request

The following code sends the protobuf request in the file request.textproto to the Cloud Fleet Routing synchronous API (optimizeTours).

Java Code
package com.google.cloud;

import com.google.cloud.optimization.v1.FleetRoutingClient;
import com.google.cloud.optimization.v1.OptimizeToursRequest;
import com.google.cloud.optimization.v1.OptimizeToursResponse;
import com.google.protobuf.Duration;
import com.google.protobuf.TextFormat;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;


/**
 * This is an example to send a request to Cloud Fleet Routing synchronous API via Java API Client.
 */
public class App {
  private static int TIMEOUT_SECONDS = 100;
  private static final String PROJECT_PARENT = "projects/{YOUR_GCP_PROJECT_ID}";
  private static final String MODEL_PATH = "request.textproto";

  public static void main(String[] args) throws Exception {
    InputStream modelInputstream = new FileInputStream(MODEL_PATH);
    Reader modelInputStreamReader = new InputStreamReader(modelInputstream);
    OptimizeToursRequest.Builder requestBuilder =
        OptimizeToursRequest.newBuilder()
            .setTimeout(Duration.newBuilder().setSeconds(TIMEOUT_SECONDS).build())
            .setParent(PROJECT_PARENT);
    TextFormat.getParser().merge(modelInputStreamReader, requestBuilder);
    FleetRoutingClient fleetRoutingClient = FleetRoutingClient.create();
    OptimizeToursResponse response = fleetRoutingClient.optimizeTours(requestBuilder.build());
    System.out.println(response.toString());
  }
}
request.textproto
# proto-file: google3/google/cloud/optimization/v1/fleet_routing.proto
# proto-message: OptimizeToursRequest
model {
  shipments {
    pickups {
      arrival_location { latitude: 48.874507 longitude: 2.30361 }
      time_windows {
        start_time { seconds: 1000 }
        end_time { seconds: 2000 }
      }
      duration { seconds: 150 }
    }
    deliveries {
      arrival_location { latitude: 48.880942 longitude: 2.323866 }
      time_windows {
        start_time { seconds: 3000 }
        end_time { seconds: 4000 }
      }
      duration: { seconds: 250 }
    }
    load_demands {
      key: "weight"
      value: { amount: 10 }
    }
  }
  shipments {
    pickups {
      arrival_location { latitude: 48.880943 longitude: 2.323867 }
      time_windows {
        start_time { seconds: 1001 }
        end_time { seconds: 2001 }
      }
      duration { seconds: 151 }
    }
    deliveries {
      arrival_location { latitude: 48.880940 longitude: 2.323844 }
      time_windows {
        start_time { seconds: 3001 }
        end_time { seconds: 4001 }
      }
      duration { seconds: 251 }
    }
    load_demands {
      key: "weight"
      value: { amount: 20 }
    }
  }
  vehicles {
    start_location { latitude: 48.863102 longitude: 2.341204 }
    end_location { latitude: 48.863110 longitude: 2.341205 }
    load_limits {
      key: "weight"
      value: { max_load: 50 }
    }
  }
  vehicles {
    start_location { latitude: 48.863112 longitude: 2.341214 }
    end_location { latitude: 48.863120 longitude: 2.341215 }
    load_limits {
      key: "weight"
      value: { max_load: 60 }
    }
  }
}

Send a synchronous request with a long timeout

When a request might take a longer time to solve, we recommend using the asynchronous API. However, if you prefer, you can still send a synchronous request with a long timeout.

If you run the client on a Compute Engine virtual machine (VM), the firewall will end connections that are idle for a long time. The keep-alive setting enforces the client to ping the API server to keep the connection alive. We recommend a five-minutes keep-alive setting, but you can adjust this value based on your use case. As an example, the following code sends the same protobuf request in the request.textproto file to the Cloud Fleet Routing Synchronous API while setting up the checks to keep the connection alive.

Java Code
package com.google.cloud;

import com.google.cloud.optimization.v1.FleetRoutingSettings;
import com.google.cloud.optimization.v1.FleetRoutingClient;
import com.google.cloud.optimization.v1.OptimizeToursRequest;
import com.google.cloud.optimization.v1.OptimizeToursResponse;
import com.google.protobuf.Duration;
import com.google.protobuf.TextFormat;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

/**
 * This is an example to send a request to Cloud Fleet Routing synchronous API via Java API Client.
 */
public class App {
  private static int TIMEOUT_SECONDS = 100;
  private static final String PROJECT_PARENT = "projects/{YOUR_GCP_PROJECT_ID}";
  private static final String MODEL_PATH = "request.textproto";

  public static void main(String[] args) throws Exception {
    InputStream modelInputstream = new FileInputStream(MODEL_PATH);
    Reader modelInputStreamReader = new InputStreamReader(modelInputstream);
    OptimizeToursRequest.Builder requestBuilder =
        OptimizeToursRequest.newBuilder()
            .setTimeout(Duration.newBuilder().setSeconds(TIMEOUT_SECONDS).build())
            .setParent(PROJECT_PARENT);
    TextFormat.getParser().merge(modelInputStreamReader, requestBuilder);
    // Checks the gRPC connection every 5 mins and keeps it alive.
    FleetRoutingClient fleetRoutingClientClient = FleetRoutingClient.create(
                FleetRoutingSettings
                .newBuilder()
                        .setTransportChannelProvider(
                                FleetRoutingSettings.
                                        defaultGrpcTransportProviderBuilder()
                                        .setKeepAliveTime(
                                                org.threeten.bp.Duration.ofSeconds(300)).build()).build());
        OptimizeToursResponse response = fleetRoutingClientClient.optimizeTours(requestBuilder.build());
    System.out.println(response.toString());
  }
}
request.textproto
# proto-file: google3/google/cloud/optimization/v1/fleet_routing.proto
# proto-message: OptimizeToursRequest
model {
  shipments {
    pickups {
      arrival_location { latitude: 48.874507 longitude: 2.30361 }
      time_windows {
        start_time { seconds: 1000 }
        end_time { seconds: 2000 }
      }
      duration { seconds: 150 }
    }
    deliveries {
      arrival_location { latitude: 48.880942 longitude: 2.323866 }
      time_windows {
        start_time { seconds: 3000 }
        end_time { seconds: 4000 }
      }
      duration: { seconds: 250 }
    }
    load_demands {
      key: "weight"
      value: { amount: 10 }
    }
  }
  shipments {
    pickups {
      arrival_location { latitude: 48.880943 longitude: 2.323867 }
      time_windows {
        start_time { seconds: 1001 }
        end_time { seconds: 2001 }
      }
      duration { seconds: 151 }
    }
    deliveries {
      arrival_location { latitude: 48.880940 longitude: 2.323844 }
      time_windows {
        start_time { seconds: 3001 }
        end_time { seconds: 4001 }
      }
      duration { seconds: 251 }
    }
    load_demands {
      key: "weight"
      value: { amount: 20 }
    }
  }
  vehicles {
    start_location { latitude: 48.863102 longitude: 2.341204 }
    end_location { latitude: 48.863110 longitude: 2.341205 }
    load_limits {
      key: "weight"
      value: { max_load: 50 }
    }
  }
  vehicles {
    start_location { latitude: 48.863112 longitude: 2.341214 }
    end_location { latitude: 48.863120 longitude: 2.341215 }
    load_limits {
      key: "weight"
      value: { max_load: 60 }
    }
  }
}

Run the code

To run the Java Code:

  1. Create a Maven project by running the following command:

  2.   mvn archetype:generate -DgroupId=com.google.cloud -DartifactId=fleet-routing -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false
      
  3. Add the following dependency in POM.xml under your fleet-routing directory:
  4. &ltdependency&gt
        &ltgroupId&gtcom.google.cloud&lt/groupId&gt
        &ltartifactId&gtgapic-google-cloud-optimization-v1-java&lt/artifactId&gt
        &ltversion&gt0.0.0-SNAPSHOT&lt/version&gt
    &lt/dependency&gt
      
  5. Copy the preceding Java code into a file named fleet-routing/src/main/java/com/google/cloud/App.java, and save the textproto file as request.textproto in your fleet-routing directory.
  6. Move the service account key file you downloaded when you created a service account to your fleet-routing directory, and rename the key file to my_keyfile.json.
  7. In the command line, run the following command: export GOOGLE_APPLICATION_CREDENTIALS="[PATH to my_keyfile.json]".
  8. Replace the value of PROJECT_PARENT with your Google Cloud project.
  9. Replace the value of MODEL_PATH with the path of your request.textproto file.
  10. At the command line, navigate to your fleet-routing directory and enter the following commands:
  11. mvn package
    mvn exec:java -D exec.mainClass=com.google.cloud.App
      

Response

The following is the response to the request.

routes {
  vehicle_start_time {
    seconds: 35
  }
  vehicle_end_time {
    seconds: 4302
  }
  visits {
    is_pickup: true
    start_time {
      seconds: 1000
    }
    demands {
      type: "weight"
      value: 10
    }
    detour {
    }
    arrival_loads {
      type: "weight"
    }
    load_demands {
      key: "weight"
      value {
        amount: 10
      }
    }
  }
  visits {
    shipment_index: 1
    is_pickup: true
    start_time {
      seconds: 1660
    }
    demands {
      type: "weight"
      value: 20
    }
    detour {
      seconds: 756
    }
    arrival_loads {
      type: "weight"
      value: 10
    }
    load_demands {
      key: "weight"
      value {
        amount: 20
      }
    }
  }
  visits {
    start_time {
      seconds: 3000
    }
    demands {
      type: "weight"
      value: -10
    }
    detour {
      seconds: 1340
    }
    arrival_loads {
      type: "weight"
      value: 30
    }
    load_demands {
      key: "weight"
      value {
        amount: -10
      }
    }
  }
  visits {
    shipment_index: 1
    start_time {
      seconds: 3250
    }
    demands {
      type: "weight"
      value: -20
    }
    detour {
      seconds: 1439
    }
    arrival_loads {
      type: "weight"
      value: 20
    }
    load_demands {
      key: "weight"
      value {
        amount: -20
      }
    }
  }
  transitions {
    travel_duration {
      seconds: 965
    }
    travel_distance_meters: 4244.0
    total_duration {
      seconds: 965
    }
    start_time {
      seconds: 35
    }
    vehicle_loads {
      key: "weight"
      value {
      }
    }
  }
  transitions {
    travel_duration {
      seconds: 510
    }
    travel_distance_meters: 2479.0
    total_duration {
      seconds: 510
    }
    start_time {
      seconds: 1150
    }
    vehicle_loads {
      key: "weight"
      value {
        amount: 10
      }
    }
  }
  transitions {
    travel_duration {
    }
    wait_duration {
      seconds: 1189
    }
    total_duration {
      seconds: 1189
    }
    start_time {
      seconds: 1811
    }
    vehicle_loads {
      key: "weight"
      value {
        amount: 30
      }
    }
  }
  transitions {
    travel_duration {
    }
    total_duration {
    }
    start_time {
      seconds: 3250
    }
    vehicle_loads {
      key: "weight"
      value {
        amount: 20
      }
    }
  }
  transitions {
    travel_duration {
      seconds: 801
    }
    travel_distance_meters: 3111.0
    total_duration {
      seconds: 801
    }
    start_time {
      seconds: 3501
    }
    vehicle_loads {
      key: "weight"
      value {
      }
    }
  }
  metrics {
    performed_shipment_count: 2
    travel_duration {
      seconds: 2276
    }
    wait_duration {
      seconds: 1189
    }
    delay_duration {
    }
    break_duration {
    }
    visit_duration {
      seconds: 802
    }
    total_duration {
      seconds: 4267
    }
    travel_distance_meters: 9834.0
    max_loads {
      key: "weight"
      value {
        amount: 30
      }
    }
  }
  end_loads {
    type: "weight"
  }
  travel_steps {
    duration {
      seconds: 965
    }
    distance_meters: 4244.0
  }
  travel_steps {
    duration {
      seconds: 510
    }
    distance_meters: 2479.0
  }
  travel_steps {
    duration {
    }
  }
  travel_steps {
    duration {
    }
  }
  travel_steps {
    duration {
      seconds: 801
    }
    distance_meters: 3111.0
  }
  vehicle_detour {
    seconds: 4267
  }
}
routes {
  vehicle_index: 1
}
metrics {
  aggregated_route_metrics {
    performed_shipment_count: 2
    travel_duration {
      seconds: 2276
    }
    wait_duration {
      seconds: 1189
    }
    delay_duration {
    }
    break_duration {
    }
    visit_duration {
      seconds: 802
    }
    total_duration {
      seconds: 4267
    }
    travel_distance_meters: 9834.0
    max_loads {
      key: "weight"
      value {
        amount: 30
      }
    }
  }
  used_vehicle_count: 1
  earliest_vehicle_start_time {
    seconds: 35
  }
  latest_vehicle_end_time {
    seconds: 4302
  }
}

For a description of the response, see Response to the request in the VRP example page.

Java code to send an asynchronous request

The following code sends the protobuf request in the file request.textproto to the Cloud Fleet Routing Asynchronous API.

Java Code
package com.google.cloud;

import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.optimization.v1.AsyncModelMetadata;
import com.google.cloud.optimization.v1.BatchOptimizeToursRequest;
import com.google.cloud.optimization.v1.BatchOptimizeToursResponse;
import com.google.cloud.optimization.v1.FleetRoutingClient;
import com.google.protobuf.TextFormat;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

/**
 * This is an example to send a request to Cloud Fleet Routing asynchronous API via Java API Client.
 */
public class App {
  private static final String PROJECT_PARENT = "projects/{YOUR_GCP_PROJECT_ID}";
  private static final String REQUEST_PATH = "request.textproto";

  public static void main(String[] args) throws Exception {
    InputStream modelInputstream = new FileInputStream(REQUEST_PATH);
    Reader modelInputStreamReader = new InputStreamReader(modelInputstream);
    BatchOptimizeToursRequest.Builder requestBuilder =
        BatchOptimizeToursRequest.newBuilder().setParent(PROJECT_PARENT);
    TextFormat.getParser().merge(modelInputStreamReader, requestBuilder);
    FleetRoutingClient fleetRoutingClient = FleetRoutingClient.create();
    OperationFuture<BatchOptimizeToursResponse, AsyncModelMetadata> response =
        fleetRoutingClient.batchOptimizeToursAsync(requestBuilder.build());

    // Block to wait for the job to finish.
    response.getPollingFuture().get();
    if (response.getMetadata().get().getState() == AsyncModelMetadata.State.SUCCEEDED) {
       // Code to do your stuff
    } else {
       System.out.println("Job failed with message:" + response.getPollingFuture().get().getErrorMessage());
    }
  }
}
request.textproto
# proto-file: google3/google/cloud/optimization/v1/fleet_routing.proto
# proto-message: BatchOptimizeToursRequest
model_configs {
  input_config {
    gcs_source: {
      uri: "${REQUEST_MODEL_GCS_PATH}"
    }
    data_format: JSON
  }
  output_config: {
    gcs_destination {
      uri: "${MODEL_SOLUTION_GCS_PATH}"
    }
    data_format: JSON
  }
}

model_configs {
  input_config {
    gcs_source: {
      uri: "${REQUEST_MODEL_GCS_PATH}"
    }
    data_format: JSON
  }
  output_config: {
    gcs_destination {
      uri: "${MODEL_SOLUTION_GCS_PATH}"
    }
    data_format: JSON
  }
}

model_configs {
  input_config {
    gcs_source: {
      uri: "${REQUEST_MODEL_GCS_PATH}"
    }
    data_format: JSON
  }
  output_config: {
    gcs_destination {
      uri: "${MODEL_SOLUTION_GCS_PATH}"
    }
    data_format: JSON
  }
}
request_model.json
{
   "parent":"${YOUR_GCP_PROJECT_ID}",
   "allowLargeDeadlineDespiteInterruptionRisk":true,
   "model":{
      "shipments":[
         {
            "deliveries":[
               {
                  "arrivalLocation":{
                     "latitude":48.880941999999997,
                     "longitude":2.3238660000000002
                  },
                  "duration":"250s",
                  "timeWindows":[
                     {
                        "endTime":"1970-01-01T01:06:40Z",
                        "startTime":"1970-01-01T00:50:00Z"
                     }
                  ]
               }
            ],
            "loadDemands": {
              "weight": {
                "amount": "10"
              }
            },
            "pickups":[
               {
                  "arrivalLocation":{
                     "latitude":48.874507000000001,
                     "longitude":2.3036099999999999
                  },
                  "duration":"150s",
                  "timeWindows":[
                     {
                        "endTime":"1970-01-01T00:33:20Z",
                        "startTime":"1970-01-01T00:16:40Z"
                     }
                  ]
               }
            ]
         },
         {
            "deliveries":[
               {
                  "arrivalLocation":{
                     "latitude":48.880940000000002,
                     "longitude":2.3238439999999998
                  },
                  "duration":"251s",
                  "timeWindows":[
                     {
                        "endTime":"1970-01-01T01:06:41Z",
                        "startTime":"1970-01-01T00:50:01Z"
                     }
                  ]
               }
            ],
            "loadDemands": {
              "weight": {
                "amount": "20"
              }
            },
            "pickups":[
               {
                  "arrivalLocation":{
                     "latitude":48.880943000000002,
                     "longitude":2.3238669999999999
                  },
                  "duration":"151s",
                  "timeWindows":[
                     {
                        "endTime":"1970-01-01T00:33:21Z",
                        "startTime":"1970-01-01T00:16:41Z"
                     }
                  ]
               }
            ]
         }
      ],
      "vehicles":[
         {
            "loadLimits": {
               "weight": {
                 "maxLoad": 50
               }
            },
            "endLocation":{
               "latitude":48.863109999999999,
               "longitude":2.341205
            },
            "startLocation":{
               "latitude":48.863101999999998,
               "longitude":2.3412039999999998
            }
         },
         {
            "loadLimits": {
               "weight": {
                 "maxLoad": 60
               }
            },
            "endLocation":{
               "latitude":48.863120000000002,
               "longitude":2.341215
            },
            "startLocation":{
               "latitude":48.863112000000001,
               "longitude":2.3412139999999999
            }
         }
      ]
   }
}

Run the code

To run the Java code:

  1. Create a Maven project by running the following command:

  2. mvn archetype:generate -DgroupId=com.google.cloud -DartifactId=fleet-routing -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false
      
  3. Add the following dependency in POM.xml under fleet-routing/:
  4. &ltdependency&gt
        &ltgroupId&gtcom.google.cloud&lt/groupId&gt
        &ltartifactId&gtgapic-google-cloud-optimization-v1-java&lt/artifactId&gt
        &ltversion&gt0.0.0-SNAPSHOT&lt/version&gt
    &lt/dependency&gt
      
  5. Copy the preceding Java code into a file named fleet-routing/src/main/java/com/google/cloud/App.java, and save the textproto file as request.textproto in your fleet-routing directory.
  6. Move the service account key file you downloaded when you created a service account to your fleet-routing directory, and rename your key file to my_keyfile.json.
  7. Create three files on your Cloud Storage bucket with the content of the request_model.json. In this file, replace the ${YOUR_GCP_PROJECT_ID} with your Google Cloud project ID and replace the ${YOUR_GCP_API_KEY} with your Google Cloud project API key generated in the "Before you begin" section.
  8. In the request.textproto file, replace ${REQUEST_MODEL_GCS_PATH} with the paths of the files you just created on your Cloud Storage bucket. Replace the ${MODEL_SOLUTION_GCS_PATH} with the three different paths for the model solutions.
  9. In the command line, run the following command: export GOOGLE_APPLICATION_CREDENTIALS="[PATH to my_keyfile.json]".
  10. Replace the value of PROJECT_PARENT with your Google Cloud project ID.
  11. Replace the value of MODEL_PATH with the path of your request.textproto file.
  12. At the command line, navigate to your fleet-routing directory and enter the following commands:
  13. mvn package
    mvn exec:java -D exec.mainClass=com.google.cloud.App
      

Response

After a couple of seconds, check your files in ${MODEL_SOLUTION_GCS_PATH}. Each file should have the following response.

{
  "metrics": {
    "aggregatedRouteMetrics": {
      "breakDuration": "0s",
      "delayDuration": "0s",
      "maxLoads": {
        "weight": {
          "amount": "30"
        }
      },
      "performedShipmentCount": 2,
      "totalDuration": "4267s",
      "travelDistanceMeters": 9834,
      "travelDuration": "2276s",
      "visitDuration": "802s",
      "waitDuration": "1189s"
    },
    "earliestVehicleStartTime": "1970-01-01T00:00:35Z",
    "latestVehicleEndTime": "1970-01-01T01:11:42Z",
    "usedVehicleCount": 1
  },
  "routes": [
    {
      "endLoads": [
        {
          "type": "weight"
        }
      ],
      "metrics": {
        "breakDuration": "0s",
        "delayDuration": "0s",
        "maxLoads": {
          "weight": {
            "amount": "30"
          }
        },
        "performedShipmentCount": 2,
        "totalDuration": "4267s",
        "travelDistanceMeters": 9834,
        "travelDuration": "2276s",
        "visitDuration": "802s",
        "waitDuration": "1189s"
      },
      "transitions": [
        {
          "startTime": "1970-01-01T00:00:35Z",
          "totalDuration": "965s",
          "travelDistanceMeters": 4244,
          "travelDuration": "965s",
          "vehicleLoads": {
            "weight": {}
          }
        },
        {
          "startTime": "1970-01-01T00:19:10Z",
          "totalDuration": "510s",
          "travelDistanceMeters": 2479,
          "travelDuration": "510s",
          "vehicleLoads": {
            "weight": {
              "amount": "10"
            }
          }
        },
        {
          "startTime": "1970-01-01T00:30:11Z",
          "totalDuration": "1189s",
          "travelDuration": "0s",
          "vehicleLoads": {
            "weight": {
              "amount": "30"
            }
          },
          "waitDuration": "1189s"
        },
        {
          "startTime": "1970-01-01T00:54:10Z",
          "totalDuration": "0s",
          "travelDuration": "0s",
          "vehicleLoads": {
            "weight": {
              "amount": "20"
            }
          }
        },
        {
          "startTime": "1970-01-01T00:58:21Z",
          "totalDuration": "801s",
          "travelDistanceMeters": 3111,
          "travelDuration": "801s",
          "vehicleLoads": {
            "weight": {}
          }
        }
      ],
      "travelSteps": [
        {
          "distanceMeters": 4244,
          "duration": "965s"
        },
        {
          "distanceMeters": 2479,
          "duration": "510s"
        },
        {
          "duration": "0s"
        },
        {
          "duration": "0s"
        },
        {
          "distanceMeters": 3111,
          "duration": "801s"
        }
      ],
      "vehicleDetour": "4267s",
      "vehicleEndTime": "1970-01-01T01:11:42Z",
      "vehicleStartTime": "1970-01-01T00:00:35Z",
      "visits": [
        {
          "arrivalLoads": [
            {
              "type": "weight"
            }
          ],
          "demands": [
            {
              "type": "weight",
              "value": "10"
            }
          ],
          "detour": "0s",
          "isPickup": true,
          "loadDemands": {
            "weight": {
              "amount": "10"
            }
          },
          "startTime": "1970-01-01T00:16:40Z"
        },
        {
          "arrivalLoads": [
            {
              "type": "weight",
              "value": "10"
            }
          ],
          "demands": [
            {
              "type": "weight",
              "value": "20"
            }
          ],
          "detour": "756s",
          "isPickup": true,
          "loadDemands": {
            "weight": {
              "amount": "20"
            }
          },
          "shipmentIndex": 1,
          "startTime": "1970-01-01T00:27:40Z"
        },
        {
          "arrivalLoads": [
            {
              "type": "weight",
              "value": "30"
            }
          ],
          "demands": [
            {
              "type": "weight",
              "value": "-10"
            }
          ],
          "detour": "1340s",
          "loadDemands": {
            "weight": {
              "amount": "-10"
            }
          },
          "startTime": "1970-01-01T00:50:00Z"
        },
        {
          "arrivalLoads": [
            {
              "type": "weight",
              "value": "20"
            }
          ],
          "demands": [
            {
              "type": "weight",
              "value": "-20"
            }
          ],
          "detour": "1439s",
          "loadDemands": {
            "weight": {
              "amount": "-20"
            }
          },
          "shipmentIndex": 1,
          "startTime": "1970-01-01T00:54:10Z"
        }
      ]
    },
    {
      "vehicleIndex": 1
    }
  ]
}

For a description of the response, see Response to the request in the VRP example page.