The Nextmv routing app is a pre-built, feature-rich routing application built on the Nextmv router
engine. This reference includes the API specification and input and output schemas.
A demo of the Nextmv routing app is available via the console. Note, some defaults or options may differ from the API (see the input schema below). You can navigate to the demo page after logging in to your Nextmv account.
API Key
Your Nextmv API key can be copied from under your account profile after logging in to the Nextmv Cloud console.
Endpoints
Nextmv Cloud API provides you with endpoints to run a model, check the status of your run, get the results of a run, and configure runs and integrations.
Note, all requests must be authenticated with Bearer Authentication. Make sure your request has a header containing your Nextmv Cloud API key, as such:
- Key:
Authorization
- Value:
Bearer <YOUR-API-KEY>
Run
Create a new run.
Request a new run to the Nextmv Cloud API. You can use a `run_profile` to specify configurations and integrations that do not vary run to run. Use the `profiles` endpoints to create and manage run profiles.
Get a run status.
Poll the status of the run requested with the `/v0/run` endpoint, using the `run_id` obtained. If the status is `succeeded`, it means that the solution can be queried using the `/v0/run/{run_id}/result` endpoint.
Get the result of the run.
Get the result of the run requested with the `/v0/run` endpoint, using the `run_id` obtained. The solution can be found under the `state` key.
Configurations
Create a new run profile.
Create a new run profile that can be used when executing runs using the `v0/run` endpoint. A run profile is used to configure options that do not vary run to run. Different run profiles may be created to fulfill distinct run configurations. A run profile uses one or more third-party integrations for enhanced functionality such as using traffic data.
List all run profiles.
List the existing run profiles.
Get a specific run profile.
Fetch a specific run profile.
Modify a run profile.
Modify an existing run profile.
Delete a run profile.
Delete an existing run profile.
List all third-party run profile integrations.
List the existing third-party integrations that can be used with a run profile. Integrations enhance the functionality of the Nextmv Cloud API.
Onfleet integration
Create a new Onfleet integration.
Create a new Onfleet integration. Onfleet is the source of the truth for tasks (stops) and workers (vehicles). Entities are fetched from the Onfleet API and containers (assignments) are created for the user to upload them to the Onfleet API. Use the `id` of the integration to manage it (using the `GET`, `PUT` and `DELETE` endpoints that follow).
Get an existing Onfleet integration.
Get an existing Onfleet integration using the `id` associated with it.
Modify an existing Onfleet integration.
Modify an existing Onfleet integration using the `id` associated with it.
Delete an existing Onfleet integration.
Delete an existing Onfleet integration using the `id` associated with it.
Create a new run specific for Onfleet tasks and workers.
Request a new run to the Nextmv Cloud API, specific for Onfleet tasks and workers. Similar to the `v0/run` endpoint, you will obtain a `run_id` that you can use to query your status and results using the `v0/status` and `v0/result` endpoints, respectively. Make sure that you have an existing Onfleet integration configured and a run profile that uses that integration. The tasks and workers that are referenced must exist in the Onfleet API.
HERE integration
Create a new HERE integration.
Create a new HERE integration. HERE is a mapping provider offering street data to estimate the distance and duration of going from A to B. HERE has the possibility to incorporate real-time or historical traffic data in their estimations.
Get an existing HERE integration.
Get an existing HERE integration using the `id` associated with it.
Modify an existing HERE integration.
Modify an existing HERE integration using the `id` associated with it.
Delete an existing HERE integration.
Delete an existing HERE integration using the `id` associated with it.
Streets integration
Create a new Streets integration.
Create a new Streets integration. The integration uses Open Street Map (OSM) road network to estimate the distance of going from A to B. It relies on an OSRM (Open Source Routing Machine) server.
Get an existing Streets integration.
Get an existing Streets integration using the `id` associated with it.
Modify an existing Streets integration.
Modify an existing Streets integration using the `id` associated with it.
Delete an existing Streets integration.
Delete an existing Streets integration using the `id` associated with it.
Input schema
The input schema is a JSON payload defining the vehicles, stops, and options for a given routing problem. Nextmv's tools are designed to operate directly on business data (in JSON
) to produce decisions that are actionable by software systems. This makes decisions more interpretable and easier to test. It also makes integration with data warehouses and business intelligence platforms significantly easier. An input contains the following components:
Property | Required | Field name | Type | Description |
---|---|---|---|---|
Vehicles | Yes | vehicles | array of object | Vehicles to route. |
Stops | Yes | stops | array of object | Stops that will be routed and assigned to the vehicles. |
Run profile | No | run_profile | object | Profile for configurations that do not vary run to run. |
Options | No | options | object | Options to configure the solver. |
Defaults | No | defaults | object | Default properties for vehicles and stops. |
Stop groups | No | stop_groups | array of array of string | Group of stops that must be part of the same route. |
Alternate stops | No | alternate_stops | array of object | Alternate locations that a vehicle can visit. |
Duration groups | No | duration_groups | array of object | Group of stops that add an overall service time. |
A sample input is provided below.
Vehicles
vehicles
define all vehicles in a fleet. Available vehicle property fields and type requirements are detailed in the table below. Besides being a mandatory field, the id
must be unique. Except for id
, required fields can be set as defaults instead of being set for each vehicle.
Note, the field alternate_stops
references stops by ID in the alternate_stops
object, not the stops
object.
Property | Required | Field name | Type | Example |
---|---|---|---|---|
Name / identifier | Yes | id | string | "id": "vehicle-1" |
Average speed | Yes | speed | float [meters/second] | "speed": 25 |
Shift start | Yes | shift_start | timestamp | "shift_start": "2021-10-17T09:00:00-06:00" |
Shift end | No | shift_end | timestamp | "shift_end": "2021-10-17T11:00:00-06:00" |
Starting position | No | start | object | "start": { "lon":-96.659222, "lat": 33.122746 } |
Ending position | No | end | object | "end": { "lon": -96.659222, "lat": 33.122746 } |
Carrying capacity | No | capacity | object or int | "capacity": { "weight": 500 } or "capacity": 500 |
Compatibility attributes | No | compatibility_attributes | array of string | "compatibility_attributes": ["refrigerated"] |
Max stops | No | max_stops | int | "max_stops": 1 |
Max distance | No | max_distance | int [meters] | "max_distance": 50000 |
Max duration | No | max_duration | int [seconds] | "max_duration": 3600 |
Stop duration multiplier | No | stop_duration_multiplier | float | "stop_duration_multiplier": 1.2 |
Backlog | No | backlog | array of string | "backlog": ["location-1"] |
Alternate stops | No | alternate_stops | array of string | "alternate_stops": ["as-1"] |
Initialization cost | No | initialization_cost | int | "initialization_cost": 34000 |
Here is an example of vehicles
:
Stops
stops
define all stops (or requests) that are candidates for assignment. Just like id
for vehicles, id
for stops must be unique. Available stop property fields and type requirements are detailed in the table below.
Property | Required | Field name | Type | Example |
---|---|---|---|---|
Name / identifier | Yes | id | string | "id": "order-1-pickup" |
Stop location | Yes | position | object | "position": { "lon": -96.827094, "lat": 33.004745 } |
Stop duration | No | stop_duration | int [seconds] | "stop_duration": 120 |
Quantity picked up (-) or dropped off (+) | No | quantity | object or int | "quantity": { "weight": -50 } or "quantity": -50 |
Target time | No | target_time | timestamp | "target_time": "2021-10-17T09:45:00-06:00" |
Hard window | No | hard_window | array of timestamp | "hard_window": [ "2021-10-17T09:00:00-06:00", "2021-10-17T10:00:00-06:00" ] |
Max wait time | No | max_wait | int [seconds] | "max_wait": 900 |
Penalty for being early | No | earliness_penalty | float | "earliness_penalty": 2 |
Penalty for being late | No | lateness_penalty | float | "lateness_penalty": 5 |
Penalty for not visiting | No | unassigned_penalty | int | "unassigned_penalty": 200000 |
Precedence - visit before | No | precedes | array of string or string | "precedes": ["order-1-drop", "order-2-drop"] or "precedes": "order-1-drop" |
Precedence - visit after | No | succeeds | array of string or string | "succeeds": ["order-1-drop", "order-2-drop"] or "succeeds": "order-1-drop" |
Compatibility attributes | No | compatibility_attributes | array of array of string | "compatibility_attributes": ["refrigerated"] |
Here is an example of stops
:
Run profile
run_profile
is a single JSON
object with an id
attribute specifying a previously configured run profile. Settings for the profile are merged with the input for the run. Additional integration-specific fields may be added to the run profile. Please note that third-party integrations are configured as part of a run profile. For more information on available integrations, please contact support.
Property | Required | Field name | Type | Example |
---|---|---|---|---|
Name / identifier | Yes | id | string | "id": "<MY-RUN-PROFILE-ID>" |
Here is an example of a run_profile
:
Options
Solver options
can also be added to the input file. Note, in the Nextmv Cloud console, options added to an input file will override options configured using the graphical user interface (e.g., a duration specified in an input file will override a duration set using the runtime slider). Available option fields and type requirements are detailed in the table below.
Property | Required | Field name | Type | Example | Default (limits) | Description |
---|---|---|---|---|---|---|
Time limit | No | duration | string | "solver": { "limits": { "duration": "5s" } } | API: 3s (600s limit); Console: 3s (30s limit) | The length of time a solver must run. |
Solution limit | No | solutions | int | "solver": { "limits": { "solutions": 1 } } | model.MaxInt | The number of feasible solutions that must be found before stopping or reaching a time limit if specified. |
Node limit | No | nodes | int | "solver": { "limits": { "nodes": 10 } } | model.MaxInt | The number of nodes that must be generated before stopping or reaching a time limit if specified. |
Diagram expansion limit | No | expansion | int | "solver": { "diagram": { "expansion": { "limit": 1 } } | 1 | The number of child nodes to generate on each pass. |
Here is an example of custom options
:
Defaults
defaults
apply default properties to all vehicles, stops and alternate stops. Properties added to specific vehicles or stops override the default settings (see vehicles and stops). Here is an example of using defaults
.
Stop groups
stop_groups
define a list of stops to be grouped together. Each group must consist of at least 2 stops, given by their IDs. Here is an example of using stop_groups
:
Alternate stops
alternate_stops
defines a list of stops. An alternate stop can be referenced by a vehicle by using the alternate_stops
property. In addition to the stops already assigned to the vehicle, one alternate stop will be assigned from all referenced alternate stops. An alternate stop has the same fields as a normal stop. Here is an example of using alternate_stops
:
Duration groups
duration_groups
define groups of stops that would take on an additional duration cost if any stop in the group is approached from a location outside of it. Any individual stop durations will be applied as usual. Two fields are required for each duration group: group
and duration
. A location must not be repeated within a group and must not be part of several groups. The table below defines the schema for a duration group.
Property | Required | Field name | Type | Example |
---|---|---|---|---|
Stop group | Yes | group | array of string | "group": ["location-1"] |
Duration | Yes | duration | int [seconds] | "duration": 120 |
Here is an example of using duration_groups
:
Output schema
The output schema defines the solution to the routing problem, in addition to the options that were used and summary statistics, all in JSON
format. The output schema contains the following components.
Property | Field name | Type | Description |
---|---|---|---|
Hop version | hop | string | The version of the Nextmv solver (Hop ) used. |
Options | options | object | The options defined in the input file and used by the solver. |
Solution | state | object | The solution to the problem. |
Statistics | statistics | object | Summary statistics of the search for the best solution. |
Here, we focus on the state
object containing a solution. The state
contains the following components:
Property | Field name | Type | Description |
---|---|---|---|
Vehicles' solution | vehicles | array of object | Vehicles with assigned routes. |
Unassigned stops | unassigned | array of object | Stops not assigned to any vehicle (if any). |
Value summary | value_summary | object | Breakdown of a vehicle's solution. |
A sample output.json
is provided below.
Vehicles output
The vehicles
key contains the route per vehicle and different fields with statistics for that vehicle. The components of a vehicle's solution are described in the following table.
Property | Field name | Type | Example | Description |
---|---|---|---|---|
Name / identifier | id | string | "id": "vehicle-1" | ID of the vehicle. |
Value | value | int | "value": 5745 | Costs associated with this vehicle. |
Total travel distance | travel_distance | float [meters] | "travel_distance": 51450.103837858944 | Total distance traveled by this vehicle. |
Total travel time | travel_time | float [seconds] | "travel_time": 5745.074947478 | Total travel time for this vehicle. |
Initialization cost | vehicle_initialization_costs | int | "vehicle_initialization_costs": 0 | The one-time costs that are applied for using this vehicle. |
Polyline | polyline | string | "polyline": "??gotiEjpomQ??fotiEkpomQ" | A polyline from start to end encoded in Google's polyline format. |
Route | route | array of object | "route": {"id":"location-1", "lon": -96.7503, "lat": 33.2058 "distance": 12542.225,"eta": "2022-02-22T09:20:54:06-00","ets": "2022-02-22T09:20:54:06-00"}, {...}, ...] | The vehicle's route with stops and additional stop information. |
The components for a vehicle's route
are described in the following table.
Property | Field name | Type | Example | Description |
---|---|---|---|---|
Name / identifier | id | string | "id": "location-1" | ID of the stop. |
Longitude | lon | float | "lon": -96.659222 | Longitude of the stop. |
Latitude | lat | float | "lat": 33.122746 | Latitude of the stop. |
Accumulated distance | distance | float [meters] | "distance": 0 | Total route distance up to this stop. |
Polyline | polyline | string | "polyline": "styrFv~xiM??" | A polyline from this stop to the next stop, encoded in Google's polyline format. |
Estimated time of arrival | eta | timestamp | "eta": "2021-10-17T09:00:00-06:00" | Estimated time at which the vehicle will arrive at this stop. |
Estimated time of departure | etd | timestamp | "etd": "2021-10-17T09:00:00-06:00" | Estimated time at which the vehicle will depart from this stop. |
Estimated time of service | ets | timestamp | "ets": "2021-10-17T09:00:00-06:00" | When using time windows there are potential wait times when arriving before the window opens. This is the estimated time at which service at the stop starts. |
Here is an example of the solution for a vehicle.
Unassigned output
The unassigned
key holds an array of unassigned stops (objects). Each unassigned stop has the following fields:
Property | Field name | Type | Example |
---|---|---|---|
Name / identifier | id | string | "id": "location-1" |
Longitude | lon | float | "lon": -96.659222 |
Latitude | lat | float | "lat": 33.122746 |
Here is an example of how unassigned
stops look like in the output.
Summary output
The value_summary
key holds summary statistics of the overall solution, like the total distance traveled and the value of the solution. The components of the value summary are described below.
Property | Field name | Type | Example |
---|---|---|---|
Value | value | int | "value": 211264 |
Total travel distance | total_travel_distance | float [meters] | "total_travel_distance": 101843.988 |
Total travel time | total_travel_time | float [seconds] | "total_travel_time": 11265.113 |
Total earliness penalty | total_earliness_penalty | float [seconds] | "total_earliness_penalty": 0 |
Total lateness penalty | total_lateness_penalty | float [seconds] | "total_lateness_penalty": 0 |
Total unassigned penalty | total_unassigned_penalty | int [seconds] | "total_unassigned_penalty": 200000 |
Total vehicle initialization costs | total_vehicle_initialization_costs | int [seconds] | "total_vehicle_initialization_costs": 0 |
Here is an example of how the value_summary
looks like in the output.
Statistics
This section details the schema in the statistics
object for each solution returned by the solver.
Property | Field name | Type | Description |
---|---|---|---|
Solution bounds | bounds | object | Bounds for the value of the solution. |
Solution state exploration | search | object | Summary of the solver's search mechanism. |
Solution time statistics | time | object | Time it took for the solver to find the solution. |
Solution value | value | int | Total value of the solution. |
The bounds
key follows the schema described below.
Property | Field name | Type | Description |
---|---|---|---|
Lower bound | lower | int | Lower bound of the solution. |
Upper bound | upper | int | Upper bound of the solution. |
In cases where the Nextmv solver is maximizing or minimizing an objective, the upper
and lower
bounds are continuously updated after generating a new state.
- If the bounds are the same in value, Nextmv solver has mathematically proven optimality of its best solution.
- When bounds are not the same value, Nextmv solver terminated early while searching the state space proving optimality. In that case, Nextmv solver will return the best solution found to date.
The search
object shows the solver's search mechanism, which is a state exploration. It projects states forward from the root state to determine what decisions you should make. Every transition in that search produces a new state which is then explored. Each of these categories contain both feasible and infeasible states.
Property | Field name | Type | Description |
---|---|---|---|
Generated states | generated | int | All of the states the solver created. |
Filtered states | filtered | int | All states that have been removed from the search because they have been bounded out. The solver has determined that it cannot, from a certain set of solutions, produce a solution that will be better than the best solution found so far. |
Expanded states | expanded | int | All states that are not 'Filtered' |
Reduced states | reduced | int | States that have been removed from the search because a 'Reducer' determined that no states directly dominate them. |
Deferred states | deferred | int | States that have not been deferred and will be investigated immediately. |
Restricted states | restricted | int | States saved for later exploration. This is how the solver manages an explosion of the state space. It will explore the most fruitful options first, then defer the others. |
Explored states | explored | int | All states that have been fully explored. Explored states cannot produce more child states. |
Total solutions | solutions | int | Number of solutions that the solver has found thus far. |
Lastly, the time
object shows the time it took for the solver to find the solution shown.
Property | Field name | Type | Description |
---|---|---|---|
Elapsed time | elapsed | string | Human-readable elapsed time to find the solution. |
Elapsed seconds | elapsed_seconds | float | Total seconds to find the solution. |
Run start time | start | timestamp | Timestamp indicating when the search began. |
Below is an example of output statistics for a solver result.
Onfleet integration input schema
The input schema for the Onfleet integration is a JSON
payload that has the following keys:
Key | Description | Required | Type |
---|---|---|---|
routing | Options to customize the routing configurations. | Yes | object |
onfleet | Specification of tasks and workers to route. | Yes | object |
A sample input is provided as a .json
file.
Routing options
The routing options is an object that has the following keys:
Key | Description | Required | Type |
---|---|---|---|
run_profile | Object to select the run profile id you want to use. | Yes | object |
options | Select the solver options that you want to use. | No | object |
defaults | Specify the default override attributes for stops and vehicles. | No | object |
A sample routing
object is provided as part of the input schema below.
Onfleet specification
The Onfleet specification is an object that has the following keys:
Key | Description | Required | Type |
---|---|---|---|
tasks | Object to specify the tasks you want to route. | Yes | object |
workers | Object to specify the workers you want to route. | Yes | object |
stop_groups | Array to specify custom stop groups for the routes. | No | array of array of string |
alternate_stops | Array of task IDs that are considered alternate stops. | No | array of string |
duration_groups | Group of stops that add an overall service time | No | array of object |
- Use of alternate stops with Onfleet does involve additional steps to assure that exactly 1 alternate stop is assigned per vehicle's route. When using
alternate_stops
it is mandatory to create thealternate_stops
as tasks per worker in Onfleet before calling the Nextmv API. E.g., if you have two locations that arealternate_stops
and you have 5 workers, you need to create 2*5=10 tasks. You can then call the Nextmv API. Once you have the Nextmv results with the calculated routes, the unusedalternate_stops
need to be deleted from Onfleet. This can be done by looping over the routes and identifying whichalternate_stops
appear there. Thealternate_stops
that are not found in the routes should be removed from Onfleet and the containers can be updated.
The tasks
object is composed of the following keys:
Key | Description | Required | Sample value | Type |
---|---|---|---|---|
ids | List of IDs to fetch from the Onfleet API and perform the routing. | Yes | [ "zntJ8QG5LPBK9mMea6zWN0lB", "cisx30t05*kQQiKYQhgyTmVF" ] | array of string |
params | Object to specify the query parameters when fetching tasks. | Yes | { "from": 1641963600000 } | object |
- When using
stop_groups
, please include the list of task IDs in both the list oftask
ids
and the list of IDs in a group insidestop_groups
. - Please include the IDs of alternate stops in both the list of
task
ids
and the list ofalternate_stops
. This is handled differently than in the original alternate stops feature, where alternate stops are only specified under thealternate_stops
key but not understops
. Keep in mind thatalternate_stops
are specified only using task IDs, not a stop object.
The tasks
params
object specifies most query parameters used in the Onfleet list tasks endpoint. This endpoint is used in the backend to search for the given task ids
. All the query parameters should be specified using snake_case
.
The lastId
query parameter is not provided, as the pagination is done automatically by the Nextmv Cloud API. Please note that there is a limit to the number of pages that are walked over. If the page limit is reached and there are tasks that haven't been found, an error will be returned in the /v0/run/run_id/status
endpoint.
We recommend using the query parameters to fine-tune the search of the desired tasks. The params
object is composed of the following keys:
Key | Description | Required | Sample value | Type |
---|---|---|---|---|
from | The starting time of the range. Tasks created or completed at or after this time will be included. | Yes | 1641963600000 | int |
to | If missing, defaults to the current time. The ending time of the range. Tasks created or completed before this time will be included. | No | 1641963600000 | int |
state | A comma-separated list of task states. | No | "0,1" | string |
worker | The ID of a worker who is currently assigned to the tasks or has previously completed the tasks. | No | "aWXnPY3NjKSOdisBihX8QPsL" | string |
complete_before_before | The timestamp before which the task completeBefore value must be. | No | 1641963600000 | int |
complete_after_after | The timestamp after which the task completeAfter value must be. | No | 1641963600000 | int |
dependencies | A comma-separated list of dependency task ids. A task gets returned in the response if it has at least one of the dependencies provided. | No | "zntJ8QG5LPBK9mMea6zWN0lB,cisx30t05*kQQiKYQhgyTmVF" | string |
The workers
object is composed of the following keys:
Key | Description | Required | Sample value | Type |
---|---|---|---|---|
ids | List of IDs to fetch from the Onfleet API and perform the routing. | Yes | [ "aWXnPY3NjKSOdisBihX8QPsL" ] | array of string |
params | Object to specify the query parameters when fetching workers. | No | { "states": "0,1" } | object |
The workers
params
object specifies most query parameters used in the Onfleet list workers endpoint. This endpoint is used in the backend to search for the given worker ids
.
We recommend using the query parameters to fine-tune the search of the desired workers. The params
object is composed of the following keys:
Key | Description | Required | Sample value | Type |
---|---|---|---|---|
filter | A comma-separated list of fields to return, if all are not desired. For example, name, location. | No | "name,location" | string |
teams | A comma-separated list of the team IDs that workers must be part of. | No | "aWXnPY3NjKSOdisBihX8QPsL" | string |
states | A comma-separated list of worker states, where 0 is off-duty, 1 is idle (on-duty, no active task) and 2 is active (on-duty, active task). | No | "0,1" | string |
phones | A comma-separated list of workers' phone numbers. | No | "9055555555" | string |
Onfleet integration output schema
The output schema is a JSON
response that has the following keys:
Key | Description | Type |
---|---|---|
workers | List of worker objects fetched from the Onfleet API. | array of object |
tasks | List of task objects fetched from the Onfleet API. | array of object |
containers | List of containers specifying the final assignments. You can use this information to update the containers using the Onfleet API. | array of object |
solution | Nexmtv Cloud output schema with solution. | object |
input | Parsed Nexmtv Cloud input schema used to run the optimization. Showcases the transformations of tasks to stops and workers to vehicles | object |
A sample output response obtained after running the sample input is provided below.