At times, you might want to plan the route your app provides to users. Using a
route token from the Routes API or
Route Optimization API can help you specify two things for your
planned route:

- A polyline for the route

- Your route objectives

For example, here are some examples of routing objectives you may have:

- **Minimize time to delivery**: A business delivering food might want to
  minimize the time it takes to deliver the food.

- **Minimize travel time or fuel consumption**: A logistics business might
  want to improve the efficiency of their drivers and reduce their fuel costs.

- **Minimize time to destination**: A service dispatch operation might want to
  minimize the time it takes to get operators to a job request.

- **Lower costs and improve safety**: A ride-sharing business might want to
  find a route that costs less for riders and avoids certain areas for safety
  reasons.

> [!IMPORTANT]
> **Important:** The route that drivers travel can differ from your planned route. Changing traffic or road conditions, the vehicle leaving the planned route, or a switch to a faster route can change the route during the trip. Whenever the Navigation SDK calculates a new route, it uses the routing options set in your route token, such as avoiding tolls.

For more information about planning a route using a route token, see [Get a
route token](https://developers.google.com/maps/documentation/routes/route_token) in
Routes API and [Transition Polylines and Route
Tokens](https://developers.google.com/maps/documentation/route-optimization/polylines-and-route-tokens) in
Route Optimization API.

## Why use a route token for route objectives

With a route token from the Routes API or
Route Optimization API, you have more control over the route
provided:

- **Plan a route in advance** for the Navigation SDK to use.

- **Choose the best route for the Navigation SDK to use**. If you
  request route tokens when generating routes in the Routes API,
  you get a route token for each generated route. You can then choose the
  token for the route you want to use when you pass it to the
  Navigation SDK.

- **Estimate the price in advance**, including estimations for ETA and
  distance. While the actual cost and time might vary, this estimation reduces
  the gap between expected and actual route cost.

- **Specify more advanced route objectives**, such as eco routing or the
  shortest route.

> [!TIP]
> **Tip:** A route token is for one specific origin and destination and at a particular time. You must make a new Routes API or Route Optimization API request for a new route token.

## How route tokens work

You can use the Routes API or
Route Optimization API to plan a route using route objectives.
You can pass a route token returned from either of these APIs to the
Navigation SDK to guide how it routes your vehicle.

Here's what happens when you request and use a route token:

1. The Routes API or Route Optimization API
   returns an encrypted route token that includes the route polyline and route
   objectives.

2. You pass the route token to the Navigation SDK.

3. The Navigation SDK starts navigation on your planned route,
   even if a faster route is available.

4. During the trip, if traffic or road conditions change, or if the vehicle
   leaves the planned route, the Navigation SDK calculates a new
   route that follows the route objectives and routing options set in your
   route token.

This process maximizes how close the actual route is to your planned route.

### Why a planned route may not be followed exactly

Navigation starts on your planned route, but the actual route can differ from
it in situations like the following:

- The vehicle starts away from the planned starting point.
- Traffic or road conditions change during the trip.
- The vehicle leaves the planned route.

These differences can affect the distance, ETA, and other important trip
qualities that you planned for.

> [!TIP]
> **Tip:** As a best practice, always request a new route token every time you set the destination in the Navigation SDK, and plan for some variation to avoid any impact to your business.

## Plan a route using a route token

You can plan a route by creating a route token and then passing it to the
Navigation SDK, as described in the following steps:

### Step 1: Create a route token using the Routes API or Route Optimization API

1. **Request a route token** with one of the following methods:

   - **Routes API** : `computeRoutes`. For more information
     about requesting a route token in the Routes API, see
     [Compute a route](https://developers.google.com/maps/documentation/routes/compute_route_directions.md.txt)
     and [Get a route token](https://developers.google.com/maps/documentation/routes/route_token.md.txt).

   - **Route Optimization API** : `optimizeTours` or
     `batchOptimizeTours`. For more information about requesting a route
     token in the Route Optimization API, see
     [Transition Polylines and Route Tokens](https://developers.google.com/maps/documentation/route-optimization/polylines-and-route-tokens.md.txt).

2. **Set up your Routes API request** to meet the requirements
   for using a route token:

   - Set `travelMode` to `DRIVE` or `TWO_WHEELER`.
   - Set `routingPreference` to `TRAFFIC_AWARE` or `TRAFFIC_AWARE_OPTIMAL`.
   - Don't use `Via` waypoints.

> [!NOTE]
> **Note:** You can specify precise origin and destination values, such as entrances, loading docks, or designated pick-up areas, in your route token using a [navigation point token](https://developers.google.com/maps/documentation/navigation/ios-sdk/navigation-points.md.txt#use_a_navigation_point_token).

### Step 2: Pass the route token to the Navigation SDK

1. **Store the route token**: In the Navigation SDK, set up a string
   to store the route token. For example:

   ```swift
   let routeToken = "route token returned by Routes API"
   ```

   Example of a returned route token:

   ```json
   {
   // Other fields
   "routeToken": "CqMBCjoKCJQOor5DHcwiEhBon3XpHXFnVvDeWMwd9PpAGgz6wtnFDKIBrAHTARpCApUDSggAAAAACjcrP3gBEAQaTApKChgKDQoCCAERAAAAAACAZkAR3SQGgZUXdUASEggAEAMQBhATEBIYAkIEGgIIBSIYChZ2VEJiWlBPSkk1aU5wUVRzNTV5d0FRKAEiFQBcJuds-Efh-2QZhOMTtUCCxEVL_g",
   }
   ```
2. **Pass the route token** to the Navigation SDK using the
   [`setDestinationsWithToken:completionHandler:`](https://developers.google.com/maps/documentation/navigation/ios-sdk/reference/objc/Classes/GMSNavigator.md.txt#-setdestinationswithtoken:completionhandler:)
   method of `mapView.navigator`. The Navigation SDK gets the
   destinations and routing options from the route token, so you don't need
   to pass waypoints.

   The travel mode set in your app, such as `mapView.travelMode`, must be one
   of the following values:
   - `.driving` (`GMSNavigationTravelModeDriving`): Driving. This is the default value, so most apps don't need to change it.
   - `.twoWheeler` (`GMSNavigationTravelModeTwoWheeler`): Two-wheeler.

   Any other travel mode makes the request fail with `.travelModeUnsupported`
   (`GMSRouteStatusTravelModeUnsupported`). With either supported value, the
   route uses the travel mode in your route token. For example, if your app
   uses driving and your route token is for a two-wheeler route, the
   Navigation SDK provides a two-wheeler route. To confirm which
   travel mode the route uses, check `resolvedParameters.travelMode`. For more
   information, see [Resolved routing options](https://developers.google.com/maps/documentation/navigation/ios-sdk/route-customizations.md.txt#resolved-parameters).

   <br />

   > [!NOTE]
   > **Note:** If your app uses a version of the Navigation SDK earlier than 11.3, use the deprecated [`setDestinations:routeToken:callback:`](https://developers.google.com/maps/documentation/navigation/ios-sdk/reference/objc/Classes/GMSNavigator.md.txt#-setdestinations:routetoken:callback:) method instead, and pass the same destination waypoints that you used to create the route token.

3. **Check the route status** in your completion handler. When the
   Navigation SDK finishes calculating the route, it passes a
   [`GMSNavigationRouteDescription`](https://developers.google.com/maps/documentation/navigation/ios-sdk/reference/objc/Protocols/GMSNavigationRouteDescription.md.txt)
   to your completion handler. If it finds a route from the vehicle's
   location to the destinations in your route token, the route description's
   `routeStatus` is `.OK` (`GMSRouteStatusOK`), and you can start guidance.
   Otherwise, your completion handler also receives an `NSError` that
   describes the failure. For example:

   ```swift
   mapView.navigator?.setDestinationsWithToken(routeToken) { [weak self] routeDescription, error in
     if routeDescription?.routeStatus == .OK {
       self?.mapView.navigator?.isGuidanceActive = true
     }
   }
   ```

> [!NOTE]
> **Note:** If you need to travel the same route again, request a new route token.

### Check whether the Navigation SDK applied your route token

A route status of `.OK` means that the Navigation SDK found a route,
but not necessarily your planned route. To check whether the route matches your
planned route, follow these steps in your completion handler:

1. Confirm that the route description's `routeStatus` is `.OK`. The
   Navigation SDK provides route token details only when it finds a
   route. For more information, see [Step 2](https://developers.google.com/maps/documentation/navigation/ios-sdk/route-customizations.md.txt#use-token-step-2).

2. Get the route description's `routeTokenExecutionDetails`, an object that
   conforms to the
   [`GMSNavigationRouteTokenExecutionDetails`](https://developers.google.com/maps/documentation/navigation/ios-sdk/reference/objc/Protocols/GMSNavigationRouteTokenExecutionDetails.md.txt)
   protocol. If the server doesn't provide route token details, this property
   is `nil`.

3. Check the `tokenExecutionStatus` property of the execution details. If it's
   `.tokenSuccessfullyApplied`, the route matches your planned route. Any other
   status means that the route might differ from your planned route. For more
   information about each status, see
   [Token execution status values](https://developers.google.com/maps/documentation/navigation/ios-sdk/route-customizations.md.txt#token-execution-status).

4. Optional: If the status is `.tokenSuccessfullyApplied`, check the
   `resolvedParameters` property of the same execution details to see which
   routing options the route uses, such as whether it avoids tolls. For more
   information, see [Resolved routing options](https://developers.google.com/maps/documentation/navigation/ios-sdk/route-customizations.md.txt#resolved-parameters).

#### Token execution status values

If `routeStatus` is `.OK`, you can start guidance with any token execution
status. The status tells you whether the route follows your planned route.

| Status | Follows your planned route | Description |
|---|---|---|
| [`.tokenSuccessfullyApplied`](https://developers.google.com/maps/documentation/navigation/ios-sdk/reference/objc/Enums/GMSNavigationRouteTokenExecutionStatus.md.txt#gmsnavigationroutetokenexecutionstatustokensuccessfullyapplied) | Yes | The Navigation SDK applied your route token. |
| [`.tokenAppliedWithLocationMismatch`](https://developers.google.com/maps/documentation/navigation/ios-sdk/reference/objc/Enums/GMSNavigationRouteTokenExecutionStatus.md.txt#gmsnavigationroutetokenexecutionstatustokenappliedwithlocationmismatch) | Not necessarily | The Navigation SDK couldn't rebuild your planned route, and the device was more than 25 meters from the origin in your route token. The route still uses the destinations and routing options from your route token. |
| [`.tokenIgnoredOther`](https://developers.google.com/maps/documentation/navigation/ios-sdk/reference/objc/Enums/GMSNavigationRouteTokenExecutionStatus.md.txt#gmsnavigationroutetokenexecutionstatustokenignoredother) | Not necessarily | The Navigation SDK couldn't rebuild your planned route for another reason, for example, because a road on your planned route is closed. The route still uses the destinations and routing options from your route token. |
| [`.noTokenProvided`](https://developers.google.com/maps/documentation/navigation/ios-sdk/reference/objc/Enums/GMSNavigationRouteTokenExecutionStatus.md.txt#gmsnavigationroutetokenexecutionstatusnotokenprovided) | Not applicable | The route request didn't include a route token. |
| [`.unknown`](https://developers.google.com/maps/documentation/navigation/ios-sdk/reference/objc/Enums/GMSNavigationRouteTokenExecutionStatus.md.txt#gmsnavigationroutetokenexecutionstatusunknown) | Unknown | The status is unknown. |

If the route doesn't necessarily follow your planned route and the exact route
matters, for example, because you used it to calculate a price, log the status
or request a new route token from the vehicle's current location.

#### Resolved routing options

`resolvedParameters` is an object that conforms to the
[`GMSNavigationRouteTokenResolvedParameters`](https://developers.google.com/maps/documentation/navigation/ios-sdk/reference/objc/Protocols/GMSNavigationRouteTokenResolvedParameters.md.txt)
protocol, or `nil` if the routing options aren't available. It has the
following properties:

- `travelMode`: The travel mode that the route uses, such as `.driving` (`GMSNavigationTravelModeDriving`). The Navigation SDK also reports `.driving` when the route uses a travel mode that has no matching value, or when the travel mode isn't available.
- `avoidTolls`: Whether the route avoids tolls.
- `avoidHighways`: Whether the route avoids highways.
- `avoidFerries`: Whether the route avoids ferries.
- `avoidTunnels`: Whether the route was calculated to avoid tunnels when possible.
- `avoidVignettes`: The countries where the route was calculated to avoid toll vignettes when possible, as Unicode CLDR two-letter region codes, such as `CH` for Switzerland.
- `rerouteStrategy`: The strategy that the routing backend uses to calculate new routes during the trip. Strategies include `.bestBasedOnTokenParameters` (`GMSNavigationRerouteStrategyBestBasedOnTokenParameters`), which uses the routing parameters in your route token to calculate new routes.

If the token execution status isn't `.tokenSuccessfullyApplied`, the
Navigation SDK reports only `travelMode`, `avoidTolls`,
`avoidHighways`, and `avoidFerries`. The other properties have their default
values, even if you asked to avoid tunnels or toll vignettes when you requested
the route token: `avoidTunnels` is `false` (`NO`), `avoidVignettes` is empty,
and `rerouteStrategy` is `.unknown` (`GMSNavigationRerouteStrategyUnknown`).

<br />

### Example

The following code example demonstrates how to plan a route using a route
token, check whether the Navigation SDK applied the token, and start
guidance.

<br />

### Swift

<br />

```swift
let routeToken = "route token returned by Routes API"

mapView.navigator?.setDestinationsWithToken(routeToken) { [weak self] routeDescription, error in
  // Check whether the Navigation SDK found a route.
  guard routeDescription?.routeStatus == .OK else {
    print("Route error: \(error?.localizedDescription ?? "unknown")")
    return
  }

  // Check whether the Navigation SDK applied the route token.
  if let executionDetails = routeDescription?.routeTokenExecutionDetails {
    if executionDetails.tokenExecutionStatus != .tokenSuccessfullyApplied {
      print("The route might differ from your planned route.")
    }
  } else {
    print("Route token details aren't available.")
  }

  self?.mapView.navigator?.isGuidanceActive = true
}
```

<br />

### Objective-C

<br />

```objective-c
NSString *routeToken = @"route token returned by Routes API";

[mapView.navigator setDestinationsWithToken:routeToken
                          completionHandler:^(id<GMSNavigationRouteDescription> _Nullable routeDescription,
                                              NSError *_Nullable error) {
  // Check whether the Navigation SDK found a route.
  if (routeDescription.routeStatus != GMSRouteStatusOK) {
    NSLog(@"Route error: %@", error.localizedDescription);
    return;
  }

  // Check whether the Navigation SDK applied the route token.
  id<GMSNavigationRouteTokenExecutionDetails> executionDetails =
      routeDescription.routeTokenExecutionDetails;
  if (executionDetails == nil) {
    NSLog(@"Route token details aren't available.");
  } else if (executionDetails.tokenExecutionStatus !=
             GMSNavigationRouteTokenExecutionStatusTokenSuccessfullyApplied) {
    NSLog(@"The route might differ from your planned route.");
  }

  mapView.navigator.guidanceActive = YES;
}];
```

<br />

<br />

### Multi-stop scenarios

You can configure a maximum of 25 waypoints.

The Navigation SDK doesn't automatically advance to the next
destination. When the vehicle arrives at a waypoint, call
[`continueToNextDestinationWithCompletion:`](https://developers.google.com/maps/documentation/navigation/ios-sdk/reference/objc/Classes/GMSNavigator.md.txt#-continuetonextdestinationwithcompletion:)
to start the next leg of the trip. This also applies to route tokens that have
intermediate waypoints. When you advance to the next destination, the
Navigation SDK keeps following the route from your route token
instead of planning a new route.

> [!CAUTION]
> **Caution:** Calling the `continueToNextDestinationWithCompletion:` method can sometimes result in an incorrect arrival event, where the just-completed destination appears to be re-selected.


## How route tokens and the Navigation SDK interact

Here's how the Navigation SDK handles your planned route:

- **Overrides** any previously set destinations.

- **Uses** the vehicle starting location.

- **Adjusts** for road and traffic conditions. See
  [Why a planned route might not be followed exactly](https://developers.google.com/maps/documentation/navigation/ios-sdk/route-customizations.md.txt#not-followed).

<!-- -->

- **Uses the routing options set in your route token** instead of the
  following settings in your app, including when it calculates a new route
  during the trip:

  - `avoidsHighways`
  - `avoidsTolls`
  - `avoidsFerries`
  - `licensePlateRestriction`
  - The travel mode set in your app

<!-- -->

- **Follows** these settings when it calculates or adjusts the route:

  - **Route objectives from your route token**, such as eco routing or the shortest route. If the Navigation SDK has to adjust the route, it uses the route objectives that you specified when you requested the route token.
  - **Waypoint-related options from your route token**, such as the side-of-road preference.

> [!NOTE]
> **Note:** With `setDestinationsWithToken:completionHandler:`, you don't pass waypoints, so the Navigation SDK uses the destinations and waypoint options from your route token. To set waypoint options, such as the side-of-road preference or vehicle stopovers, use the `sideOfRoad` and `vehicleStopover` fields on the waypoints in your Routes API request. The origin is always the device's location, so options that you set on the origin in your Routes API request don't apply.