# Deep Integration

The Deep Integration option lets you build your own driver-facing application on top of Better Route's optimisation engine, calling the [Better Route API](/products/route/apis/ntc/tour-commander-api) directly from your backend. The core flow, creating a tour and requesting a sequence, is enough on its own for most integrations; the sections further down cover optional extensions once that's working.

Before you start, make sure you've covered the [shared prerequisites](/products/route/resources/route-integration-options), in particular your Data Gateway connector needs to already be delivering job data, since there's nothing to build a tour from otherwise.

## How it works

Three things happen, in order, for every tour:

1. **Job data arrives.** Your [connector](/overview/data-gateway/resources/connector-design) sends job data (deliveries, pickups, collections) into the Data Gateway, tagged with an `assignment` value: the vehicle, route, or driver identifier for that tour.
2. **You create a tour.** Your backend calls the Better Route API with that same `assignment` value, plus the `date` and `depot`. Better Route uses `assignment` to look up the jobs your connector already sent.
3. **You request a sequence.** Once the tour exists, you ask Better Route to optimise it. This is where the actual stop order and ETAs come from: a tour without a sequence has no order yet.


```mermaid
sequenceDiagram
    participant Conn as Your Connector
    participant DG as Data Gateway
    participant BR as Better Route API
    participant BE as Your Backend

    Conn->>DG: Job data (tagged with assignment)
    DG->>BR: Job data
    BE->>BR: Create tour (date, assignment, depot)
    BR-->>BE: tourId
    BE->>BR: Request sequence (tourId, mode)
    BR-->>BE: Ordered waypoints, jobs, ETAs
    BR->>DG: Job status updates
```

*Above is a simplified flow, there are more options of interaction between Your Backend and the Better Route API.*

## Creating your first tour and sequence

**1. Create the tour**: [`POST /v1/tours`](/products/route/apis/ntc/tour-commander-api#operation/createTour) with `date`, `assignment`, and `depot`. This returns a `tourId` you'll use for every subsequent call on this tour.

**2. Request a sequence**: [create a sequence](/products/route/apis/ntc/tour-commander-api#operation/createSequence) for that `tourId`, specifying a `mode`. The sequence is what actually contains the ordered waypoints, jobs, and ETAs your driver-facing app displays: creating the tour alone doesn't sequence it.

Request a new sequence at least every 10 minutes, and more often whenever something changes: a job status update, a new pickup, a timeframe change. See the [Better Route API reference](/products/route/apis/ntc/tour-commander-api) for full request and response schemas.

### Sequence modes

Four modes are available:

| Mode | What it does | Use it when |
|  --- | --- | --- |
| `FIXED_OPTIMIZATION` | Recalculates ETAs, keeps the existing waypoint order intact (waypoints only move in special cases, e.g. a timeframe change). | This is your default: the vast majority of sequence requests. |
| `FULL_OPTIMIZATION` | Builds an entirely new sequence from scratch, without trying to preserve the previous order. | The route has changed enough that re-optimising from scratch is worth it. Check [potential recalculation gain](#checking-for-recalculation-gain) first. |
| `RETURN_TO_PREVIOUS_WAYPOINT_ORDER` | Reverts to the last order used before a `FULL_OPTIMIZATION`. | A `FULL_OPTIMIZATION` result needs to be undone. |
| `USE_PROVIDED` | Keeps exactly the waypoint order you provide, ignoring timeframes. | You, or the driver, want full manual control over the order. |


```mermaid
%%{
  init: {
    'themeVariables': {
      'fontSize': '80%',
      'edgeLabelBackground': '#efefef'
    }
  }
}%%
graph TD
    Start{"Requesting a sequence"}
    Start -->|"Otherwise (default)"| FI("FIXED_OPTIMIZATION")
    Start -->|"Route has changed enough to<br/>warrant re-optimising from scratch?"| FU("FULL_OPTIMIZATION")
    FU -->|"Undoing a previous<br/>FULL_OPTIMIZATION?"| RT("RETURN_TO_PREVIOUS_WAYPOINT_ORDER")
    Start -->|"Want full manual control<br/>over the order?"| UP("USE_PROVIDED")
```

## Extended use cases

Once the core flow above is working, each of the following is an optional enhancement you can add independently, as your drivers' real-world needs come up. Every delivery route is a little different, drivers have their own habits, and that's fine. Better Route is built to support that. These are all extra endpoints on top of the same [Better Route API](/products/route/apis/ntc/tour-commander-api), not a separate integration.

- **Selecting the first waypoint**: a driver may prefer to start in a particular street or area. Allow it in the [sequence request](/products/route/apis/ntc/tour-commander-api#operation/createSequence); it can also be changed through the day.
- **Setting a custom timeframe on a waypoint**: timeframes usually arrive on jobs via the connector, but a driver may need to pin one directly on the [waypoint](/products/route/apis/ntc/tour-commander-api#operation/pinWaypointTimeFrame) (e.g. a road that closes after 10:30 am).
- **Adding and removing custom jobs**: most jobs come through the connector, but some don't, for example a driver needing to charge the vehicle. Adding it as a [custom job](/products/route/apis/ntc/tour-commander-api#operation/createCustomJob) means the stop is considered in sequencing and ETAs adjust accordingly. Best combined with custom timeframes and stop times.
- **Defining a custom destination**: drivers usually return to the depot, but not always. Define a [custom destination](/products/route/apis/ntc/tour-commander-api#operation/setTourDestination) and it's factored into calculations.
- **Defining custom waypoints**: for a "mega stop" (one parking spot, several addresses on foot), the driver can define a [custom waypoint](/products/route/apis/ntc/tour-commander-api#operation/createCustomWaypoint) with its jobs and address.
- **Setting custom stop times**: stop times are calculated from the jobs at each waypoint, but the system can't always estimate them, for example at a security check. Drivers can set a [custom stop time](/products/route/apis/ntc/tour-commander-api#operation/pinWaypointStopTime), ideally in 15-minute intervals, to keep the choice simple.
- **Checking for recalculation gain**: while on the road, faster routes might appear, especially with a fully custom order. Check periodically for [potential recalculation gain](/products/route/apis/ntc/tour-commander-api#operation/getPotentialRecalcGain) using `FULL_OPTIMIZATION`, then switch back to `FIXED_OPTIMIZATION` once done.


## Further extension options

Beyond the API itself, two optional libraries extend a Deep Integration further:

### Navigation SDK

The Better Route API gives you an optimised sequence of stops, but not a navigation interface. The [Navigation SDK](/products/route/sdks/navigation-sdk) adds turn-by-turn navigation on top of that sequence, built specifically for the last-mile delivery use case rather than general-purpose driving directions.

### Address Formatter Kotlin

The Better Route API returns addresses as individual components, such as street, house number, and postal code, not a single formatted string. If you serve multiple countries, the expected order and conventions for those components differ (for example, whether the house number comes before or after the street name). The [Address Formatter Kotlin](/products/route/resources/address-formatter-kotlin) library handles that per-country formatting for you, and it's free and open source. If you only operate in a single country, you likely don't need it: you can just hard-code the component order yourself.

## More ideas or questions?

The last-mile space is complex. If you have a use case we haven't covered here, reach out, we're happy to talk it through and recommend an approach.