action graphhopper_solve_vrp { label: "POST route optimization problem" description: "\nTo get started with the Route Optimization API, please read the [introduction](#tag/Route-Optimization-API).\n\nTo solve a new vehicle routing problem, make a HTTP POST to this URL\n\n```\nhttps://graphhopper.com/api/1/vrp?key=\n```\n\nIt returns the solution to this problem in the JSON response.\n\nPlease note that this URL is very well suited to solve minor problems.\nLarger vehicle routing problems, which take longer than 10 seconds to solve, cannot be solved.\nTo solve them, please use the [batch mode URL](#operation/asyncVRP) instead.\n" provider: graphhopper method: POST path: "/vrp" encoding: json input: { type: "object" properties: { algorithm: { type: "object" description: "Use `objectives` instead." properties: { objective: { type: "string" enum: ["transport_time", "completion_time"] } problem_type: { type: "string" enum: ["min", "min-max"] } } } configuration: { type: "object" description: "Specifies general configurations that are taken into account when solving the vehicle routing problem." properties: { routing: { type: "object" description: "This contains all routing specific configurations." properties: { calc_points: { type: "boolean" description: "It lets you specify whether the API should provide you with route geometries for vehicle routes or not. Thus, you do not need to do extra routing to get the polyline for each route." } consider_traffic: { type: "boolean" description: "indicates whether historical traffic information should be considered" } curbside_strictness: { type: "string" description: "In some cases curbside constraints cannot be fulfilled. For example in one-way streets you cannot arrive at a building that is on the left side of the street such that the building is to the right of you (unless you drove the one-way street the wrong/illegal way). You can set the `curbside_strictness` to `soft` to ignore the curbside constraint in such cases or set it to `strict` to get an error response instead. You can also set it to `ignore` to ignore all curbside constraints (this is useful to compare the results with and without constraints without modifying every single address)." enum: ["ignore", "soft", "strict"] } fail_fast: { type: "boolean" description: "indicates whether matrix calculation should fail fast when points cannot be connected" } network_data_provider: { type: "string" description: "specifies the data provider, read more about it [here](#section/Map-Data-and-Routing-Profiles)." enum: ["openstreetmap", "tomtom"] } return_snapped_waypoints: { type: "boolean" description: "Indicates whether a solution includes snapped waypoints. In contrary to the address coordinate a snapped waypoint is the access point to the (road) network." } snap_preventions: { type: "array" description: "Prevents snapping locations to road links of specified road types, e.g. to motorway." items: { type: "string" enum: ["motorway", "trunk", "bridge", "ford", "tunnel", "ferry"] } } } } } } cost_matrices: { type: "array" description: "Specifies your own tranport time and distance matrices." items: { type: "object" properties: { data: { type: "object" description: "JSON data of matrix response" properties: { distances: { type: "array" items: { type: "array" items: { type: "number" format: "double" } } } info: { type: "object" description: "Additional information for your request" properties: { copyrights: { type: "array" items: { type: "string" } } took: { type: "number" format: "double" } } } times: { type: "array" items: { type: "array" items: { type: "integer" format: "int64" } } } } } location_ids: { type: "array" items: { type: "string" } } profile: { type: "string" description: "vehicle profile or empty if catch all fallback" } type: { type: "string" description: "type of cost matrix, currently default or google are supported" enum: ["default", "google"] } } } } objectives: { type: "array" description: "Specifies an objective function. The vehicle routing problem is solved in such a way that this objective function is minimized." items: { type: "object" required: ["type", "value"] properties: { type: { type: "string" description: "Type of objective function, i.e. `min` or `min-max`.\n\n * `min`: Minimizes the objective value.\n * `min-max`: Minimizes the maximum objective value.\n\nFor instance, `min` -> `vehicles` minimizes the number of employed vehicles.\n`min` -> `completion_time` minimizes the sum of your vehicle routes' completion time.\n\nIf you use, for example, `min-max` -> `completion_time`, it minimizes the maximum of your vehicle routes' completion time, i.e. it minimizes the overall makespan.\nThis only makes sense if you have more than one vehicle. In case of one vehicle, switching from `min` to `min-max` should not have any impact.\nIf you have more than one vehicle, then the algorithm tries to constantly move stops from one vehicle to another such that\nthe completion time of longest vehicle route can be further reduced. For example, if you have one vehicle that takes 8 hours\nto serve all customers, adding another vehicle (and using `min-max`) might halve the time to serve all customers to 4 hours. However,\nthis usually comes with higher transport costs.\n\nIf you want to minimize `vehicles` first and, second, `completion_time`, you can also combine different objectives like this:\n\n```json\n\"objectives\" : [\n {\n \"type\": \"min\",\n \"value\": \"vehicles\"\n },\n {\n \"type\": \"min\",\n \"value\": \"completion_time\"\n }\n]\n```\n\nIf you want to balance activities or the number of stops among all employed drivers, you need to specify it as follows:\n\n```json\n\"objectives\" : [\n {\n \"type\": \"min-max\",\n \"value\": \"completion_time\"\n },\n {\n \"type\": \"min-max\",\n \"value\": \"activities\"\n }\n]\n```\n" enum: ["min", "min-max"] } value: { type: "string" description: "The value of the objective function.\nThe objective value `transport_time` solely considers the time\nyour drivers spend on the road, i.e. transport time. In contrary to `transport_time`, `completion_time` also takes waiting times at customer sites into account.\nThe `completion_time` of a route is defined as the time from starting to ending the route,\ni.e. the route's transport time, the sum of waiting times plus the sum of activity durations.\nNote that choosing `transport_time` or `completion_time` only makes a difference if you specified time windows for your services/shipments since only in\nscenarios with time windows waiting times can occur.\nThe objective value `vehicles` can only be used along with `min` and minimizes vehicles.\n" enum: ["completion_time", "transport_time", "vehicles", "activities"] } } } } relations: { type: "array" description: "Defines additional relationships between orders." items: { type: "object" } } services: { type: "array" description: "Specifies the orders of the type \"service\". These are, for example, pick-ups, deliveries or other stops that are to be approached by the specified vehicles. Each of these orders contains only one location." items: { type: "object" required: ["id"] properties: { address: { type: "object" required: ["location_id", "lon", "lat"] properties: { curbside: { type: "string" description: "Optional parameter. Specifies on which side a point should be relative to the driver when she leaves/arrives at a start/target/via point. Only supported for motor vehicles and OpenStreetMap." enum: ["right", "left", "any"] } lat: { type: "number" format: "double" description: "Latitude of location." } location_id: { type: "string" description: "Specifies the id of the location." } lon: { type: "number" format: "double" description: "Longitude of location." } name: { type: "string" description: "Name of location." } street_hint: { type: "string" description: "Optional parameter. Specifies a hint for each address to better snap the coordinates (lon,lat) to road network. E.g. if there is an address or house with two or more neighboring streets you can control for which street the closest location is looked up." } } } allowed_vehicles: { type: "array" description: "Specifies an array of allowed vehicles, i.e. array of vehicle ids. For example, if this service can only be conducted EITHER by `technician_peter` OR `technician_stefan` specify this as follows: `[\"technician_peter\",\"technician_stefan\"]`." items: { type: "string" } } disallowed_vehicles: { type: "array" description: "Specifies an array of disallowed vehicles, i.e. array of vehicle ids." items: { type: "string" } } duration: { type: "integer" format: "int64" description: "Specifies the duration of the service in seconds, i.e. how long it takes at the customer site." } group: { type: "string" description: "Group this service belongs to. See the group relation and [this post](https://discuss.graphhopper.com/t/4040) on how to utilize this." } id: { type: "string" description: "Specifies the id of the service. Ids need to be unique so there must not be two services/shipments with the same id." } max_time_in_vehicle: { type: "integer" format: "int64" description: "Specifies the maximum time in seconds a delivery can stay in the vehicle. Currently, it only works with services of \"type\":\"delivery\"." } name: { type: "string" description: "Meaningful name for service, e.g. `\"deliver pizza\"`." } preparation_time: { type: "integer" format: "int64" description: "Specifies the preparation time in seconds. It can be used to model parking lot search time since if you have 3 identical locations in a row, it only falls due once." } priority: { type: "integer" format: "int32" description: "Specifies the priority. Can be 1 = high priority to 10 = low priority. Often there are more services/shipments than the available vehicle fleet can handle. Then you can set priorities to differentiate high priority tasks from those that could be left unassigned. I.e. the lower the priority the earlier these tasks are omitted in the solution." } required_skills: { type: "array" description: "Specifies an array of required skills, i.e. array of string (not case sensitive). For example, if this service needs to be conducted by a technician having a `drilling_machine` and a `screw_driver` then specify the array as follows: `[\"drilling_machine\",\"screw_driver\"]`. This means that the service can only be done by a vehicle (technician) that has the skills `drilling_machine` AND `screw_driver` in its skill array. Otherwise it remains unassigned." items: { type: "string" } } size: { type: "array" description: "Size can have multiple dimensions and should be in line with the capacity dimension array of the vehicle type. For example, if the item that needs to be delivered has two size dimension, volume and weight, then specify it as follow [ 20, 5 ] assuming a volume of 20 and a weight of 5." items: { type: "integer" format: "int32" } } time_windows: { type: "array" description: "Specifies an array of time window objects (see time_window object below). Specify the time either with the recommended Unix time stamp (the number of seconds since 1970-01-01) or you can also count the seconds relative to Monday morning 00:00 and define the whole week in seconds. For example, Monday 9am is then represented by 9hour * 3600sec/hour = 32400. In turn, Wednesday 1pm corresponds to 2day * 24hour/day * 3600sec/hour + 1day * 13hour/day * 3600sec/hour = 219600. See this tutorial for more information." items: { type: "object" properties: { earliest: { type: "integer" format: "int64" description: "Specifies the opening time of the time window in seconds, i.e. the earliest time the service can start." } latest: { type: "integer" format: "int64" description: "Specifies the closing time of the time window in seconds, i.e. the latest time the service can start." } } } } type: { type: "string" description: "Specifies type of service. This makes a difference if items are loaded or unloaded, i.e. if one of the size dimensions > 0. If it is specified as `service` or `pickup`, items are loaded and will stay in the vehicle for the rest of the route (and thus consumes capacity for the rest of the route). If it is a `delivery`, items are implicitly loaded at the beginning of the route and will stay in the route until delivery (and thus releases capacity for the rest of the route)." enum: ["service", "pickup", "delivery"] } } } } shipments: { type: "array" description: "Specifies the available shipments. Each shipment contains a pickup and a delivery stop, which must be processed one after the other." items: { type: "object" required: ["id", "pickup", "delivery"] properties: { allowed_vehicles: { type: "array" description: "Specifies an array of allowed vehicles, i.e. array of vehicle ids. For example, if this shipment can only be conducted EITHER by \"technician_peter\" OR \"technician_stefan\" specify this as follows: [\"technician_peter\",\"technician_stefan\"]." items: { type: "string" } } delivery: { type: "object" properties: { address: { type: "object" additionalProperties: true } duration: { type: "integer" format: "int64" description: "Specifies the duration of the pickup or delivery in seconds, e.g. how long it takes unload items at the customer site." } group: { type: "string" description: "Group this stop belongs to. See the group relation and [this post](https://discuss.graphhopper.com/t/4040) on how to utilize this." } preparation_time: { type: "integer" format: "int64" description: "Specifies the preparation time in seconds. It can be used to model parking lot search time since if you have 3 identical locations in a row, it only falls due once." } time_windows: { type: "array" description: "Specifies an array of time window objects (see time window object below). For example, if an item needs to be delivered between 7am and 10am then specify the array as follows: [ { \"earliest\": 25200, \"latest\" : 32400 } ] (starting the day from 0 in seconds)." items: { type: "object" additionalProperties: true } } } } disallowed_vehicles: { type: "array" description: "Specifies an array of disallowed vehicles, i.e. array of vehicle ids." items: { type: "string" } } id: { type: "string" description: "Specifies the id of the shipment. Ids need to be unique so there must not be two services/shipments with the same id." } max_time_in_vehicle: { type: "integer" format: "int64" description: "Specifies the maximum time in seconds a shipment can stay in the vehicle." } name: { type: "string" description: "Meaningful name for shipment, e.g. \"pickup and deliver pizza to Peter\"." } pickup: { type: "object" additionalProperties: true } priority: { type: "integer" format: "int32" description: "Specifies the priority. Can be 1 = high priority to 10 = low priority. Often there are more services/shipments than the available vehicle fleet can handle. Then you can set priorities to differentiate high priority tasks from those that could be left unassigned. I.e. the lower the priority the earlier these tasks are omitted in the solution." } required_skills: { type: "array" description: "Specifies an array of required skills, i.e. array of string (not case sensitive). For example, if this shipment needs to be conducted by a technician having a `drilling_machine` and a `screw_driver` then specify the array as follows: `[\"drilling_machine\",\"screw_driver\"]`. This means that the service can only be done by a vehicle (technician) that has the skills `drilling_machine` AND `screw_driver` in its skill array. Otherwise it remains unassigned." items: { type: "string" } } size: { type: "array" description: "Size can have multiple dimensions and should be in line with the capacity dimension array of the vehicle type. For example, if the item that needs to be delivered has two size dimension, volume and weight, then specify it as follow [ 20, 5 ] assuming a volume of 20 and a weight of 5." items: { type: "integer" format: "int32" } } } } } vehicle_types: { type: "array" description: "Specifies the available vehicle types. These types can be assigned to vehicles." items: { type: "object" required: ["type_id"] properties: { capacity: { type: "array" description: "Specifies an array of capacity dimension values which need to be int values. For example, if there are two dimensions such as volume and weight then it needs to be defined as [ 1000, 300 ] assuming a maximum volume of 1000 and a maximum weight of 300." items: { type: "integer" format: "int32" } } consider_traffic: { type: "boolean" description: "Specifies whether traffic should be considered. if \"tomtom\" is used and this is false, free flow travel times from \"tomtom\" are calculated. If this is true, historical traffic info are used. We do not yet have traffic data for \"openstreetmap\", thus, setting this true has no effect at all." } cost_per_activation: { type: "number" format: "double" description: "**_BETA feature_**! Cost parameter vehicle activation, i.e. fixed costs per vehicle" } cost_per_meter: { type: "number" format: "double" description: "**_BETA feature_**! Cost parameter per distance unit, here meter is used" } cost_per_second: { type: "number" format: "double" description: "**_BETA feature_**! Cost parameter per time unit, here second is used" } network_data_provider: { type: "string" description: "Specifies the network data provider. Either use [`openstreetmap`](#section/Map-Data-and-Routing-Profiles/OpenStreetMap) (default) or [`tomtom`](#section/Map-Data-and-Routing-Profiles/TomTom) (add-on required)." enum: ["openstreetmap", "tomtom"] } profile: { type: "object" } service_time_factor: { type: "number" format: "double" description: "Specifies a service time factor for this vehicle type. If the vehicle/driver that uses this type is able to conduct the service as double as fast as it is determined in the corresponding service or shipment then set it to 0.5." } speed_factor: { type: "number" format: "double" description: "Specifies a speed factor for this vehicle type. If the vehicle that uses this type needs to be only half as fast as what is actually calculated with our routing engine then set the speed factor to 0.5." } type_id: { type: "string" description: "Specifies the id of the vehicle type. If a vehicle needs to be of this type, it should refer to this with its type_id attribute." } } } } vehicles: { type: "array" description: "Specifies the available vehicles." items: { type: "object" required: ["vehicle_id", "start_address"] properties: { break: { type: "object" } earliest_start: { type: "integer" format: "int64" description: "Earliest start of vehicle in seconds. It is recommended to use the unix timestamp." } end_address: { type: "object" additionalProperties: true } latest_end: { type: "integer" format: "int64" description: "Latest end of vehicle in seconds, i.e. the time the vehicle needs to be at its end location at latest." } max_activities: { type: "integer" format: "int32" description: "Specifies the maximum number of activities a vehicle can conduct." } max_distance: { type: "integer" format: "int64" description: "Specifies the maximum distance (in meters) a vehicle can go." } max_driving_time: { type: "integer" format: "int64" description: "Specifies the maximum drive time (in seconds) a vehicle/driver can go, i.e. the maximum time on the road (service and waiting times are not included here)" } max_jobs: { type: "integer" format: "int32" description: "Specifies the maximum number of jobs a vehicle can load." } min_jobs: { type: "integer" format: "int32" description: "Specifies the minimum number of jobs a vehicle should load. This is a soft constraint, i.e. if it is not possible to fulfill “min_jobs”, we will still try to get as close as possible to this constraint." } move_to_end_address: { type: "boolean" description: "Indicates whether a vehicle should be moved even though it has not been assigned any jobs." } return_to_depot: { type: "boolean" description: "If it is false, the algorithm decides where to end the vehicle route. It ends in one of your customers' locations. The end is chosen such that it contributes to the overall objective function, e.g. min transport_time. If it is true, you can either specify a specific end location (which is then regarded as end depot) or you can leave it and the driver returns to its start location." } skills: { type: "array" description: "Array of skills, i.e. array of string (not case sensitive)." items: { type: "string" } } start_address: { type: "object" additionalProperties: true } type_id: { type: "string" description: "The type ID assigns a vehicle type to this vehicle. You can specify types in the array of vehicle types. If you omit the type ID, the default type is used. The default type is a `car` with a capacity of 0." } vehicle_id: { type: "string" description: "Specifies the ID of the vehicle. Ids must be unique, i.e. if there are two vehicles with the same ID, an error is returned." } } } } } } output: { type: "object" properties: { copyrights: { type: "array" items: { type: "string" description: "Attribution" } } processing_time: { type: "integer" format: "int64" description: "Processing time in ms. If job is still waiting in queue, processing_time is 0" } solution: { type: "object" description: "Only available if status field indicates `finished`." properties: { completion_time: { type: "integer" format: "int64" description: "Overall completion time in seconds, i.e. the sum of each routes/drivers operation time." } costs: { type: "integer" format: "int32" } distance: { type: "integer" format: "int32" description: "Overall distance travelled in meter, i.e. the sum of each route's transport distance" } max_operation_time: { type: "integer" format: "int64" description: "Operation time of longest route in seconds." } no_unassigned: { type: "integer" format: "int32" description: "Number of jobs that could not be assigned to final solution." } no_vehicles: { type: "integer" format: "int32" description: "Number of employed vehicles." } preparation_time: { type: "integer" format: "int64" description: "Overall preparation time in seconds." } routes: { type: "array" description: "An array of routes" items: { type: "object" properties: { activities: { type: "array" description: "Array of activities" items: { type: "object" properties: { address: { type: "object" description: "Address of activity" properties: { lat: { type: "number" format: "double" description: "Latitude of location." } location_id: { type: "string" description: "Specifies the id of the location." } lon: { type: "number" format: "double" description: "Longitude of location." } name: { type: "string" description: "Name of location." } snapped_waypoint: { type: "object" description: "Access point to the (road)network. It is only available if `return_snapped_waypoints` is true (be default it is false)." properties: { lat: { type: "object" additionalProperties: true } lon: { type: "object" additionalProperties: true } } } street_hint: { type: "string" description: "Optional parameter. Specifies a hint for each address to better snap the coordinates (lon,lat) to road network. E.g. if there is an address or house with two or more neighboring streets you can control for which street the closest location is looked up." } } } arr_date_time: { type: "string" format: "date-time" description: "Arrival date time with offset like this 1970-01-01T01:00+01:00. If you do not use time-dependent optimization, this is `null`." } arr_time: { type: "integer" format: "int64" description: "Arrival time at this activity in seconds. If type is `start`, this is not available (since it makes no sense to have `arr_time` at start). However, `end_time` is available and actually means \\\"departure time\\\" at start location. It is important to note that `arr_time` does not necessarily mean \\\"start of underlying activity\\\", it solely means arrival time at activity location. If this activity has no time windows and if there are no further preparation times, `arr_time` is equal to activity start time." } distance: { type: "integer" format: "int64" description: "cumulated distance from start to this activity in m" } driving_time: { type: "integer" format: "int64" description: "cumulated driving time from start to this driver activity in seconds" } end_date_time: { type: "string" format: "date-time" description: "End date time with offset like this 1970-01-01T01:00+01:00. If you do not use time-dependent optimization, this is `null`." } end_time: { type: "integer" format: "int64" description: "End time of and thus departure time at this activity. If type is `end`, this is not available (since it makes no sense to have an `end_time` at end) `end_time` at each activity is equal to the departure time at the activity location." } id: { type: "string" description: "Id referring to the underlying service or shipment, i.e. the shipment or service this activity belongs to" } load_after: { type: "array" description: "Array with size/capacity dimensions after this activity" items: { type: "integer" format: "int32" description: "dimension value" } } load_before: { type: "array" description: "Array with size/capacity dimensions before this activity" items: { type: "integer" format: "int32" description: "dimension value" } } location_id: { type: "string" description: "Id that refers to address" } preparation_time: { type: "integer" format: "int64" description: "preparation time at this activity in seconds" } type: { type: "string" description: "type of activity" enum: ["start", "end", "service", "pickupShipment", "deliverShipment", "pickup", "delivery", "break"] } waiting_time: { type: "integer" format: "int64" description: "Waiting time at this activity in seconds. A waiting time can occur if the activity has at least one time window. If `arr_time` < `time_window.earliest` a waiting time of `time_window_earliest` - `arr_time` occurs." } } } } completion_time: { type: "integer" format: "int64" description: "Completion time of route in seconds" } distance: { type: "integer" format: "int64" description: "Distance of route in meter" } points: { type: "array" description: "Array of route planning points" items: { type: "object" properties: { coordinates: { type: "array" items: { type: "object" } } type: { type: "string" } } } } preparation_time: { type: "integer" format: "int64" description: "Preparation time of route in seconds" } service_duration: { type: "integer" format: "int64" description: "Service duration of route in seconds" } transport_time: { type: "integer" format: "int64" description: "Transport time of route in seconds" } vehicle_id: { type: "string" description: "Id of vehicle that operates route" } waiting_time: { type: "integer" format: "int64" description: "Waiting time of route in seconds" } } } } service_duration: { type: "integer" format: "int64" description: "Overall service time in seconds." } time: { type: "integer" format: "int64" description: "Use `transport_time` instead." } transport_time: { type: "integer" format: "int64" description: "Overall time travelled in seconds, i.e. the sum of each route's transport time." } unassigned: { type: "object" properties: { breaks: { type: "array" description: "An array of ids of unassigned breaks" items: { type: "string" description: "Id of unassigned breaks" } } details: { type: "array" description: "An array of details, i.e. reason for unassigned services or shipments" items: { type: "object" properties: { code: { type: "integer" format: "int32" description: "Reason code\n\nCode | Reason\n:------|:---------\n1 | cannot serve required skill\n2 | cannot be visited within time window\n3 | does not fit into any vehicle due to capacity\n4 | cannot be assigned due to max distance constraint of vehicles\n21 | could not be assigned due to relation constraint\n22 | could not be assigned due to allowed vehicle constraint\n23 | could not be assigned due to max-time-in-vehicle constraint\n24 | driver does not need a break\n25 | could not be assigned due to disallowed vehicle constraint\n26 | could not be assigned due to max drive time constraint\n27 | could not be assigned due to max job constraint\n28 | could not be assigned due to max activity constraint\n50 | underlying location cannot be accessed over road network by at least one vehicle\n" } id: { type: "string" description: "Id of unassigned service/shipment" } reason: { type: "string" description: "Human readable reason as listed above" } } } } services: { type: "array" description: "An array of ids of unassigned services" items: { type: "string" description: "Id of unassigned service" } } shipments: { type: "array" description: "An array of ids of unassigned shipments" items: { type: "string" description: "Id of unassigned shipments" } } } } waiting_time: { type: "integer" format: "int64" description: "Overall waiting time in seconds." } } } status: { type: "string" description: "Indicates the current status of the job" enum: ["waiting_in_queue", "processing", "finished"] } waiting_time_in_queue: { type: "integer" format: "int64" description: "Waiting time in ms" } } } }