Optimal Routes API
Given an unordered list of stops, work out the most efficient order to visit them in.
Overview & Solution
A driver with a dozen stops on their list, entered in whatever order they came in, ends up zig-zagging across town instead of working through them efficiently. Someone has to sit down and figure out a sensible visiting order - or the driver just wings it.
The Optimal Routes API does that ordering for you. Hand it a list of stops in any order, and it hands back the same stops resequenced into an efficient route to visit them in.
Industry Use Cases
1. Field Sales & Van Delivery
- Daily stop sequencing - turn today's list of retailer or customer stops into an order that doesn't backtrack across the same area twice.
2. Field Service & Maintenance
- Technician visit order - sequence a technician's assigned jobs for the day into an efficient route instead of visiting them in ticket-creation order.
3. Local Pickup & Delivery
- Multi-stop run planning - sequence a batch of pickups or drop-offs assigned to one driver on one route.
API reference
Route and Journey Intelligence APIs · API key only
Endpoints
All requests need only your API key, as the api-key query parameter - no bearer token:
?api-key=<apiKey>
Reorder stops into the most efficient visiting sequence
POST /routing/optimize
Base URL: https://api-gw.sovereignsolutions.com/gateway
Request Parameters
| Parameter | In | Type | Required | Description | Example |
|---|---|---|---|---|---|
locations | body | array | No | Stops to visit, in any order. The first stop is the start. | |
locations[] | body | object | No | ||
locations[].lon | body | number | No | Longitude of the point, decimal degrees. | |
locations[].lat | body | number | No | Latitude of the point, decimal degrees. | |
costing | body | string | No | Travel mode used for costing. The examples use auto (driving) and pedestrian (walking). | |
units | body | string | No | Distance unit: km. |
Request body
{
"locations": [
{
"lon": 80.2675007,
"lat": 13.0355685
},
{
"lon": 80.267291,
"lat": 13.036289
},
{
"lon": 80.267437,
"lat": 13.03525
},
{
"lon": 80.267779,
"lat": 13.034928
},
{
"lon": 80.251724,
"lat": 13.032119
}
],
"costing": "auto",
"units": "km"
}
Response Schema
200 OK
{
"trip": {
"locations": [
{
"type": "break",
"lat": 13.035568,
"lon": 80.2675,
"side_of_street": "left",
"original_index": 0
},
{
"type": "break",
"lat": 13.034928,
"lon": 80.267779,
"side_of_street": "left",
"original_index": 3
},
{
"type": "break",
"lat": 13.03525,
"lon": 80.267437,
"side_of_street": "right",
"original_index": 2
},
{
"type": "break",
"lat": 13.036289,
"lon": 80.267291,
"side_of_street": "right",
"original_index": 1
},
{
"type": "break",
"lat": 13.032119,
"lon": 80.251724,
"side_of_street": "right",
"original_index": 4
}
],
"legs": [
{
"maneuvers": [
{
"type": 3,
"instruction": "Drive southwest on Subbarayan Salai.",
"verbal_succinct_transition_instruction": "Drive southwest.",
"verbal_pre_transition_instruction": "Drive southwest on Subbarayan Salai.",
"verbal_post_transition_instruction": "Continue for 400 meters.",
"street_names": [
"Subbarayan Salai"
],
"time": 39.918,
"length": 0.442,
"cost": 67.968,
"begin_shape_index": 0,
"end_shape_index": 11,
"travel_mode": "drive",
"travel_type": "car"
},
{
"type": 15,
"instruction": "Turn left onto Venkatesa Agraharam Road.",
"verbal_transition_alert_instruction": "Turn left onto Venkatesa Agraharam Road.",
"verbal_succinct_transition_instruction": "Turn left. Then Turn right onto Sathyani Muthu Street.",
"verbal_pre_transition_instruction": "Turn left onto Venkatesa Agraharam Road. Then Turn right onto Sathyani Muthu Street.",
"verbal_post_transition_instruction": "Continue for 50 meters.",
"street_names": [
"Venkatesa Agraharam Road"
],
"time": 11.643,
"length": 0.048,
"cost": 33.968,
"begin_shape_index": 11,
"end_shape_index": 14,
"verbal_multi_cue": true,
"travel_mode": "drive",
"travel_type": "car"
}
],
"summary": {
"has_time_restrictions": false,
"has_toll": false,
"has_highway": false,
"has_ferry": false,
"min_lat": 13.029259,
"min_lon": 80.263792,
"max_lat": 13.0357,
"max_lon": 80.268026,
"time": 253.396,
"length": 1.87,
"cost": 473.711
},
"shape": "gjszWiacbxCbGtDvSpMlZbUdDlG`NtYzGb_@jF~Q`Q|`@hD`FpS~YhCfCtC}DdI{HnBoCrJ~If]dAhTdArRTjACrJl@b\\fBrhBbQ`B}PXuKb@wVV_NLaGXsHLkZ@_ArAi]j@oT}u@gKqc@cEsZaDiD_@yMeCcJcDq`Aa^{AsDeBiBg~@sLoZiEuFy@eE[wCAcA@wAFsElCsKx@"
}
],
"summary": {
"has_time_restrictions": false,
"has_toll": false,
"has_highway": false,
"has_ferry": false,
"min_lat": 13.029259,
"min_lon": 80.25148,
"max_lat": 13.036045,
"max_lon": 80.268026,
"time": 549.848,
"length": 4.36,
"cost": 1762.634
},
"status_message": "Found route between points",
"status": 0,
"units": "kilometers",
"language": "en-US"
}
}
| Field | Type | Description |
|---|---|---|
trip | object | |
trip.locations | array | Stops in the optimized visiting order. |
trip.locations[] | object | |
trip.locations[].type | string | |
trip.locations[].lat | number | |
trip.locations[].lon | number | |
trip.locations[].side_of_street | string | Side of the street the stop is on. |
trip.locations[].original_index | integer | Position of this stop in your request - use it to map the new order back to your input. |
trip.legs | array | One leg between each pair of consecutive stops. |
trip.legs[] | object | |
trip.legs[].maneuvers | array | Turn-by-turn instructions for the leg. |
trip.legs[].maneuvers[] | object | |
trip.legs[].maneuvers[].type | integer | |
trip.legs[].maneuvers[].instruction | string | Human-readable instruction. |
trip.legs[].maneuvers[].verbal_succinct_transition_instruction | string | |
trip.legs[].maneuvers[].verbal_pre_transition_instruction | string | |
trip.legs[].maneuvers[].verbal_post_transition_instruction | string | |
trip.legs[].maneuvers[].street_names | array | |
trip.legs[].maneuvers[].street_names[] | string | |
trip.legs[].maneuvers[].time | number | Time for this maneuver, seconds. |
trip.legs[].maneuvers[].length | number | Length of this maneuver, in units. |
trip.legs[].maneuvers[].cost | number | |
trip.legs[].maneuvers[].begin_shape_index | integer | |
trip.legs[].maneuvers[].end_shape_index | integer | |
trip.legs[].maneuvers[].travel_mode | string | |
trip.legs[].maneuvers[].travel_type | string | |
trip.legs[].summary | object | |
trip.legs[].summary.has_time_restrictions | boolean | |
trip.legs[].summary.has_toll | boolean | |
trip.legs[].summary.has_highway | boolean | |
trip.legs[].summary.has_ferry | boolean | |
trip.legs[].summary.min_lat | number | |
trip.legs[].summary.min_lon | number | |
trip.legs[].summary.max_lat | number | |
trip.legs[].summary.max_lon | number | |
trip.legs[].summary.time | number | Leg travel time, seconds. |
trip.legs[].summary.length | number | Leg length, in units. |
trip.legs[].summary.cost | number | |
trip.legs[].shape | string | Leg geometry as an encoded polyline. |
trip.summary | object | |
trip.summary.has_time_restrictions | boolean | |
trip.summary.has_toll | boolean | true when the route uses a toll road. |
trip.summary.has_highway | boolean | true when the route uses a highway. |
trip.summary.has_ferry | boolean | true when the route uses a ferry. |
trip.summary.min_lat | number | |
trip.summary.min_lon | number | |
trip.summary.max_lat | number | |
trip.summary.max_lon | number | |
trip.summary.time | number | Total travel time, seconds. |
trip.summary.length | number | Total length, in units. |
trip.summary.cost | number | |
trip.status_message | string | Result message. |
trip.status | integer | 0 when a route was found. |
trip.units | string | Distance unit used in the response. |
trip.language | string | Language of the instructions. |
Example
curl -X POST 'https://api-gw.sovereignsolutions.com/gateway/routing/optimize?api-key=$API_KEY' \
-H 'Content-Type: application/json' \
-d '{"locations": [{"lon": 80.2675007, "lat": 13.0355685}, {"lon": 80.267291, "lat": 13.036289}, {"lon": 80.267437, "lat": 13.03525}, {"lon": 80.267779, "lat": 13.034928}, {"lon": 80.251724, "lat": 13.032119}], "costing": "auto", "units": "km"}'
Notes
The example response is shortened to the first leg; a real response has one leg between each pair of consecutive stops.