**European Economic Area (EEA) developers**

> [!NOTE]
> If your billing address is in the European Economic Area, effective on 8 July 2025, the [Google Maps Platform EEA Terms of Service](https://cloud.google.com/terms/maps-platform/eea) will apply to your use of the Services. Functionality varies by region. [Learn more](https://developers.google.com/maps/comms/eea/faq.md.txt).

This document shows you how to make your first request to the Route Optimization
API using a real-world use-case scenario.

For simplicity, the example uses HTTP and JSON to demonstrate the REST API. For
your production environment, however, the overall
**recommendation is to use gRPC** for its performance benefits. However, gRPC
requires some installation. For more information, see
[Route Optimization API client libraries](https://developers.google.com/maps/documentation/route-optimization/client-libraries.md.txt).

## Scenario

![A map of San Francisco with pins for Coit Tower, Mission Dolores Park, and South Sunset Playground Park](https://developers.google.com/static/maps/documentation/route-optimization/images/first-request-scenario-map.png)

You run a doggy daycare service from 7 AM to 7 PM in San Francisco. This
morning, you want to pick up three dogs from different locations in the city and
bring them to your daycare center.

The Bernese mountain dog and the Chihuahua are regular clients who booked their
appointments last week. The German shepherd is a new, last-minute request. You
want to accommodate the German shepherd if possible, but not at the expense of
your regular clients.

You have one van for the job, and you pay the driver $27 an hour. The
driver and van start the day at your daycare center at 7 AM and need to be
back from the morning pickups by noon for a lunch break.

Today is February 13, 2024. All times in this scenario are San Francisco local
time, which is Pacific Standard Time (UTC-8) in February. The driver has the
following tasks:

- Pick up the Bernese mountain dog near Coit Tower. The owner requested a tight pickup window between 8 AM and 8:20 AM.
- Pick up the Chihuahua at the South Sunset Playground Park. The owner offered a more flexible pickup window between 7:30 AM and 9:30 AM.
- Pick up the German shepherd at Land's End. The owner also requested a tight pickup window between 8 AM and 8:20 AM.
- Drop off the dogs at the daycare center at Mission Dolores Park. The daycare requires dropoffs between 9:30 AM and 11:30 AM.

Each pickup and dropoff visit takes 5 minutes to load or unload the dog.

Because Land's End is far from Coit Tower and their pickup windows conflict, the
driver cannot perform all three pickups. The optimizer must choose which dog to
skip to minimize the total cost (driver wages and any skip penalties).

## Before you begin

To run the code in this example scenario, you must first complete the
instructions in [Set up the Route Optimization API](https://developers.google.com/maps/documentation/route-optimization/cloud-setup.md.txt).

## 1. Choose your route optimization approach

The Route Optimization API has multiple methods for you to choose from depending
on the complexity of your optimization problem.

Because this doggy daycare scenario is a small and straightforward request, use
a blocking method, such as [`optimizeTours`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/projects/optimizeTours.md.txt), which quickly delivers results
for small requests. For more information about the Route Optimization API
endpoints, see [Choose an endpoint](https://developers.google.com/maps/documentation/route-optimization/endpoints.md.txt).

Use the following URL to make an HTTP POST request to the [`optimizeTours`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/projects/optimizeTours.md.txt)
method:

    https://routeoptimization.googleapis.com/v1/projects/PROJECT_OR_ID:optimizeTours

You also need to set the timeout and deadline settings to be short to reduce any
unnecessary wait time. For this doggy daycare scenario, the optimizer doesn't
need a lot of time to respond to your request, so use the following settings:

- Set the [`timeout`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/projects/optimizeTours.md.txt#body.request_body.FIELDS.timeout) parameter to 2 seconds.
- Leave the deadline settings at the default, which is 60 seconds for REST requests.

> [!IMPORTANT]
> **Important:** For other types of requests, you should set the timeout and deadline settings based on the complexity of your request, the method, and your chosen protocol. For more details, see [Timeouts and deadlines](https://developers.google.com/maps/documentation/route-optimization/timeouts.md.txt).

## 2. Construct the request message body

After choosing the blocking [`optimizeTours`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/projects/optimizeTours.md.txt) method and defining the timeout
and deadline settings, your next step is to construct the body of the request
message.

For this scenario, the request is an [`OptimizeToursRequest`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/projects/optimizeTours.md.txt#body.request_body) message
encoded as JSON in the REST API.

To construct the request message, follow the next steps:

1. **Start with the basic request structure**, which is as follows:

   ```json
   {
     "timeout": ...,
     "model": {
       "shipments": [...],
       "vehicles": [...],
       "globalStartTime": "...",
       "globalEndTime": "..."
     }
   }
   ```

   For more information on the structure, see the key concept guide for
   [Base structure (ShipmentModel, Shipment, and Vehicle)](https://developers.google.com/maps/documentation/route-optimization/concepts/base-structure.md.txt).
2. **Define shipments.** In the [`shipments`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#FIELDS.shipments) field, add a [`Shipment`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#Shipment)
   message for each dog that needs to be picked up and dropped off in the
   morning. This is where you define each of the dog owner's preferred pickup
   location and times and the daycare center's location and times to drop the
   dogs off.

   1. For each dog, create a [`VisitRequest`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#VisitRequest) for pickups and another for
      the deliveries, which, for this scenario, is referred to as the daycare
      dropoff.

      - In pickups, set the [`arrivalWaypoint`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#VisitRequest.FIELDS.arrival_waypoint) to the dog's
        pickup location (Coit Tower for the Bernese mountain dog, South
        Sunset Playground Park for the Chihuahua, or Land's End for the
        German shepherd). Set the [`timeWindows`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#VisitRequest.FIELDS.time_windows) to the owner's
        requested pickup time (8 AM to 8:20 AM for the Bernese mountain
        dog and German shepherd, and 7:30 AM to 9:30 AM for the Chihuahua).

      - In deliveries, set the [`arrivalWaypoint`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#VisitRequest.FIELDS.arrival_waypoint) to the
        daycare center and the [`timeWindows`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#VisitRequest.FIELDS.time_windows) for the required dropoff
        time (9:30 AM to 11:30 AM).

      - For all pickups and deliveries, set the [`duration`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#VisitRequest.FIELDS.duration) to 5
        minutes (`300s`) to account for loading and unloading the dogs.

      For more information on time windows, see [Time windows](https://developers.google.com/maps/documentation/route-optimization/concepts/time-windows.md.txt).
   2. To prioritize regular clients, you set the [`penaltyCost`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#Shipment.FIELDS.penalty_cost) to `1000`
      for the Bernese mountain dog and Chihuahua, and `100` for the German
      shepherd. With penalty costs set, the optimizer can skip any of the
      dogs, but it considers skipping the German shepherd (which has a lower
      penalty) first if constraints make it impossible to perform all pickups.

   3. You can use the [`label`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#Shipment.FIELDS.label) field to add an identifier for each
      shipment, like "Bernese mountain dog", "Chihuahua", and "German
      shepherd". This can help you identify the shipments in the response.

   For more information on defining shipments, see [Shipment](https://developers.google.com/maps/documentation/route-optimization/concepts/base-structure.md.txt#shipment).
3. **Define vehicles.** In the [`vehicles`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#FIELDS.vehicles) field, add a [`Vehicle`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#Vehicle)
   message for your one van with the daycare center as the starting and end
   points, the cost of the driver's wage, and the operational hours for the
   van.

   1. Set the [`startWaypoint`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#Vehicle.FIELDS.start_waypoint) and [`endWaypoint`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#Vehicle.FIELDS.end_waypoint) for the van to the
      start and end locations of the day, which is the daycare center near
      Mission Dolores Park.

   2. To minimize your costs of operation, you must define the cost
      constraints of your business. Set the cost parameter [`costPerHour`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#Vehicle.FIELDS.cost_per_hour)
      to `27`, which is how much you pay the driver for driving the doggy
      daycare van. For more information on cost parameters, see
      [Cost model](https://developers.google.com/maps/documentation/route-optimization/concepts/costs.md.txt).

      > [!IMPORTANT]
      > **Important:** Costs are essential for the optimizer to find the best route. Without them, the optimizer treats all solutions as equal.

   3. To ensure the optimizer creates a route within the van's operational
      hours, define a window of operation for the vehicle. This window sets
      the starting and ending time constraints for the route. By defining only
      one half of each time window, you'll give the optimizer flexibility to
      start the route later or end it earlier:

      - Setting [`startTime`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#TimeWindow.FIELDS.start_time) in [`startTimeWindows`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#Vehicle.FIELDS.start_time_windows) to 7 AM means
        the driver can start their shift as early as 7 AM. They can also
        start later if there are no early morning pickups.

      - Setting [`endTime`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#TimeWindow.FIELDS.end_time) in [`endTimeWindows`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#Vehicle.FIELDS.end_time_windows) to noon means the
        driver must end their shift by noon. They can also end their shift
        as soon as they complete the last delivery.

      Omitting the other half of the windows minimizes the driver's wait and
      detour times. For more information on time windows, see
      [Time windows](https://developers.google.com/maps/documentation/route-optimization/concepts/time-windows.md.txt).

   For more information on defining vehicles, see [Vehicle](https://developers.google.com/maps/documentation/route-optimization/concepts/base-structure.md.txt#vehicle).
4. **Set a global time window.** The global time window represents the
   timeframe for when the van may perform pickups and dropoffs for your
   daycare throughout the day. For this scenario, set [`globalStartTime`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#FIELDS.global_start_time)
   to 7 AM and [`globalEndTime`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel.md.txt#FIELDS.global_end_time) to 7 PM for February 13, 2024, which
   represent your doggy daycare operational hours.

## 3. Send the request

The following is a simple `curl` request based on the doggy daycare scenario and
uses the blocking [`optimizeTours`](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/projects/optimizeTours.md.txt) method.

Before you send the request, replace
<var translate="no">PROJECT_NUMBER_OR_ID</var> in the sample code with your
Google Cloud project ID.

```json
curl -X POST 'https://routeoptimization.googleapis.com/v1/projects/PROJECT_NUMBER_OR_ID:optimizeTours' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
--data @- << EOM
{
  "timeout": "2s",
  "model": {
    "shipments": [
      {
        "pickups": [
          {
            "arrivalWaypoint": {
              "location": {
                "latLng": {
                  "latitude": 37.802395,
                  "longitude": -122.405822
                }
              }
            },
            "timeWindows": [
              {
                "startTime": "2024-02-13T08:00:00-08:00",
                "endTime": "2024-02-13T08:20:00-08:00"
              }
            ],
            "duration": "300s"
          }
        ],
        "deliveries": [
          {
            "arrivalWaypoint": {
              "location": {
                "latLng": {
                  "latitude": 37.759719,
                  "longitude": -122.42798
                }
              }
            },
            "timeWindows": [
              {
                "startTime": "2024-02-13T09:30:00-08:00",
                "endTime": "2024-02-13T11:30:00-08:00"
              }
            ],
            "duration": "300s"
          }
        ],
        "label": "Bernese mountain dog",
        "penaltyCost": 1000
      },
      {
        "pickups": [
          {
            "arrivalWaypoint": {
              "location": {
                "latLng": {
                  "latitude": 37.738067,
                  "longitude": -122.498593
                }
              }
            },
            "timeWindows": [
              {
                "startTime": "2024-02-13T07:30:00-08:00",
                "endTime": "2024-02-13T09:30:00-08:00"
              }
            ],
            "duration": "300s"
          }
        ],
        "deliveries": [
          {
            "arrivalWaypoint": {
              "location": {
                "latLng": {
                  "latitude": 37.759719,
                  "longitude": -122.42798
                }
              }
            },
            "timeWindows": [
              {
                "startTime": "2024-02-13T09:30:00-08:00",
                "endTime": "2024-02-13T11:30:00-08:00"
              }
            ],
            "duration": "300s"
          }
        ],
        "label": "Chihuahua",
        "penaltyCost": 1000
      },
      {
        "pickups": [
          {
            "arrivalWaypoint": {
              "location": {
                "latLng": {
                  "latitude": 37.78018,
                  "longitude": -122.51194
                }
              }
            },
            "timeWindows": [
              {
                "startTime": "2024-02-13T08:00:00-08:00",
                "endTime": "2024-02-13T08:20:00-08:00"
              }
            ],
            "duration": "300s"
          }
        ],
        "deliveries": [
          {
            "arrivalWaypoint": {
              "location": {
                "latLng": {
                  "latitude": 37.759719,
                  "longitude": -122.42798
                }
              }
            },
            "timeWindows": [
              {
                "startTime": "2024-02-13T09:30:00-08:00",
                "endTime": "2024-02-13T11:30:00-08:00"
              }
            ],
            "duration": "300s"
          }
        ],
        "label": "German shepherd",
        "penaltyCost": 100
      }
    ],
    "vehicles": [
      {
        "startWaypoint": {
          "location": {
            "latLng": {
              "latitude": 37.759719,
              "longitude": -122.42798
            }
          }
        },
        "endWaypoint": {
          "location": {
            "latLng": {
              "latitude": 37.759719,
              "longitude": -122.42798
            }
          }
        },
        "costPerHour": 27,
        "startTimeWindows": [
          {
            "startTime": "2024-02-13T07:00:00-08:00"
          }
        ],
        "endTimeWindows": [
          {
            "endTime": "2024-02-13T12:00:00-08:00"
          }
        ]
      }
    ],
    "globalStartTime": "2024-02-13T07:00:00-08:00",
    "globalEndTime": "2024-02-13T19:00:00-08:00"
  }
}
EOM
```

## Request parameters used in the request

The following table describes the request parameters used in the request body of
the example scenario. You can filter the contents by parent or by text search.
OptimizeToursRequest ShipmentModel Shipment VisitRequest Vehicle

| Parent | Parameter | Property Type | Description |
|---|---|---|---|
| `OptimizeToursRequest` | `model` | object (`ShipmentModel`) | This is the core of your request. It's a single object where you define your entire problem, including all the dogs you need to pick up and drop off (`shipments`) and the van in your fleet (`vehicles`). Think of it as the complete blueprint for the problem you need to optimize. |
| `OptimizeToursRequest` | `timeout` | Duration | This parameter specifies the maximum time the server works on a request before returning a response. Use this parameter to shorten your wait time. For small and quick requests, such as this doggy daycare scenario, set this value to 2s. |
| `ShipmentModel` | `shipments[]` | array of objects (`Shipment`) | This is an array of objects where each object represents a dog that needs to be picked up or dropped off. |
| `ShipmentModel` | `vehicles[]` | array of objects (`Vehicle`) | This is an array of objects where each object defines a vehicle in your fleet. It's where you describe your resources, such as the van that performs the pickups and dropoffs. You must define at least one vehicle to get an optimized route. |
| `ShipmentModel` | `globalStartTime` | Timestamp | This is the earliest possible time for any event in your entire model to occur. This parameter narrows the optimization problem down in time, which is crucial for accurate traffic and routing calculations. For this doggy daycare scenario, set this to the earliest time the driver can operate the van for the day, which is 7 AM for February 13, 2024. |
| `ShipmentModel` | `globalEndTime` | Timestamp | This is the latest possible time for any event in your entire model to occur. For this doggy daycare scenario, set this to when the van is expected to end its operation, which is 7 PM for February 13, 2024. |
| `Shipment` | `pickups[]` | array of objects (`VisitRequest`) | This is a list of all possible pickup options for the shipment. The optimizer chooses the best one to solve your problem. For this doggy daycare scenario, list the pickup locations and time windows that each owner provided for each dog. |
| `Shipment` | `deliveries[]` | array of objects (`VisitRequest`) | This is a list of all possible dropoff options for the shipment. The optimizer chooses the best one to solve your problem. For this doggy daycare scenario, list the location of the doggy daycare facility and the time window for when the driver needs to return for lunch for each dog. |
| `Shipment` | `label` | string | This is an identifier for a specific shipment in your request. You can specify labels in your request to make it easier to read the response. For this doggy daycare scenario, use a descriptive string like "Chihuahua", "Bernese mountain dog" or the dog's name to match the solution to your input when you receive the API response. |
| `Shipment` | `penaltyCost` | double | This is the penalty cost incurred if the optimizer skips this shipment. By default, shipments are mandatory---the optimizer prioritizes minimizing skipped mandatory shipments and skips them only when there's no other option. Setting a penalty cost lets the optimizer skip a shipment if it's infeasible or too costly to perform, and lets you weigh priorities between shipments. In this scenario, you set a higher penalty cost (`1000`) for your regular clients (Bernese mountain dog and Chihuahua) and a lower penalty cost (`100`) for the last-minute German shepherd request. This tells the optimizer to prioritize the regular clients, so it considers skipping the German shepherd first when it can't perform all pickups. |
| `VisitRequest` | `arrivalWaypoint` | object (`Waypoint`) | This is the location of a specific visit on the route. You can define this using latitude and longitude coordinates, a place ID, or a heading. In this doggy daycare scenario, set this to the location provided by the owner for `pickups` and to the daycare center's address for `deliveries`. |
| `VisitRequest` | `timeWindows[]` | array of objects (`TimeWindow`) | This is an array of objects that define the time constraints for a pickup or delivery. For this scenario, use this to define the pickup window for each of the dogs and the acceptable window for dropping the dogs off at the daycare center. |
| `VisitRequest` | `duration` | Duration | This parameter specifies the duration of the visit (e.g. loading or unloading time). In this scenario, you set a 5-minute buffer (`300s`) for all pickups and deliveries to account for the driver loading and unloading the dogs. |
| `Vehicle` | `startWaypoint` | object (`Waypoint`) | This is the starting location of the vehicle's route, defined with latitude and longitude coordinates or a place ID. This parameter tells the optimizer where the vehicle must begin the route. If you don't define this waypoint, the optimizer chooses one of the pickups or deliveries as the starting location. For this doggy daycare scenario, because the driver starts the day at the daycare facility, use the coordinates for Mission Dolores Park. |
| `Vehicle` | `endWaypoint` | object (`Waypoint`) | This is the final destination for the vehicle's route, defined with latitude and longitude coordinates or a place ID. This parameter tells the optimizer where the vehicle must end the route. If you don't define this waypoint, the optimizer chooses one of the pickups or deliveries as the end of the route. For this doggy daycare scenario, because the driver must end the day at the daycare facility, use the coordinates for Mission Dolores Park. |
| `Vehicle` | `costPerHour` | number | This is the cost incurred for every hour a vehicle is used, regardless of whether it's traveling or stopped. For this doggy daycare scenario, use this to model a driver's hourly wage. |
| `Vehicle` | `startTimeWindows[]` | array of objects (`TimeWindow`) | This is the acceptable time window for when the driver can start their shift. For this doggy daycare scenario, define the `startTime` as 7 AM but omit the `endTime`. This allows the optimizer to delay the start of the shift if the first pickup is later in the morning. Note that even if you don't provide an `endTime` for `startTimeWindows`, the start time is implicitly bounded by the `endTimeWindows`. The vehicle must start the route before the route ends. |
| `Vehicle` | `endTimeWindows[]` | array of objects (`TimeWindow`) | This is the acceptable time window for the driver to finish the route. For this doggy daycare scenario, define the `endTime` as noon but omit the `startTime`. This allows the driver to return to the daycare center immediately after the last dropoff. |

## Next

[Interpret the response](https://developers.google.com/maps/documentation/route-optimization/interpret-response.md.txt)