Overview
TSP API allows you to solve the traveling salesman problem (TSP/VRP) - building the shortest route in time or distance to pass through the specified points. You can specify one or several couriers to visit the points. If several couriers are used, the route will be divided between them in the most optimal way (some couriers can be excluded if using fewer couriers is more optimal for the task).
You can specify up to 4000 points and up to 200 couriers for a route.
Getting an access key
-
Sign in to the Platform Manager.
-
Create a demo key or purchase a subscription for using API. For details on service prices, see the Tariffs section.
For more information on working with access keys and subscriptions, see the account documentation.
Task example
Deliver cargo from a depot to three different points with the following conditions:
- one courier is used with a capacity of up to 2000 kg
- 800 kg of cargo need to be delivered to each point
- the courier starts and finishes at the depot
- the depot and all points are available for visiting from 7:00 AM to 3:00 PM
Points to visit are displayed on the map. To see parameters of each point, hover over a corresponding marker.
TSP API solves the traveling salesman problem asynchronously. To build a route (an order of passing points):
- Send a request to create a route building task.
- Periodically check the status of the task until the route calculation is complete.
- Get the calculated route when the task is complete.
For more details on parameters from the requests below, see the API Reference.
TSP API finds the most optimal order of passing the given points considering all road situation features. To get a detailed driving or walking route, use Routing API after getting a solution from TSP API.
1. Creating a task
To create a task, send a POST request to the /logistics/vrp/2.0.0/create endpoint. Specify your API key as the key parameter in the query string:
https://routing.api.2gis.com/logistics/vrp/2.0.0/create?key=API_KEY
Send route point coordinates, number of couriers, and other parameters as a JSON string in the request body. For example, to define conditions from the task example:
-
List all points to visit in the
waypointsarray and specify their parameters:id(required): point identifierpoint(required): point coordinates (lat,lon) and position relative to the road (type)type: point type (delivery,pickup, oragent)service_duration_s: courier's service time at the point (in seconds)depot_ids: array of identifiers of depots from which the couriers can pick up orderstime_windows: time windowsshipment_size: cargo size
{
"waypoints": [
{
"id": "1",
"point": { "lat": 55.708272, "lon": 37.46326, "type": "stop" },
"type": "delivery",
"service_duration_s": 0,
"depot_ids": ["0"],
"time_windows": [
{
"time_window": "07:00-15:00",
"hard_time_window": "07:00-15:00"
}
],
"shipment_size": { "weight_kg": 800 }
}
]
}
-
List the couriers in the
agentsarray and specify their parameters:id(required): courier identifiercapacity: courier carrying capacitytravel_time_multiplier: travel speed multipliercost: courier coststart_at: identifier of the depot where the courier starts the routefinish_at: identifier of the depot where the courier finishes the route
{
"agents": [
{
"id": "1",
"capacity": { "weight_kg": 2000 },
"travel_time_multiplier": 1.0,
"cost": {
"fixed": 3000,
"hour": 100,
"km": 8
},
"start_at": "0",
"finish_at": "0"
}
]
} -
(Optional) List the depots in the
depotsarray:id: depot identifierpoint: depot coordinates and typeservice_duration_s: service time at the depottime_window: depot operating time window (time_window,hard_time_window)
{
"depots": [
{
"id": "0",
"point": {
"lat": 55.734157,
"lon": 37.589346,
"type": "stop"
},
"service_duration_s": 0,
"time_window": {
"time_window": "07:00-15:00",
"hard_time_window": "07:00-15:00"
}
}
]
} -
(Optional) Specify route parameters in the
optionsobject:route_type: route type (e.g.,"jam"with traffic jams considered)routing_type: transportation type (e.g.,"driving")date: route date inYYYY-MM-DDformattime_zone: time zone (e.g.,"Europe/Moscow")solver_time_limit_s: timeout for solving the task (in seconds)need_altitudes: whether to consider altitudes (trueorfalse)
{
"options": {
"route_type": "jam",
"routing_type": "driving",
"date": "2021-02-19",
"time_zone": "Europe/Moscow",
"solver_time_limit_s": 60,
"need_altitudes": false
}
}
Request example
curl --location --request POST 'https://routing.api.2gis.com/logistics/vrp/2.0.0/create?key=API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"waypoints": [
{
"id": "1",
"point": {
"lat": 55.708272,
"lon": 37.46326,
"type": "stop"
},
"type": "delivery",
"service_duration_s": 0,
"depot_ids": [
"0"
],
"time_windows": [
{
"time_window": "07:00-15:00",
"hard_time_window": "07:00-15:00"
}
],
"shipment_size": {
"weight_kg": 800
}
},
{
"id": "2",
"point": {
"lat": 55.705352,
"lon": 37.461495,
"type": "stop"
},
"type": "delivery",
"service_duration_s": 0,
"depot_ids": [
"0"
],
"time_windows": [
{
"time_window": "07:00-15:00",
"hard_time_window": "07:00-15:00"
}
],
"shipment_size": {
"weight_kg": 800
}
},
{
"id": "3",
"point": {
"lat": 55.704175,
"lon": 37.471526,
"type": "stop"
},
"type": "delivery",
"service_duration_s": 0,
"depot_ids": [
"0"
],
"time_windows": [
{
"time_window": "07:00-15:00",
"hard_time_window": "07:00-15:00"
}
],
"shipment_size": {
"weight_kg": 800
}
}
],
"agents": [
{
"id": "1",
"capacity": {
"weight_kg": 2000
},
"travel_time_multiplier": 1.0,
"cost": {
"fixed": 3000,
"hour": 100,
"km": 8
},
"start_at": "0",
"finish_at": "0"
}
],
"depots": [
{
"id": "0",
"point": {
"lat": 55.734157,
"lon": 37.589346,
"type": "stop"
},
"service_duration_s": 0,
"time_window": {
"time_window": "07:00-15:00",
"hard_time_window": "07:00-15:00"
}
}
],
"options": {
"route_type": "jam",
"routing_type": "driving",
"date": "2021-02-19",
"time_zone": "Europe/Moscow",
"solver_time_limit_s": 60,
"need_altitudes": false
}
}'
The request returns information about the created task, including the task identifier (task_id), which is used to check the task status:
{
"task_id": "dcabb3f6188935187d54088556238b83",
"status": {
"status": "Run",
"queued": "2026-04-20T11:44:14.906+00:00",
"started": null,
"matrix_downloaded": null,
"calculated": null,
"completed": null
},
"result": null
}
Limitations
The request will not be executed if:
- the agent's starting or ending point has been excluded
- the request execution time is not included in the working hours of the agents
2. Checking task status
To check the status of the task, send a GET request to the /logistics/vrp/2.0.0/status endpoint. Specify two parameters in the query string:
task_id- task IDkey- your API key
curl --location --request GET 'https://routing.api.2gis.com/logistics/vrp/2.0.0/status?task_id=dcabb3f6188935187d54088556238b83&key=API_KEY'
If the task is still being processed, the request will return the same response as when the task was initially created (the status field will contain the value "Run"):
{
"task_id": "dcabb3f6188935187d54088556238b83",
"status": {
"status": "Run",
"queued": "2026-04-20T11:44:14.906+00:00",
"started": null,
"matrix_downloaded": null,
"calculated": null,
"completed": null
},
"result": null
}
If the task is completed, the response body will contain the following data:
-
status: one of the following values:Done- the route was successfully built.Partial- the route was built, but points or agents were excluded from it.Fail- an error occurred when building the route.
-
queued: time the task was placed in the queue in ISO 8601 format. -
started: time the processing started. -
matrix_downloaded: time the reachability matrix download was completed (distances and travel times between all possible pairs of points in the task). -
calculated: time the calculation was completed. -
completed: time the task was completed.
{
"task_id": "dcabb3f6188935187d54088556238b83",
"status": {
"status": "Done",
"queued": "2026-04-20T11:44:14.906+00:00",
"started": "2026-04-20T11:44:14.906+00:00",
"matrix_downloaded": "2026-04-20T11:44:15.094+00:00",
"calculated": "2026-04-20T11:44:15.144+00:00",
"completed": "2026-04-20T11:44:15.144+00:00"
}
}
3. Getting task results
The task solution is contained in the result.metrics and result.routes objects. Excluded points and couriers are contained in the result.dropped_waypoints and result.dropped_agents fields.
Response example
{
"result": {
"metrics": {
"number_of_routes": 2,
"used_agents": 1,
"dropped_waypoints_count": 0,
"max_agent_runs": 2,
"total_duration_s": 3897,
"total_service_duration_s": 0,
"total_early_count": 0,
"total_early_duration_s": 0,
"total_distance_m": 55501
},
"options": {
"routing_type": "driving",
"route_type": "jam",
"date": "2021-02-19",
"time_zone": "Europe/Moscow",
"need_altitudes": false,
"solver_time_limit_s": 60
},
"routes": [
{
"agent_id": "1",
"run_number": 0,
"duration_s": 931,
"distance_m": 13606,
"route": [
{
"arrival_time": "2021-02-19T07:00:00+03:00",
"departure_time": "2021-02-19T07:00:00+03:00",
"node": {
"type": "depot",
"value": { "depot_id": "0", "delivery_to": "2" }
},
"service_start_time": "2021-02-19T07:00:00+03:00",
"waiting_duration_s": 0,
"transit_duration_s": 0,
"transit_distance_m": 0
},
{
"arrival_time": "2021-02-19T07:00:00+03:00",
"departure_time": "2021-02-19T07:00:00+03:00",
"node": {
"type": "depot",
"value": { "depot_id": "0", "delivery_to": "1" }
},
"service_start_time": "2021-02-19T07:00:00+03:00",
"waiting_duration_s": 0,
"transit_duration_s": 0,
"transit_distance_m": 0
},
{
"arrival_time": "2021-02-19T07:15:31+03:00",
"departure_time": "2021-02-19T07:15:31+03:00",
"node": {
"type": "waypoint",
"value": { "waypoint_id": "1", "picked_up_from": "0" }
},
"service_start_time": "2021-02-19T07:15:31+03:00",
"waiting_duration_s": 0,
"transit_duration_s": 931,
"transit_distance_m": 13606
}
]
},
{
"agent_id": "1",
"run_number": 1,
"duration_s": 2966,
"distance_m": 41895,
"route": [
{
"arrival_time": "2021-02-19T07:30:16+03:00",
"departure_time": "2021-02-19T07:30:16+03:00",
"node": {
"type": "depot",
"value": { "depot_id": "0", "delivery_to": "3" }
},
"service_start_time": "2021-02-19T07:30:16+03:00",
"waiting_duration_s": 0,
"transit_duration_s": 885,
"transit_distance_m": 13546
},
{
"arrival_time": "2021-02-19T07:46:12+03:00",
"departure_time": "2021-02-19T07:46:12+03:00",
"node": {
"type": "waypoint",
"value": { "waypoint_id": "3", "picked_up_from": "0" }
},
"service_start_time": "2021-02-19T07:46:12+03:00",
"waiting_duration_s": 0,
"transit_duration_s": 956,
"transit_distance_m": 13441
},
{
"arrival_time": "2021-02-19T07:49:48+03:00",
"departure_time": "2021-02-19T07:49:48+03:00",
"node": {
"type": "waypoint",
"value": { "waypoint_id": "2", "picked_up_from": "0" }
},
"service_start_time": "2021-02-19T07:49:48+03:00",
"waiting_duration_s": 0,
"transit_duration_s": 216,
"transit_distance_m": 1376
},
{
"arrival_time": "2021-02-19T08:04:57+03:00",
"departure_time": "2021-02-19T08:04:57+03:00",
"node": {
"type": "agent",
"value": { "waypoint_id": "0" }
},
"service_start_time": "2021-02-19T08:04:57+03:00",
"waiting_duration_s": 0,
"transit_duration_s": 909,
"transit_distance_m": 13532
}
]
}
],
"dropped_waypoints": [],
"dropped_agents": []
}
}
The calculated route for couriers is displayed on the map.
Tariffs
- The service fee is calculated based on the task scope: the number of points to visit multiplied by the number of couriers. For example, if the task has 5 points and 2 couriers, 10 calculations are billed.
- See current prices and rate limits in the Prices section.
Deployment options
- Cloud-based: all TSP API methods are available through public Urbi endpoints.
- On-Premise: all TSP API methods are available when the Urbi API Platform is installed in a private network. For more information, see the API Platform for server.
Support
-
If you have any questions while working with the API, ask AI assistant (in the lower-right corner of website), use the documentation search, or send an email to api@2gis.com.
-
If you would like to discuss the capabilities of the API or its integration with your product, please contact a manager.