{
  "openapi": "3.1.0",
  "info": {
    "title": "GraphHopper Directions API",
    "description": "\nIntegrate A-to-B route planning, turn-by-turn navigation,\nroute optimization, isochrone calculations, location clustering and other tools into your application.\n\n  #### Authentication\n  \n  1. [Sign up for GraphHopper](https://graphhopper.com/dashboard/signup)\n  2. [Create an API key](https://support.graphhopper.com/a/solutions/articles/44001976027)\n\n  Authenticate to the API by passing your key as a query parameter in every request.\n\n  #### API Explorer\n\n  You can also try all API parts without registration in the [API explorer](https://explorer.graphhopper.com/).\n\n  #### Client Libraries\n\n  To speed up development and make coding easier, we offer a [JavaScript client](https://www.npmjs.com/package/@graphhopper/directions-api-js-client) and a\n  [Java client](https://github.com/graphhopper/graphhopper/tree/master/client-hc).\n\n  #### Plans and Rate Limits\n\n  | Plan | Daily credits | Credits/min | Requests/sec | Max optimization vehicles | Max routing locations |\n  |---|---|---|---|---|---|\n  | Free (non-commercial) | 500 | limited | limited | 1 | 5 |\n  | Basic | 5,000 | 100 | 1 | 2 | 30 |\n  | Standard | 15,000 | 400 | 2 | 10 | 80 |\n  | Premium | 50,000 | 1,000 | 10 | 20 | 200 |\n  | Custom | custom | custom | custom | up to 200 | up to 10,000 |\n\n  Rate limiting is credit-based. Every response includes `X-RateLimit-Remaining` (credits left) and `X-RateLimit-Reset` (seconds until reset). A `429` response means the limit is exhausted.\n\n  #### Credit Costs per Request\n\n  | Endpoint | Formula | Example |\n  |---|---|---|\n  | Routing | 1 credit for 2–10 locations; locations ÷ 10 above that. +1 for `alternative_route`, ×2 for round trips, ×10 for `optimize=true` | 25 locations = 2.5 credits |\n  | Route Optimization | vehicles × locations (min 10, max 10 × locations). Solution polling (GET) costs 0.3 credits | 10 vehicles, 150 stops = 1,500 credits |\n  | Matrix | (origins × destinations) ÷ 2, or max(origins, destinations) × 10 — whichever is cheaper (min 1) | 30 origins × 40 destinations = 400 credits |\n  | Geocoding | 0.3 credits per request (default provider) | |\n  | Map Matching | locations ÷ 50 (min 1) | 200 GPS points = 4 credits |\n  | Isochrone | 2 credits per minute explored (min 10) | 20-min isochrone = 40 credits |\n  | Cluster | customers × 10 (min 10). `as_the_crow_flies` profile: customers × 1 (min 1) | 100 customers = 1,000 credits |\n\n  #### Common Workflows\n\n  The APIs are designed to be combined. Here are the most common patterns:\n\n  **Delivery / field service app** — Geocoding → Route Optimization → Routing\n\n  1. [Geocoding](#tag/Geocoding): convert customer addresses to coordinates. Note: the Geocoding response uses `point.lng` while the Optimization request uses `lon` — map the field name accordingly.\n  2. [Route Optimization](#tag/Route-Optimization) (`POST /vrp`): pass the coordinates as service addresses along with your vehicles. Set `configuration.routing.calc_points` to `true` to get route geometries in the response. The solver assigns stops to vehicles, sequences them, and returns routes with arrival times.\n  3. [Routing](#tag/Routing) (`POST /route`): optionally, call this per driver route to get turn-by-turn instructions. Pass the stop coordinates from the optimization solution as `points`, set `instructions` to `true`.\n\n  If you only need geometries (no turn-by-turn instructions), step 3 is unnecessary — `calc_points` in step 2 already provides them.\n\n  **ETA / distance matrix** — Geocoding → Matrix\n\n  1. [Geocoding](#tag/Geocoding): convert addresses to coordinates.\n  2. [Matrix](#tag/Matrices) (`POST /matrix`): compute travel times and distances between all pairs (or specific origin/destination sets). Useful for displaying ETAs to customers or pre-filtering stops before optimization.\n\n  **Simple A-to-B navigation** — Routing only\n\n  Call [Routing](#tag/Routing) (`POST /route`) with two or more `points`. No optimization or geocoding needed if you already have coordinates.\n\n  #### Optimize Response Speed\n\n  1. Reuse SSL/TLS sessions\n\n  You should utilize the SSL session to speed up responses after the initial response or use a library that does this. E.g. for Java the\n  [OkHttp library](https://square.github.io/okhttp/) automatically reuses SSL/TLS sessions and also the browser takes care of this automatically.\n  For python you can use the [`requests` library](https://requests.readthedocs.io/en/latest/user/advanced/): first you create a\n  session (`session = requests.Session()`) and then do requests only with this session instead of directly using \"requests\".\n\n  2. Bandwidth reduction\n\n  If you create your own client, make sure it supports http/2 and gzipped responses for best speed.\n  If you use Route Optimization or Matrices and want to solve large problems, we recommend you to reduce bandwidth\n  by [compressing your POST request](https://gist.github.com/karussell/82851e303ea7b3459b2dea01f18949f4) and specifying the header\n  as follows: `Content-Encoding: gzip`. This will also avoid the HTTP 413 error \"Request Entity Too Large\".\n",
    "version": "1.0.0",
    "termsOfService": "https://www.graphhopper.com/terms/",
    "contact": {
      "name": "Support",
      "email": "support@graphhopper.com",
      "url": "https://www.graphhopper.com/"
    },
    "x-logo": {
      "url": "img/graphhopper-logo.svg",
      "altText": "GraphHopper"
    }
  },
  "servers": [
    {
      "url": "https://graphhopper.com/api/1"
    }
  ],
  "tags": [
    {
      "name": "Map Data and Routing Profiles",
      "description": "\nThe default data source is [OpenStreetMap](https://www.openstreetmap.org). As an alternative, we also offer TomTom MultiNet.\n\nPlease read in [our attribution page](https://www.graphhopper.com/attribution/) on how to attribute these different data sources.\n\n# OpenStreetMap\n\n#### Geographical Coverage\n\n[OpenStreetMap](https://www.openstreetmap.org) covers the whole world. If you want to see for yourself if we can provide data suitable for your region,\nplease visit [GraphHopper Maps](https://graphhopper.com/maps/).\nYou can edit and modify OpenStreetMap data if you find that important information is missing, e.g. a weight limit for a bridge.\n[Here](https://wiki.openstreetmap.org/wiki/Beginners%27_guide) is a beginner's guide that shows how to add data. If you have edited data, we usually consider your data after 1 week at the latest.\n\n#### Standard Routing Profiles\n\nThe Routing, Matrix and Route Optimization APIs support the following profiles. But also see the section about customized profiles below the table.\n\nName             | Description           | Restrictions                        | Icon\n-----------------|:----------------------|:------------------------------------|:---------------------------------------------------------\ncar              | Car mode              | car access, weight=2500kg, width=2m, height=2m           | ![car image](./img/car.png)\ncar_avoid_motorway | Car mode            | like car that heavily penalizes motorways        | ![car image](./img/car.png)\ncar_avoid_ferry    | Car mode            | like car that heavily penalizes ferries          | ![car image](./img/car.png)\ncar_avoid_toll     | Car mode            | like car that heavily penalizes tolls and ferries| ![car image](./img/car.png)\nsmall_truck        | Small truck like a Mercedes Sprinter, Ford Transit or Iveco Daily | height=2.7m, width=2+0.28m, length=5.5m, weight=2080+1400 kg | ![small truck image](./img/small_truck.png)\ntruck              | Truck like a MAN or Mercedes-Benz Actros              | height=3.7m, width=2.6+0.34m, length=12m, weight=13000+13000 kg, hgv=yes, 3 Axes | ![truck image](./img/truck.png)\nscooter            | Moped mode          | Fast inner city, often used for food delivery, is able to ignore certain bollards, maximum speed of roughly 50km/h. weight=300kg, width=1m, height=2m | ![scooter image](./img/scooter.png)\nfoot       | Pedestrian routes | foot access         | ![foot image](./img/foot.png)\nhike       | Pedestrian routes prioritizing scenic beauty and longer distances than with the `foot` profile, designed for hiking experiences rather than casual walks. Walking duration is influenced by elevation differences. May include challenging or potentially dangerous trail sections requiring appropriate preparation, equipment and caution. Use the `hike_rating` [path detail](/openapi/routing/postroute#routing/postroute/t=request&path=details) for this information.  | foot access, but with potentially dangerous [SAC-scales](https://wiki.openstreetmap.org/wiki/Key:sac_scale)         | ![hike image](./img/hike.png)\nbike       | Trekking bike avoiding hills | bike access         | ![Bike image](./img/bike.png)\nmtb        | Mountainbike                 | bike access         | ![Mountainbike image](./img/mtb.png)\nracingbike | Bike preferring roads        | bike access         | ![Racingbike image](./img/racingbike.png)\necargobike | Similar to racingbike but a bit faster and with width constraints. | bike access but without steps and footways | ![Racingbike image](./img/racingbike.png)\nas_the_crow_flies | Only available for the Cluster API. Uses the straight-line (or \"direct\") distance. This allows to use 5x more customers than the contractual \"locations\" limit defines. | -         | -\n\nNote:\n\n * the free package supports only the routing profiles `car`, `bike` or `foot`\n * up to 3 different routing profiles can be used in a single request towards the Route Optimization API. The number of vehicles is unaffected and depends on your subscription.\n * a sophisticated `motorcycle` profile is available up on request. It is powered by the [Kurviger](https://kurviger.de/en) Routing API and favors curves and slopes while avoiding cities and highways.\n \n#### Customized Routing Profiles\n\nCustomized routing profiles let you modify any vehicle profile, including speed, access restrictions, and other parameters. Read more about this [in the documentation](#tag/Custom-Profiles).\nCustom profiles work for the Routing, Route Optimization and Matrix API.\n\nFor the Routing API, it is also possible to modify the profile on a per-request basis using [custom models](#tag/Custom-Model), without needing to create a separate custom profile in advance.\nThis enables dynamic adjustments to routing preferences, such as avoiding certain areas or applying vehicle-specific restrictions, directly within each request.\n\n# TomTom MultiNet\n\nThrough a partnership with TomTom, we offer the TomTom MultiNet map as an alternative to OSM. Consider this option\nif your application requires more data-driven travel time estimates than our OSM-based map can provide.\n\nThis map can sometimes give more accurate travel time estimates and produce higher-quality routes. It uses\nlink speeds that vary over the time of day, accounting for different traffic conditions during rush hours.\n\nThis map is updated quarterly. Optionally, we can take currently known road closures from a live feed into account.\n\n#### Geographical Coverage\n\nTomTom MultiNet is a global map covering more than 150 countries and 30 territories.\n\n#### Routing Profiles\n\nName       | Description           | Restrictions              | Icon\n-----------|:----------------------|:--------------------------|:---------------------------------------------------------\ncar        | Car mode              | car access                | ![car image](./img/car.png)\nsmall_truck| Small truck like a Mercedes Sprinter, Ford Transit or Iveco Daily | height=2.7m, width=2+0.28m, length=5.5m, weight=2080+1400 kg | ![small truck image](./img/small_truck.png)\n"
    },
    {
      "name": "Route Optimization",
      "description": "The Route Optimization API solves [traveling salesman](https://en.wikipedia.org/wiki/Travelling_salesman_problem) and [vehicle routing problems](https://en.wikipedia.org/wiki/Vehicle_routing_problem): given a set of stops to visit and a set of vehicles to visit them with, it returns an assignment of stops to vehicles and an order to visit them in, minimizing an objective you choose (total time, number of vehicles used, longest single route, etc.) while respecting constraints you specify (time windows, vehicle capacities, driver skills, and many more).\n\nThis page describes the conceptual model. The endpoint reference pages linked at the bottom describe the request and response schema in detail. If you prefer to learn by example, jump to the [API Explorer](https://explorer.graphhopper.com/?endpoint=vrp) or the [Getting Started tutorial](https://www.graphhopper.com/blog/2019/05/17/getting-started-with-the-optimization-api-traveling-salesman-problem/).\n\n# Mental Model\n\nA request describes a **fleet**, a **workload**, and an **objective**. The API returns a **solution**.\n\nThe **fleet** is the set of vehicles that will execute the routes. Vehicles are described individually (start and end location, optional shift schedule); shared characteristics (routing profile, capacity, speed, cost per hour and per kilometer) are factored out into vehicle types.\n\nThe **workload** is the set of orders to be served. Each order is either a **service** (a single stop) or a **shipment** (a paired pickup and delivery that must end up on the same route, in order).\n\nThe **objective** is what the optimizer minimizes. Total time, number of vehicles used, longest single route, fairness across drivers. You choose, and you can combine multiple objectives in priority order.\n\nA **solution** is a list of routes (one per used vehicle), each an ordered list of activities with arrival and departure times, plus an `unassigned` list for orders that could not be placed.\n\nTwo further mechanisms refine the model:\n\n**Constraints** restrict which solutions are valid. Hard constraints (time windows, capacity, skills, allowed vehicles) leave non-conforming orders unassigned; soft constraints (priority, preferred vehicles) influence the optimizer without forbidding violations.\n\n**Relations** link orders to each other beyond what an objective and constraints can express. They state that certain orders must be served on the same route, in a given sequence, or within a geographic flow, independently of what the optimizer would otherwise choose.\n\nThese five elements — fleet, workload, objective, constraints, relations — are everything you ever describe in a request. The rest of this page explains how to use each of them well.\n\n# Minimal Example\n\nA request with one vehicle, one vehicle type, four services, a relation, and an objective to minimize total time. One service exceeds the vehicle's capacity and will be left unassigned. The `in_direct_sequence` relation forces order-3 to be served immediately after the vehicle's start, followed immediately by order-2:\n\n```json\n{\n  \"vehicles\": [\n    {\n      \"vehicle_id\": \"driver-1\",\n      \"type_id\": \"van\",\n      \"start_address\": { \"location_id\": \"depot\", \"lon\": 13.3888, \"lat\": 52.5170 },\n      \"earliest_start\": 1746612000\n    }\n  ],\n  \"vehicle_types\": [\n    {\n      \"type_id\": \"van\",\n      \"profile\": \"car\",\n      \"capacity\": [10]\n    }\n  ],\n  \"services\": [\n    {\n      \"id\": \"order-1\",\n      \"address\": { \"location_id\": \"order-1\", \"lon\": 13.3762, \"lat\": 52.5206 },\n      \"size\": [2],\n      \"duration\": 300,\n      \"time_windows\": [{ \"earliest\": 1746612000, \"latest\": 1746615600 }]\n    },\n    {\n      \"id\": \"order-2\",\n      \"address\": { \"location_id\": \"order-2\", \"lon\": 13.4050, \"lat\": 52.5200 },\n      \"size\": [3],\n      \"duration\": 300\n    },\n    {\n      \"id\": \"order-3\",\n      \"address\": { \"location_id\": \"order-3\", \"lon\": 13.4270, \"lat\": 52.5230 },\n      \"size\": [1],\n      \"duration\": 300\n    },\n    {\n      \"id\": \"order-4\",\n      \"address\": { \"location_id\": \"order-4\", \"lon\": 13.395163, \"lat\": 52.526215 },\n      \"size\": [20],\n      \"duration\": 300\n    }\n  ],\n  \"objectives\": [\n    { \"type\": \"min\", \"value\": \"completion_time\" }\n  ],\n  \"relations\": [ { \"type\": \"in_direct_sequence\", \"ids\": [\"start\",\"order-3\",\"order-2\"] } ],\n  \"configuration\": { \"routing\": { \"calc_points\": true } }\n}\n```\n\nThe response contains a `solution` with a `routes` array (one per used vehicle) and an `unassigned` object for orders that could not be placed:\n\n```json\n{\n  \"solution\": {\n    \"distance\": 10424,\n    \"transport_time\": 1279,\n    \"completion_time\": 2179,\n    \"no_vehicles\": 1,\n    \"no_unassigned\": 1,\n    \"routes\": [\n      {\n        \"vehicle_id\": \"driver-1\",\n        \"points\": [\n          { \"type\": \"LineString\", \"coordinates\": [[13.3888,52.517],\"...\",  [13.427,52.523]] },\n          { \"type\": \"LineString\", \"coordinates\": [[13.427,52.523], \"...\", [13.405,52.52]] },\n          { \"type\": \"LineString\", \"coordinates\": [[13.405,52.52],  \"...\", [13.3762,52.5207]] },\n          { \"type\": \"LineString\", \"coordinates\": [[13.3762,52.5207],\"...\",[13.3888,52.517]] }\n        ],\n        \"activities\": [\n          { \"type\": \"start\", \"location_id\": \"depot\", \"arr_time\": 1746612000, \"end_time\": 1746612000, \"load_after\": [0] },\n          { \"type\": \"service\", \"id\": \"order-3\", \"location_id\": \"order-3\", \"arr_time\": 1746612352, \"end_time\": 1746612652, \"load_before\": [0], \"load_after\": [1] },\n          { \"type\": \"service\", \"id\": \"order-2\", \"location_id\": \"order-2\", \"arr_time\": 1746612966, \"end_time\": 1746613266, \"load_before\": [1], \"load_after\": [4] },\n          { \"type\": \"service\", \"id\": \"order-1\", \"location_id\": \"order-1\", \"arr_time\": 1746613640, \"end_time\": 1746613940, \"load_before\": [4], \"load_after\": [6], \"time_window\": { \"earliest\": 1746612000, \"latest\": 1746615600 } },\n          { \"type\": \"end\", \"location_id\": \"depot\", \"arr_time\": 1746614179, \"end_time\": 1746614179, \"load_before\": [6] }\n        ]\n      }\n    ],\n    \"unassigned\": {\n      \"services\": [\"order-4\"],\n      \"details\": [{ \"id\": \"order-4\", \"code\": 3, \"reason\": \"does not fit into any vehicle due to capacity\" }]\n    }\n  }\n}\n```\n\nNote that `time_windows` use Unix timestamps (recommended). The `in_direct_sequence` relation forced the solver to visit order-3 then order-2 immediately after the start, even though a different sequence might have been shorter. `order-4` was left unassigned with reason code 3 (capacity exceeded: size 20 vs. vehicle capacity 10). Because `configuration.routing.calc_points` is `true`, the response includes a `points` array with one LineString geometry per leg — use these to render routes on a map without a separate Routing API call.\n\n# Concepts\n\n## Services vs. Shipments\n\nThe choice matters because it changes what the optimizer is allowed to do.\n\nA **service** is loaded onto the vehicle for the rest of the route (if `type` is `service` or `pickup`) or treated as already-loaded at the depot and dropped at the customer (`type: delivery`). The optimizer is free to interleave services from different customers in any order that satisfies constraints.\n\nA **shipment** introduces an ordering constraint: the pickup of shipment X must happen before the delivery of shipment X, on the same route. Between those two stops, the optimizer can interleave other services or other shipments' pickups and deliveries, as long as capacity holds.\n\nUse services for typical last-mile delivery (where goods come from a single depot), customer visits, technician dispatch. Use shipments when goods move directly between customer locations: courier work, ride-hailing, moving services, vehicle repositioning.\n\n## Constraints: Hard vs. Soft\n\nConstraints fall into two categories, and understanding the difference is critical for diagnosing why the solver returned the result it did.\n\n**Hard constraints** must be satisfied. If they cannot be, the order is left unassigned and appears in `solution.unassigned`. Hard constraints include:\n\n- Time windows on services, shipments, and vehicle shifts\n- Vehicle capacity vs. order size\n- Skills (a service's `required_skills` must be a subset of the assigned vehicle's `skills`)\n- `allowed_vehicles` and `disallowed_vehicles` lists\n- `max_distance`, `max_driving_time`, `max_jobs`, `max_activities` per vehicle\n- `max_time_in_vehicle` for deliveries\n- Relation constraints (`in_sequence`, `in_direct_sequence`, `in_same_route`, `in_area_sequence`)\n\n**Soft constraints** influence the solution but do not prevent assignment. Violating them costs the optimizer \"score,\" so it tries to avoid them, but will accept a violation if there's no alternative. Soft constraints include:\n\n- `priority` on services and shipments (high-priority orders get assigned first when not all can be served)\n- `preferred_vehicles`\n- `min_jobs` per vehicle\n\nWhen an order ends up unassigned, the response includes `solution.unassigned.details` with a code indicating the most likely reason (capacity, time window, skill mismatch, etc.) and a `reasons` array with all probable causes ranked by likelihood. The full code table is in the [POST /vrp reference](#operation/solveVRP).\n\n## Relations: Shaping the Solution\n\nThe objectives plus hard and soft constraints can express most of what a router needs, but not everything. Real-world dispatchers carry knowledge that resists formalization: a driver prefers to clear the north side of town before lunch, two stops at the same office should be done back-to-back so the driver only signs in once, a particular customer expects to be the first visit of the day, the morning route should sweep west-to-east before circling back. These aren't gaps in the API — they're the gap between any abstract objective and the messy reality of operations. Drivers have preferences, customers have habits, and dispatchers have judgment that earned its keep over years.\n\n**Relations are the escape hatch for that gap.** Instead of trying to encode every preference as an objective or constraint, you let the optimizer do its job within boundaries you define. A relation says \"whatever else you decide, this constraint must hold.\"\n\nThe available relation types:\n\n- **`in_same_route`** — the related items must end up on the same vehicle, regardless of order.\n- **`not_in_same_route`** — the related items must end up on different vehicles. This is the only exclusion relation; all others pull items together.\n- **`in_sequence`** — the related items must appear in the listed order on a single route, but other stops may be inserted between them.\n- **`in_direct_sequence`** — the related items must appear in the listed order on a single route, with no stops in between.\n- **`neighbor`** — the related items must be served by the same vehicle and appear next to each other, but in any order.\n- **`in_area_sequence`** — each area is defined by an anchor stop and a radius; all stops within that radius belong to the area. The areas must be visited in the given order, while the optimizer remains free to sequence stops within each area.\n\n`in_area_sequence` is unique among the six in that the grouping is defined spatially, by an anchor stop and a radius, rather than by labels you assign to individual orders. A dispatcher picks a few anchor stops, sets a radius for each, orders the resulting areas, and the optimizer respects the geographic flow while still finding the best sequence within each area. The dispatcher's tacit knowledge about traffic, neighborhood characteristics, or driver preference becomes a few clicks; the optimizer handles the rest.\n\n### Two Granularities: Orders and Groups\n\nRelations operate at two granularities, depending on which field you populate.\n\n**Order-level relations** use the `ids` field, listing individual service or shipment ids. `in_sequence` over `[\"service-A\", \"service-B\"]` means service-A must be served before service-B on the same route.\n\n**Group-level relations** use the `group` field, listing group labels instead of order ids. `in_sequence` over groups `[\"downtown\", \"uptown\"]` is a higher-order constraint: every stop tagged `group: \"downtown\"` must be served before every stop tagged `group: \"uptown\"`. The relation operates on the clusters as units, not on the individual stops inside them.\n\nGroup-level relations are what make interactive UIs practical. A dispatcher assigns a group label to a set of stops in a neighborhood, and a single relation entry sequences that group against another, regardless of how many stops are inside either one. The dispatcher works with a handful of meaningful clusters; the request stays compact regardless of how many orders the underlying problem contains.\n\n### Groups Own Semantics\n\nGroups are not only labels you reference from relations. Assigning the same group label to two or more orders is itself a constraint.\n\nTagging orders with the same group does two things at once. First, it treats them as a contiguous cluster: wherever they are served, they appear as a block, with no other stops inserted between them. Second, it leaves the order within that block to the optimizer. A group is in effect a \"weak in_sequence\": the stops stay together, but the algorithm picks the best internal sequence.\n\nThe cluster constraint is about contiguity, not route assignment. In a multi-vehicle problem, the orders in group A and the orders in group B can land on different routes; the optimizer is free to make that choice. On each route a group appears on, its members are contiguous. If you want all members of a group on the same route, add an `in_same_route` relation over the group, or pin the group to a specific vehicle by adding a `vehicle_id` to the relation.\n\nUngrouped orders are by default not allowed to be inserted inside a group; if you need that flexibility, set `configuration.optimization.free_insertion` to true. You can then exempt specific groups (typically conventional ones like `\"asap\"` or `\"last\"`) from free insertion via `free_insertion_exempt_groups`, so those groups remain compact while other ungrouped orders move freely.\n\n### Practical Notes\n\nRelations are hard constraints: an order in an unsatisfiable relation appears in `unassigned` with reason code 21 (or 29 for group constraints). They compose with all other constraints, so a relation that conflicts with a time window or capacity will leave the affected orders unassigned.\n\nRelations can also be built dynamically. A common pattern is to take the result of a first optimization, extract the sequence the optimizer chose, and feed it back as `in_direct_sequence` relations to lock that sequence in for the next request. This is useful when re-planning around late-breaking changes without disrupting an already-communicated route. Watch for cases where the new constraints over-constrain the problem and previously-assignable orders become unassigned.\n\n## Choosing an Objective\n\nPick the objective that matches what you're actually optimizing for. The defaults that suit most use cases:\n\n**Just minimize total time:** `min completion_time`. This is the right answer for ~80% of real dispatch problems.\n\n**Use as few vehicles as possible, then minimize time:** combine `min vehicles` followed by `min completion_time`. The order matters: the optimizer treats objectives lexicographically, so vehicles are minimized first, completion time second.\n\n**Finish all routes as early as possible (minimize the longest route):** `min-max completion_time`. Useful when you have a hard end-of-day deadline and want all drivers home around the same time.\n\n**Distribute work fairly across drivers:** `balance completion_time` (Beta) or `balance activities`. The `balance` type minimizes the variance of workload, while `min-max` only minimizes the longest route. Use `balance` when fairness matters; use `min-max` when only the latest finish time matters.\n\n**Travel time only, ignoring waiting at customer sites:** `min transport_time`. Rare. Most users actually want `completion_time`.\n\nFor a deeper discussion, see [completion time vs. transport time](https://www.graphhopper.com/blog/2016/06/20/what-is-the-difference-between-the-minimization-of-completion-time-and-minimizing-transport-time/).\n\n## Synchronous vs. Asynchronous\n\nTwo endpoints solve the same problem with different delivery mechanisms.\n\n**`POST /vrp`** (synchronous) returns the solution in the response body. Use this when the problem is small enough to solve in under 10 seconds. If the solver runs longer, the request times out and you lose the work.\n\n**`POST /vrp/optimize`** (asynchronous) returns a `job_id` immediately. You then poll **`GET /vrp/solution/{jobId}`** every 500ms or so until `status` is `finished`. Use this for any problem that might exceed 10 seconds.\n\nAs a rule of thumb, prefer the synchronous endpoint for problems with a single vehicle and up to 200 stops. If you're unsure, start synchronous; if you hit timeouts, switch to async. The async workflow has the same request body, so switching is a one-line change.\n\n## Endpoints\n\n- [POST /vrp](#operation/solveVRP): synchronous endpoint. Returns the solution in the response. Suitable for problems that solve in under 10 seconds.\n- [POST /vrp/optimize](#operation/asyncVRP): asynchronous endpoint. Returns a `job_id`; fetch the solution from the endpoint below. Use this for problems that take longer than 10 seconds. The request body is identical to `/vrp`.\n- [GET /vrp/solution/{jobId}](#operation/getSolution): poll this endpoint until `status` is `finished`. Recommended interval: 500ms.\n\n## Further reading\n\n- [Getting Started with the Optimization API](https://www.graphhopper.com/blog/2019/05/17/getting-started-with-the-optimization-api-traveling-salesman-problem/) — step-by-step walkthrough of a first VRP request\n- [Area Sequencing: shape your routes by area](https://www.graphhopper.com/blog/2026/05/04/area-sequencing-shape-your-routes-by-area/) — using `in_area_sequence` to control geographic flow\n- [Solving a TSP with a week-planning horizon and driver shifts](https://www.graphhopper.com/blog/2020/07/15/how-to-solve-a-traveling-salesman-problem-with-a-week-planning-horizon-and-driver-shifts/)\n- [Scheduling technicians with skills and multiple dependencies](https://www.graphhopper.com/blog/2016/06/03/how-to-route-technicians-with-skills-and-multiple-dependencies-between-tasks/)\n- [Completion time vs. transport time](https://www.graphhopper.com/blog/2016/06/20/what-is-the-difference-between-the-minimization-of-completion-time-and-minimizing-transport-time/)\n- [Modeling multi-trip routes for a single vehicle](https://www.graphhopper.com/blog/2016/07/21/how-to-model-multiple-delivery-routes-with-a-single-vehicle/)\n"
    },
    {
      "name": "Routing",
      "description": "The Routing API calculates the best path connecting two or more points, where the meaning of ''best'' depends on the vehicle profile and use case.\nBesides path coordinates it can return turn-by-turn instructions, elevation, [path details](https://www.graphhopper.com/blog/2019/11/28/routing-api-using-path-details/) and other useful information about the route.\n\nUse our [API Explorer](https://explorer.graphhopper.com/) to explore the Routing API.\n"
    },
    {
      "name": "Matrices",
      "description": "The Matrix API calculates distances and times between multiple start and destination locations.\nIt can compute full NxN matrices or asymmetric matrices with separate origin and destination sets.\n"
    },
    {
      "name": "Geocoding",
      "description": "_Geocoding_ describes the process of transforming an textual address representation to a coordinate (`latitude,longitude`).\nFor example the conversion from `Berlin` to `52.5170365,13.3888599`.\n\n_Reverse geocoding_ converts a coordinate to a textual address representation or place name. Find out more about Geocoding itself on [Wikipedia](http://en.wikipedia.org/wiki/Geocoding).\n"
    },
    {
      "name": "Isochrones",
      "description": "An isochrone of a location is ''a line connecting points at which a vehicle arrives at the same time'', see Wikipedia.\nWith the same API you can also calculate isodistances, just use the parameter distance_limit instead of time_limit`.\n\nSome possible areas in which this API may be useful to you:\n\n- real estate analysis\n- realtors\n- vehicle scheduling\n- geomarketing\n- reach of electric vehicles\n- transport planning\n- logistics (distribution and retail network planning)\n\nSee the [clients](#section/API-Clients) section in the main documentation, and [our API explorer](https://explorer.graphhopper.com/?endpoint=isochrone).\n"
    },
    {
      "name": "Map Matching",
      "description": "You can snap measured GPS points typically as GPX files to a digital\nroad network to e.g. clean data or attach certain data like elevation or turn instructions to it.\n\nSee the [clients](#section/API-Clients) section in the main documentation, and [our API explorer](https://explorer.graphhopper.com/?endpoint=match).\n\nThe cost for one request depends on the number of GPS location and is documented [here](https://support.graphhopper.com/support/solutions/articles/44000718211-what-is-one-credit-).\n\nOne request should not exceed the Map Matching API location limit depending on the package, see the pricing in our dashboard.\n"
    },
    {
      "name": "Clustering",
      "description": "It solves the “capacity clustering problem” by assigning a set of customers to a given number of distinct groups (called clusters).\nThe API “clusters” by minimizing the total distance from each individual customer to its designated group median.\nIt can also consider minimum and maximum capacity restrictions for each group.\n\nClustering can be used in many practical applications.\nFor example, it can help to plan territories, i.e. territory optimization for field teams with large territories for field workers,\nor to solve large vehicle routing problems (VRP).\n\nTry Clustering in our [API Explorer](https://explorer.graphhopper.com/?endpoint=cluster)!\n\nThe idea is to divide a certain number of customers, a pre-specified number of clusters. As already written above, a distribution is sought that minimizes the total cost (e.g. distance or time or a function of distance and time).\nWe currently support two approaches.\n\n1. You can simply define a certain number of clusters via configuration (\"clustering\" with empty set of \"clusters\") and additionally how many customers should be in such a cluster.\nThis is defined by an upper and lower limit (\"min_quantity\" and \"max_quantity). The algorithm then searches for suitable clusters and divides the customers into these clusters.\n\n2. You can explicitly define clusters via \"clusters\". In this way, each individual cluster can be defined.\nThis approach not only allows each cluster to have its own capacity upper and lower bound, but each cluster can also be assigned a fixed cluster center.\nIn contrast to 1. the algorithm then does not search for a suitable center, but assigns the customers given the fixed centers to each cluster. Note that if you define clusters\nexplicitly, any configuration of \"clustering\" will be overwritten by these explicit clusters.\n"
    },
    {
      "name": "Custom Model",
      "description": "\nA custom model allows you to modify the default routing behavior of a vehicle profile by specifying a set of rules in JSON language.\nThere are three JSON properties to change a profile: `priority`, `speed` and `distance_influence` that are described in great detail in the next sections and you can get a quick overview in this [example-driven blog post](https://www.graphhopper.com/blog/2020/05/31/examples-for-customizable-routing/).\n\nBut first we will give an introductory example for each of these JSON properties. Let's start with `speed`:\n\n```json\n{\n  \"speed\": [{\n    \"if\": \"road_class == MOTORWAY\",\n    \"limit_to\": \"90\"\n  }]\n}\n```\n\nAs you might have already guessed this limits the speed on motorways to 90km/h.\nChanging the speed will of course change the travel time, but at the same time this makes other road classes more likely as well, so you can use this model to avoid motorways.\n\nYou can immediately try this out in the Browser [on GraphHopper Maps](https://graphhopper.com/maps/?point=50.856527%2C12.876127&point=51.02952%2C13.295603&profile=car&custom_model=%7B%22speed%22%3A%5B%7B%22if%22%3A%22road_class+=%3D+MOTORWAY%22%2C%22limit_to%22%3A%2290%22%7D%5D%7D).\nGraphHopper Maps offers an interactive text editor to comfortably enter custom models.\nYou can open it by pressing the gear icon in the top left corner. It will check the syntax of your custom model and mark errors in red. You can press\nCtrl+Space or Alt+Enter to retrieve auto-complete suggestions. Pressing Ctrl+Enter will send a routing request for the\ncustom model you entered. To disable the custom model you click the gear icon again.\n\nIn the second example we show how to avoid certain road classes without changing the travel time:\n\n```json\n{\n  \"priority\": [{\n    \"if\": \"road_class == LIVING_STREET || road_class == RESIDENTIAL || road_class == UNCLASSIFIED\",\n    \"multiply_by\": \"0.1\"\n  }]\n}\n```\n\nThis example avoids certain smaller streets. [View it in GraphHopper Maps](https://graphhopper.com/maps/?point=51.125708%2C13.067915&point=51.125964%2C13.082271&profile=car&custom_model=%7B%22priority%22%3A%5B%7B%22if%22%3A%22road_class+=%3D+LIVING_STREET+%7C%7C+road_class+%3D%3D+RESIDENTIAL+%7C%7C+road_class+%3D%3D+UNCLASSIFIED%22%2C%22multiply_by%22%3A%220.1%22%7D%5D%7D).\n\nThe third example shows how to prefer shortest paths:\n\n```json\n{\n  \"distance_influence\": 200\n}\n```\n\n[View this example in GraphHopper Maps](https://graphhopper.com/maps/?point=51.04188%2C13.057766&point=51.057527%2C13.068237&profile=car&custom_model=%7B%22distance_influence%22%3A200%7D).\n\nThere is a fourth JSON property `areas` that allows you to define areas that can then be used in the `if` or `else_if` conditions for `speed` and `priority`.\nPlease read more about this and the other properties below and try some examples in\n[GraphHopper Maps](https://graphhopper.com/maps/) with the help of\n[this blog post](https://www.graphhopper.com/blog/2020/05/31/examples-for-customizable-routing/).\n\n\n## Customizing speed\n\nWhen using custom models you do not need to define rules that specify a speed for every road segment, but rather GraphHopper\nassumes a default speed. All you need to do is adjust this default speed to your use-case as you will always use the custom \nmodel in conjunction with a routing profile which is used to determine the default speed.\n\nThe custom model is a JSON object and the first property we will learn about here is the `speed` property. The `speed`\nproperty's value is a list of conditional statements that modify the default speed. Every such statement consists of a\ncondition and an operation. The different statements are applied to the default speed from top to bottom, i.e.\nstatements that come later in the list are applied to the resulting value of previous operations. Each statement is only\nexecuted if the corresponding condition applies for the current road segment. This will become more clear in the following\nexamples.\n\nCurrently the custom model language supports two operators:\n\n- `multiply_by` multiplies the speed value with a given number\n- `limit_to` limits the speed value to a given number\n\n#### Conditional multiplication\n\nLet's start with a simple example using `multiply_by`:\n\n```json\n{\n  \"speed\": [\n    {\n      \"if\": \"road_class == MOTORWAY\",\n      \"multiply_by\": \"0.5\"\n    }\n  ]\n}\n```\n\nThis custom model reduces the speed of every road segment for which the `road_class` attribute is `MOTORWAY` to\nfifty percent of the default speed (the default speed is multiplied by `0.5`). Again, the default speed is the speed\nthat GraphHopper would normally use for the profile's vehicle. Note the `if` clause which means that the operation\n(`multiply_by`) is only applied *if* the condition `road_class == MOTORWAY` is fulfilled for the road segment under\nconsideration. The `==` indicates equality, i.e. the condition reads \"the road_class equals MOTORWAY\". If you're a bit\nfamiliar with programming note that the condition (the value of the `if` key) is just a boolean condition in Java\nlanguage (other programming languages like C or JavaScript are very similar in this regard). A more complex condition\ncould look like this: `road_class == PRIMARY || road_class == TERTIARY` which uses the **or**\n(`||`) operator and literally means \"road_class equals PRIMARY or road_class equals TERTIARY\".\n\nThere can be multiple such 'if statements' in the speed section, and they are evaluated from top to bottom:\n\n```json\n{\n  \"speed\": [\n    {\n      \"if\": \"road_class == MOTORWAY\",\n      \"multiply_by\": \"0.5\"\n    },\n    {\n      \"if\": \"road_class == PRIMARY || road_environment == TUNNEL\",\n      \"multiply_by\": \"0.7\"\n    }\n  ]\n}\n```\n\nIn this example the default speed of road segments with `road_class == MOTORWAY` will be multiplied by `0.5`, the default speed\nof road segments with `road_class == PRIMARY` will be multiplied by `0.7` and for road segments with both `road_class == MOTORWAY` and\n`road_environment == TUNNEL` the default speed will be multiplied first by `0.5` and then by `0.7`. So overall the\ndefault speed will be multiplied by `0.35`. For road segments with `road_class == PRIMARY` and `road_environment == TUNNEL` we\nonly multiply by `0.7`, even though both parts of the second condition apply. It only matters whether the road segment matches\nthe condition or not.\n\n`road_class` and `road_environment` are road attributes of 'enum' type, i.e. their value can only be one of a fixed set of\nvalues, like `MOTORWAY` for `road_class`.\n\nOther road attributes like `road_class_link` are of `boolean` type. They can be used as conditions directly, for example:\n\n```json\n{\n  \"speed\": [\n    {\n      \"if\": \"road_class_link\",\n      \"multiply_by\": \"0.6\"\n    }\n  ]\n}\n```\n\nwhich means that for road segments with `road_class_link==true` the speed factor will be `0.6`.\n\nFor attributes with numeric values, like `max_width` you should not use the `==` (equality) or `!=` (\ninequality) operators, but the numerical comparison operators \"bigger\" `>`, \"bigger or equals\" `>=`, \"smaller\" `<`, or\n\"smaller or equals\" `<=`, e.g.:\n\n```json\n{\n  \"speed\": [\n    {\n      \"if\": \"max_width < 2.5\",\n      \"multiply_by\": \"0.8\"\n    }\n  ]\n}\n``` \n\nwhich means that for all road segments with `max_width` smaller than `2.5m` the speed is multiplied by `0.8`.\n\n\n### Conditional capping\n\nBesides the `multiply_by` operator there is also the `limit_to` operator. As the name suggests `limit_to` limits the\ncurrent value to the given value. Take this example:\n\n```json\n{\n  \"speed\": [\n    {\n      \"if\": \"road_class == MOTORWAY\",\n      \"multiply_by\": \"0.8\"\n    },\n    {\n      \"if\": \"surface == GRAVEL\",\n      \"limit_to\": \"60\"\n    }\n  ]\n}\n```\n\nThis implies that on all road segments with the `GRAVEL` value for `surface` the speed will be at most `60km/h`,\nregardless of the default speed and the previous rules. So for a road segment with `road_class == MOTORWAY`,\n`surface == GRAVEL` and default speed `100` the first statement reduces the speed from `100` to `80` and the second\nstatement further reduces the speed from `80` to `60`. If the `road_class` was `PRIMARY` and the default speed was `50`\nthe first rule would not apply and the second rule would do nothing, because limiting `50` to `60` still yields `50`.\n\nA common use-case for the `limit_to` operation is the following pattern:\n\n```json\n{\n  \"speed\": [\n    {\n      \"if\": \"true\",\n      \"limit_to\": \"90\"\n    }\n  ]\n}\n```\n\nwhich means that the speed is limited to `90km/h` for all road segments regardless of its properties. The condition\n\"`true`\" is always fulfilled.\n\n### Conditionals with multiple branches\n\nThe `else` statement allows you to define that some operations should be applied if an road segment does **not** match a\ncondition. So this example:\n\n```json\n{\n  \"speed\": [\n    {\n      \"if\": \"road_class == MOTORWAY\",\n      \"multiply_by\": \"0.5\"\n    },\n    {\n      \"else\": \"\",\n      \"limit_to\": \"50\"\n    }\n  ]\n}\n```\n\nmeans that for all road segments with `road_class == MOTORWAY` we multiply the default speed by `0.5` and for all others we\nlimit the default speed to `50` (but never both).\n\nIn case you want to distinguish more than two cases (road segments that match or match not a condition) you can use `else_if`\nstatements which are only evaluated in case the previous `if` or `else_if` statement did **not** match:\n\n```json\n{\n  \"speed\": [\n    {\n      \"if\": \"road_class == MOTORWAY\",\n      \"multiply_by\": \"0.5\"\n    },\n    {\n      \"else_if\": \"road_environment == TUNNEL\",\n      \"limit_to\": \"70\"\n    },\n    {\n      \"else\": \"\",\n      \"multiply_by\": \"0.9\"\n    }\n  ]\n}\n```\n\nSo if the first condition matches (`road_class == MOTORWAY`) the default speed is multiplied by `0.5`, but the other two\nstatements are ignored. Only if the first statement does not match (e.g. `road_class == PRIMARY`) the second statement\nis even considered and only if it matches (`road_environment == TUNNEL`) the default speed is limited to 70. The last\noperation (`multiply_by: \"0.9\"`) is only applied if both previous conditions did not match.\n\n`else` and `else_if` statements always require a preceding `if` or `else_if` statement. However, there can be multiple\n'blocks' of subsequent `if/else_if/else` statements in the list of rules for `speed`.\n\n`else_if` is useful for example in case you have multiple `multiply_by` operations, but you do not want that the speed\ngets reduced by all of them. For the following model\n\n```json\n{\n  \"speed\": [\n    {\n      \"if\": \"road_class == MOTORWAY\",\n      \"multiply_by\": \"0.5\"\n    },\n    {\n      \"else_if\": \"road_environment == TUNNEL\",\n      \"multiply_by\": \"0.8\"\n    }\n  ]\n}\n```\n\nonly the first factor (`0.5`) will be applied even for road segments that fulfill both conditions.\n\n## Limit rules to certain areas\n\nYou can not only modify the speed of road segments based on properties, like we saw in the previous examples, but you\ncan also modify the speed of road segments based on their location. To do this you need to first create and add some\nareas to the `areas` section of the custom model. You can then use the name of these areas in the conditions of your\n`if/else/else_if` statements.\n\nIn the following example we multiply the speed of all road segments in an area called `custom1` with `0.7` and also limit it\nto `50km/h`. Note that each area's name needs to be prefixed with `in_`:\n\n```json\n{\n  \"speed\": [\n    {\n      \"if\": \"in_custom1\",\n      \"multiply_by\": \"0.7\"\n    },\n    {\n      \"if\": \"in_custom1\",\n      \"limit_to\": \"50\"\n    }\n  ],\n  \"areas\": {\n    \"type\": \"FeatureCollection\",\n    \"features\": [{\n      \"type\": \"Feature\",\n      \"id\": \"custom1\",\n      \"geometry\": {\n        \"type\": \"Polygon\",\n        \"coordinates\": [\n          [\n            [\n              1.525,\n              42.511\n            ],\n            [\n              1.510,\n              42.503\n            ],\n            [\n              1.531,\n              42.495\n            ],\n            [\n              1.542,\n              42.505\n            ],\n            [\n              1.525,\n              42.511\n            ]\n          ]\n        ]\n      }\n    }]\n  }\n}\n```\n\nAreas are given in GeoJson format (FeatureCollection). Currently a member of this collection must be a `Feature` with a\ngeometry type `Polygon`. Note that the coordinates array of `Polygon` is an array of arrays that\neach must describe a closed ring, i.e. the first point must be equal to the last, identical to the GeoJSON specs.\nEach point is given as an array [longitude, latitude], so the `coordinates` array has three dimensions total.\n\nUsing the `areas` feature you can also block entire areas i.e. by multiplying the speed with `0`, but for this you\nshould rather use the `priority` section that we will explain next.\n\n## Customizing priority\n\nMake sure you read the introductory section of this document to learn what the `priority` factor means. In short it\nallows similar modifications as `speed`, but instead of modifying the road segment weights *and* travel times it will only\naffect the weights. By default, the priority is `1` for every road segment, so it does not affect the weight. However,\nchanging the priority of a road can yield a relative weight difference in comparison to other roads.\n\nCustomizing the `priority` works very much like changing the `speed`, so in case you did not read the section about\n`speed` you should go back there and read it now. The only real difference is that there is no `limit_to` operator for\n`priority`. As a quick reminder here is an example for priority:\n\n```json\n{\n  \"priority\": [\n    {\n      \"if\": \"road_class == MOTORWAY\",\n      \"multiply_by\": \"0.5\"\n    },\n    {\n      \"else_if\": \"road_class == SECONDARY\",\n      \"multiply_by\": \"0.9\"\n    },\n    {\n      \"if\": \"road_environment == TUNNEL\",\n      \"multiply_by\": \"0.1\"\n    }\n  ]\n}\n```\n\nmeans that road segments with `road_class==MOTORWAY` and `road_environment==TUNNEL` get priority `0.5*0.1=0.05` and\nthose with `road_class==SECONDARY` and no TUNNEL, get priority `0.9` and so on.\n\nEdges with lower priority values will be less likely part of the optimal route calculated by GraphHopper, higher values\nmean that these road segments shall be preferred. If you do not want to state which road segments shall be avoided, but\nrather which ones shall be preferred, you need to **decrease** the priority of others:\n\n```json\n{\n  \"priority\": [\n    {\n      \"if\": \"road_class != CYCLEWAY\",\n      \"multiply_by\": \"0.8\"\n    }\n  ]\n}\n```\n\nmeans decreasing the priority for all road_classes *except* cycleways.\n\nJust like we saw for `speed` you can also adjust the priority for road segments in a certain area. It works exactly the\nsame way:\n\n```json\n{\n  \"priority\": [\n    {\n      \"if\": \"in_custom1\",\n      \"multiply_by\": \"0.7\"\n    }\n  ]\n}\n```\n\nTo block an entire area set the priority value to `0`. You can even set the priority only for certain roads in an area\nlike this:\n\n```json\n{\n  \"priority\": [\n    {\n      \"if\": \"road_class == MOTORWAY && in_custom1\",\n      \"multiply_by\": \"0.1\"\n    }\n  ]\n}\n```\n\nSome other useful attributes to restrict access to certain roads depending on your vehicle dimensions are the\nfollowing:\n\n```json\n{\n  \"priority\": [\n    {\n      \"if\": \"max_width < 2.5\",\n      \"multiply_by\": \"0\"\n    },\n    {\n      \"if\": \"max_length < 10\",\n      \"multiply_by\": \"0\"\n    },\n    {\n      \"if\": \"max_weight < 3.5\",\n      \"multiply_by\": \"0\"\n    }\n  ]\n}\n```\n\nwhich means that the priority for all road segments that allow a maximum vehicle width of `2.5m`, a maximum vehicle\nlength of `10m` or a maximum vehicle weight of `3.5tons`, or less, is zero, i.e. these \"narrow\" road segments are\nblocked.\n\n## Customizing distance_influence\n\nThe `distance_influence` property allows you to control the trade-off between a fast route (minimum time) and a short route\n(minimum distance). The larger `distance_influence` is the more GraphHopper will prioritize routes with a small\ntotal distance. More precisely, the `distance_influence` is the time you need to save on a detour (a longer distance\nroute option) such that you prefer taking the detour compared to a shorter route. Please note that this value is a number, not a string.\n\nA value of `100` means that one extra kilometer of detour must save you `100s` of travelling time or else you are not \nwilling to take the detour. Or to put it another way, if a reference route takes `600s` and is `10km` long, \n`distance_influence=100` means that you are willing to take an alternative route that is `11km` long only if \nit takes no longer than `500s` (saves `100s`). Things get a bit more complicated when `priority` is not `1`, but the \neffect stays the same: The larger `distance_influence` is, the more GraphHopper will focus on finding short routes.\n\n\n## Road attributes\n\nGraphHopper stores different attributes for every road segment. Some frequently used are the following (some of their possible values are given in brackets):\n\n- road_class: (OTHER, MOTORWAY, TRUNK, PRIMARY, SECONDARY, TRACK, STEPS, CYCLEWAY, FOOTWAY, ...)\n- road_environment: (ROAD, FERRY, BRIDGE, TUNNEL, ...)\n- road_access: (DESTINATION, DELIVERY, PRIVATE, NO, ...)\n- surface: (PAVED, DIRT, SAND, GRAVEL, ...)\n- smoothness: (EXCELLENT, GOOD, INTERMEDIATE, ...)\n- toll: (MISSING, NO, HGV, ALL)\n- bike_network, foot_network: (MISSING, INTERNATIONAL, NATIONAL, REGIONAL, LOCAL, OTHER)\n- country: (`MISSING` or the country as a `ISO3166-1:alpha3` code e.g. `DEU`)\n- hazmat: (YES, NO), hazmat_tunnel: (A, B, .., E), hazmat_water: (YES, PERMISSIVE, NO)\n- hgv: (MISSING, YES, DESIGNATED, ...)\n- track_type: (MISSING, GRADE1, GRADE2, ..., GRADE5)\n- urban_density: (RURAL, RESIDENTIAL, CITY)\n\n\nTo learn about all available encoded values you can query the `/info` endpoint\n\nBesides this kind of categories, which can take multiple different string values, there are also some that represent a\nboolean value (they are either true or false for a given road segment), like:\n\n- road_class_link\n- roundabout\n\nThere are also some that take on a numeric value, like:\n\n- average_slope: a number for 100 * \"elevation change\" / edge_distance for a road segment; it changes the sign in reverse direction; see also max_slope\n- curvature: \"beeline distance\" / edge_distance (0..1) e.g. a curvy road is smaller than 1\n- hike_rating, horse_rating, mtb_rating: a number from 0 to 6 for the `sac_scale` in OSM, e.g. 0 means \"missing\", 1 means \"hiking\", 2 means \"mountain_hiking\" and so on\n- lanes: number of lanes\n- max_slope: an unsigned decimal for the maximum slope (100 * \"elevation change / distance_i\") of an edge with `sum(distance_i)=edge_distance`. Important for longer road segments where ups (or downs) can be much bigger than the average_slope.\n- max_speed: the speed limit from a sign (km/h)\n- max_height (meter), max_width (meter), max_length (meter)\n- max_weight (ton)\n\n\n## Limitations\n\nYou can directly use custom models with the [POST Route Endpoint](#operation/postRoute).\n\nTo use custom models with the Route Optimization API or the Matrix API, use the [Profiles API](#tag/Custom-Profiles)\nto create a new named profile with your custom model. You can then use that profile like you\nwould use a pre-defined profile.\n\nThis feature will strongly benefit from feedback, so do not hesitate to share your experience, your favorite custom\nmodel or some of the problems you ran into when you tried building your own custom model.\n\n## Troubleshooting\n\n### Recommendations\n\nFor debugging you can use the custom model editor in [GraphHopper Maps](https://graphhopper.com/maps/) (click the 'gear' button in the top left).\n\nWhen debugging problems with custom models you should first try if your request goes through without an error using an empty custom model.\n\n### Route calculation is slower\n\nThe route calculation with custom_models will be slower as a different algorithm has to be used. The more the result deviates from the optimum the slower the response can get.\n\nIf you create [custom profile](#tag/Custom-Profiles) with a custom_model you'll get faster response times nearly as fast as the default vehicle profile.\n\nIf a custom profile is not something you can use then for certain use cases you can make the route calculation faster when you tune the `custom_model` and e.g. exclude certain ways via `{ \"if\": \"road_class == TRACK || road_class == RESIDENTIAL\", \"multiply_by\": \"0\" }` in the `priority`.\n\nIf this is still not sufficient and you need even faster response times, you can use the parameter `astarbi.epsilon` (`>=1`). This enables a heuristic that speeds up routing \nbut may occasionally cause unwanted detours. The closer this value is to 1, the nearer the route is to optimal.\nIn practice, a value 1.3-1.4 provides good speed improvements (10-20%) while causing little to no deviation from the optimal route in most cases.\n\n### All routes for my custom model fail\n\nThis could mean that either your custom model made some of the roads near the start and destination inaccessible, \nthen usually we return a PointNotFoundException with the point_index with the \"location snap\" problem.\n\nOr, the custom model made a route between your start and destination impossible, then we return a ConnectionNotFoundException. This happens e.g. when you exclude tunnels, \nferries or motorways but all routes between start and destination have these road attributes satisfied, i.e. we cannot find a route.\n\n**Solution for both cases**: relax your custom model and e.g. instead of excluding certain road attributes via `\"multiply_by\": \"0\"` you should try to use `\"0.01\"`.\n"
    },
    {
      "name": "Custom Profiles",
      "description": "\nYou can create routing profiles that are customized to your needs. You can take advantage of\nall the modelling options described in the [Custom Model section](#tag/Custom-Model) and use the created custom profile (prefix `cp_`)\nwith our Routing, Matrix and Route Optimization APIs.\n\n**Notes**\n\n * The geographic coverage of each custom profile is restricted and varies based on the selected package.\n * This feature is available starting with the premium package.\n\nA curl example to create a profile:\n\n```\ncurl -X POST -H \"Content-Type: application/json\" \"https://graphhopper.com/api/1/profiles?key=YOUR_KEY\" -d '{\"bounds\":{\"bbox\":[11.45462,48.00954,11.77322,48.2076]},\"custom_model\":{\"priority\":[{\"if\":\"road_class == MOTORWAY\",\"multiply_by\":\"0\"}]},\"profile\":\"car\"}'\n```\n\nTo quickly test your custom_model you can use the Routing API where a different custom model can be specified in every request.\nOr use [GraphHopper Maps](https://graphhopper.com/maps/) and click the gear button.\n\n**Creating custom profiles using the API Explorer**\n\nBesides using the `/profiles` endpoint directly you can also create custom profiles using [our API explorer](https://explorer.graphhopper.com/?endpoint=profiles).\n\n 1. Visit the [API explorer](https://explorer.graphhopper.com/?endpoint=profiles).\n 2. Set your API key with the \"API key\" button.\n 2. Now copy and paste the JSON to create a custom profile into the input window. To get started you can use the already pre-filled example, which will create a\n    custom profile that excludes motorways and is limited to the Munich area.\n 3. Click \"Send\". This creates a custom profile. Copy the returned `id` from the output window (it starts with `cp_`).\n 4. To try this profile out you change the drop down to \"Optimization API\", pick the first example and replace `car` in `\"profile\": \"car\"` (`vehicle_types` section) with the profile `id` you just copied and click \"Send\".\n\nThe optimized route no longer uses motorways. Keep in mind that this is a simple example and the custom model language\nis a lot more powerful than this with which you can avoid, exclude or prefer certain areas or road classes and a lot more.\nMake sure you read the [Custom Model section](#tag/Custom-Model) to learn about all the details.\n\nNote that you can use the profile `id` just as well for the `/matrix` or `/route` endpoint. E.g. select \"Routing API\"\nand use the profile `id` in the request.\n"
    }
  ],
  "paths": {
    "/route": {
      "post": {
        "summary": "Calculate a route",
        "operationId": "postRoute",
        "description": "This POST endpoint accepts routing requests as JSON and returns the computed route as JSON. It offers a high degree of customization through the custom model to account for \nvehicle constraints such as height or weight, avoidance or exclusion of specific areas. It also provids rich route information including elevation data, turn-by-turn instructions,\ntoll information, and other detailed path details.\n",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RouteRequest"
              }
            }
          }
        },
        "tags": [
          "Routing"
        ],
        "responses": {
          "200": {
            "description": "Routing Result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RouteResponse"
                },
                "example": {
                  "hints": {
                    "visited_nodes.sum": 58,
                    "visited_nodes.average": 58
                  },
                  "info": {
                    "copyrights": [
                      "GraphHopper",
                      "OpenStreetMap contributors"
                    ],
                    "took": 2
                  },
                  "paths": [
                    {
                      "distance": 1791.011,
                      "weight": 307.852443,
                      "time": 370962,
                      "transfers": 0,
                      "points_encoded": false,
                      "bbox": [
                        11.539424,
                        48.118343,
                        11.558901,
                        48.122364
                      ],
                      "points": {
                        "type": "LineString",
                        "coordinates": [
                          [
                            11.539424,
                            48.118352
                          ],
                          [
                            11.540387,
                            48.118368
                          ],
                          [
                            11.54061,
                            48.118356
                          ],
                          [
                            11.541941,
                            48.118409
                          ],
                          [
                            11.543696,
                            48.118344
                          ],
                          [
                            11.547167,
                            48.118343
                          ],
                          [
                            11.548478,
                            48.118366
                          ],
                          [
                            11.548487,
                            48.119329
                          ],
                          [
                            11.548807,
                            48.119328
                          ],
                          [
                            11.549408,
                            48.119366
                          ],
                          [
                            11.550349,
                            48.119508
                          ],
                          [
                            11.550441,
                            48.119473
                          ],
                          [
                            11.551109,
                            48.119467
                          ],
                          [
                            11.551553,
                            48.119445
                          ],
                          [
                            11.551748,
                            48.119398
                          ],
                          [
                            11.552087,
                            48.119475
                          ],
                          [
                            11.552236,
                            48.119542
                          ],
                          [
                            11.552353,
                            48.119635
                          ],
                          [
                            11.553853,
                            48.121136
                          ],
                          [
                            11.555448,
                            48.12039
                          ],
                          [
                            11.555797,
                            48.120206
                          ],
                          [
                            11.55632,
                            48.120592
                          ],
                          [
                            11.556716,
                            48.120919
                          ],
                          [
                            11.557326,
                            48.121345
                          ],
                          [
                            11.558901,
                            48.122364
                          ]
                        ]
                      },
                      "instructions": [
                        {
                          "distance": 672.954,
                          "heading": 89.04,
                          "sign": 0,
                          "interval": [
                            0,
                            6
                          ],
                          "text": "Continue onto Lindenschmitstraße",
                          "time": 144703,
                          "street_name": "Lindenschmitstraße"
                        },
                        {
                          "distance": 107.145,
                          "sign": -2,
                          "interval": [
                            6,
                            7
                          ],
                          "text": "Turn left",
                          "time": 22675,
                          "street_name": ""
                        },
                        {
                          "distance": 140.169,
                          "sign": 2,
                          "interval": [
                            7,
                            10
                          ],
                          "text": "Turn right onto Oberländerstraße",
                          "time": 28032,
                          "street_name": "Oberländerstraße"
                        },
                        {
                          "distance": 360.232,
                          "sign": 1,
                          "interval": [
                            10,
                            18
                          ],
                          "text": "Turn slight right",
                          "time": 72677,
                          "street_name": ""
                        },
                        {
                          "distance": 177.621,
                          "sign": 2,
                          "interval": [
                            18,
                            20
                          ],
                          "text": "Turn right onto Thalkirchner Straße",
                          "time": 35524,
                          "street_name": "Thalkirchner Straße"
                        },
                        {
                          "distance": 332.89,
                          "sign": -2,
                          "interval": [
                            20,
                            24
                          ],
                          "text": "Turn left onto Thalkirchner Straße",
                          "time": 67351,
                          "street_name": "Thalkirchner Straße"
                        },
                        {
                          "distance": 0,
                          "sign": 4,
                          "last_heading": 45.67046584987792,
                          "interval": [
                            24,
                            24
                          ],
                          "text": "Arrive at destination",
                          "time": 0,
                          "street_name": ""
                        }
                      ],
                      "legs": [],
                      "details": {},
                      "ascend": 6.3294677734375,
                      "descend": 25.0579833984375,
                      "snapped_waypoints": {
                        "type": "LineString",
                        "coordinates": [
                          [
                            11.539424,
                            48.118352
                          ],
                          [
                            11.558901,
                            48.122364
                          ]
                        ]
                      }
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Your request is not valid. For example, you specified too few or too many points.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GHError"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "description": "Authentication necessary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GHError"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "429": {
            "description": "API limit reached.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GHError"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error. We get notified automatically and fix this asap.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GHError"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "Calculate a route",
        "operationId": "getRoute",
        "description": "For the GET request you specify the parameters in the URL and can try it directly in every browser.\nHowever, it has some disadvantages when using many points (URL length limit) and the [`custom_model` Feature](#tag/Custom-Model) cannot be used. \nTherefore, our recommended endpoint is the [POST route endpoint](#operation/postRoute).\n",
        "parameters": [
          {
            "in": "query",
            "name": "profile",
            "schema": {
              "$ref": "#/components/schemas/VehicleProfileId"
            }
          },
          {
            "name": "point",
            "in": "query",
            "description": "The points for which the route should be calculated. Format: `latitude,longitude`. Specify at least an origin and a destination. Via points are possible.\nThe maximum number depends on your plan.\n",
            "required": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "example": [
              "51.131,12.414",
              "48.224,3.867"
            ],
            "style": "form",
            "explode": true
          },
          {
            "name": "point_hint",
            "in": "query",
            "description": "The `point_hint` is typically a road name to which the associated `point` parameter should be snapped to. Specify no `point_hint` parameter or the same number as you have `point` parameters.\n",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true
          },
          {
            "name": "snap_prevention",
            "in": "query",
            "description": "Optional parameter. 'Snapping' is the process of finding the closest road location for GPS coordinates provided in the `point` parameter. The `snap_prevention` parameter allows you to prevent snapping to specific types of roads. For example, if `snap_prevention` is set to bridge, the routing engine will avoid snapping to a bridge, even if it is the closest road for the given `point`. Current supported values: `motorway`, `trunk`, `ferry`, `tunnel`, `bridge` and `ford`. Multiple values are specified like `snap_prevention=ferry&snap_prevention=motorway`. Note that once snapped the routing algorithm can still route over bridges (or the other values). To avoid this you need to use the `custom_model`.\n",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "explode": true
          },
          {
            "in": "query",
            "name": "curbside",
            "description": "Optional parameter. It specifies on which side a point should be relative to the driver when she leaves/arrives at a start/target/via point. You need to specify this parameter for either none or all points. Only supported for motor vehicles and OpenStreetMap.\n",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "any",
                  "right",
                  "left"
                ]
              }
            }
          },
          {
            "name": "locale",
            "in": "query",
            "description": "The locale of the resulting turn instructions. E.g. `pt_PT` for Portuguese or `de` for German.\n",
            "schema": {
              "type": "string",
              "default": "en"
            }
          },
          {
            "name": "elevation",
            "in": "query",
            "description": "If `true`, a third coordinate, the altitude, is included with all positions in the response.\nThis changes the format of the `points` and `snapped_waypoints` fields of the response, in both their\nencodings. Unless you switch off the `points_encoded` parameter, you need special code on the\nclient side that can handle three-dimensional coordinates.\n",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "details",
            "in": "query",
            "description": "Optional parameter. The following path details are available: `street_name`, `street_ref`, `street_destination`, `leg_time`, `leg_distance`, `roundabout`, `country`, `time`, `distance`, `max_speed`,\n`max_weight`, `max_width`, `toll`, `road_class`, `road_class_link`, `road_access`, `road_environment`, `hazmat`, `hazmat_tunnel`, `hazmat_water`, \n`lanes`, `surface`, `smoothness`, `hike_rating`, `mtb_rating`, `foot_network`, `bike_network`. Read more about the usage of path details [here](https://discuss.graphhopper.com/t/2539).\n",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "explode": true
          },
          {
            "in": "query",
            "name": "optimize",
            "description": "Normally, the calculated route will visit the points in the order you specified them.\nIf you have more than two points, you can set this parameter to `\"true\"` and the points may be re-ordered to minimize the total travel time.\nKeep in mind that the limits on the number of locations of the Route Optimization API applies, and the request costs more credits.\n",
            "schema": {
              "type": "string",
              "default": "false"
            }
          },
          {
            "in": "query",
            "name": "instructions",
            "description": "If instructions should be calculated and returned\n",
            "schema": {
              "type": "boolean",
              "default": true
            }
          },
          {
            "name": "calc_points",
            "in": "query",
            "description": "If the points for the route should be calculated at all.\n",
            "schema": {
              "type": "boolean",
              "default": true
            }
          },
          {
            "name": "debug",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "If `true`, the output will be formatted.\n"
          },
          {
            "name": "points_encoded",
            "in": "query",
            "description": "Allows changing the encoding of location data in the response. The default is polyline encoding, which is compact\nbut requires special client code to unpack. (We provide it in our JavaScript client library!)\nSet this parameter to `false` to switch the encoding to simple coordinate pairs like `[lon,lat]`, or `[lon,lat,elevation]`.\nSee the description of the response format for more information.\n",
            "schema": {
              "type": "boolean",
              "default": true
            }
          },
          {
            "name": "ch.disable",
            "in": "query",
            "description": "Use `true` to enable the flexible mode to use the `custom_model` or any of the following options below.\n",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "heading",
            "in": "query",
            "description": "Favour a heading direction for a certain point. Specify either one heading for the start point or as many as there are points.\nIn this case headings are associated by their order to the specific points. Headings are given as north based clockwise angle between 0 and 360 degree.\nThis parameter also influences the tour generated with `algorithm=round_trip` and forces the initial direction.  Requires `ch.disable=true`.\n",
            "schema": {
              "type": "array",
              "items": {
                "type": "integer",
                "format": "int32"
              }
            },
            "explode": true
          },
          {
            "name": "heading_penalty",
            "in": "query",
            "description": "Time penalty in seconds for not obeying a specified heading. Requires `ch.disable=true`.\n",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 300
            }
          },
          {
            "name": "pass_through",
            "in": "query",
            "description": "If `true`, u-turns are avoided at via-points with regard to the `heading_penalty`. Requires `ch.disable=true`.\n",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "algorithm",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "round_trip",
                "alternative_route"
              ]
            },
            "description": "Rather than looking for the shortest or fastest path, this parameter lets you solve two different problems related to routing:\nWith `alternative_route`, we give you not one but several routes that are close to optimal, but\nnot too similar to each other. \nWith `round_trip`, the route will get you back to where you started. This is meant for fun (think of\na bike trip), so we will add some randomness.\nYou can control both of these features with additional parameters, see below. \n"
          },
          {
            "name": "round_trip.distance",
            "in": "query",
            "description": "If `algorithm=round_trip`, this parameter configures approximative length of the resulting round trip.\n",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 10000
            }
          },
          {
            "name": "round_trip.seed",
            "in": "query",
            "description": "If `algorithm=round_trip`, this sets the random seed. Change this to get a different tour for each value.\n",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "alternative_route.max_paths",
            "in": "query",
            "description": "If `algorithm=alternative_route`, this parameter sets the number of maximum paths which should be calculated. Increasing can lead to worse alternatives.\n",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 2
            }
          },
          {
            "name": "alternative_route.max_weight_factor",
            "in": "query",
            "description": "If `algorithm=alternative_route`, this parameter sets the factor by which the alternatives routes can be longer than the optimal route. Increasing can lead to worse alternatives.\n",
            "schema": {
              "type": "number",
              "default": 1.4
            }
          },
          {
            "name": "alternative_route.max_share_factor",
            "in": "query",
            "description": "If `algorithm=alternative_route`, this parameter specifies how similar an alternative route can be to the optimal route. Increasing can lead to worse alternatives.\n",
            "schema": {
              "type": "number",
              "default": 0.6
            }
          }
        ],
        "tags": [
          "Routing"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "source": "curl \"https://graphhopper.com/api/1/route?point=51.131,12.414&point=48.224,3.867&profile=car&locale=de&calc_points=false&key=api_key\""
          },
          {
            "lang": "Java",
            "source": "OkHttpClient client = new OkHttpClient();\nRequest request = new Request.Builder()\n        .url(\"https://graphhopper.com/api/1/route?point=51.131,12.414&point=48.224,3.867&profile=car&locale=de&calc_points=false&key=api_key\")\n        .get()\n        .build();\n\nResponse response = client.newCall(request).execute();"
          }
        ],
        "responses": {
          "200": {
            "description": "Routing Result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RouteResponse"
                },
                "example": {
                  "hints": {
                    "visited_nodes.sum": 58,
                    "visited_nodes.average": 58
                  },
                  "info": {
                    "copyrights": [
                      "GraphHopper",
                      "OpenStreetMap contributors"
                    ],
                    "took": 2
                  },
                  "paths": [
                    {
                      "distance": 1791.011,
                      "weight": 307.852443,
                      "time": 370962,
                      "transfers": 0,
                      "points_encoded": false,
                      "bbox": [
                        11.539424,
                        48.118343,
                        11.558901,
                        48.122364
                      ],
                      "points": {
                        "type": "LineString",
                        "coordinates": [
                          [
                            11.539424,
                            48.118352
                          ],
                          [
                            11.540387,
                            48.118368
                          ],
                          [
                            11.54061,
                            48.118356
                          ],
                          [
                            11.541941,
                            48.118409
                          ],
                          [
                            11.543696,
                            48.118344
                          ],
                          [
                            11.547167,
                            48.118343
                          ],
                          [
                            11.548478,
                            48.118366
                          ],
                          [
                            11.548487,
                            48.119329
                          ],
                          [
                            11.548807,
                            48.119328
                          ],
                          [
                            11.549408,
                            48.119366
                          ],
                          [
                            11.550349,
                            48.119508
                          ],
                          [
                            11.550441,
                            48.119473
                          ],
                          [
                            11.551109,
                            48.119467
                          ],
                          [
                            11.551553,
                            48.119445
                          ],
                          [
                            11.551748,
                            48.119398
                          ],
                          [
                            11.552087,
                            48.119475
                          ],
                          [
                            11.552236,
                            48.119542
                          ],
                          [
                            11.552353,
                            48.119635
                          ],
                          [
                            11.553853,
                            48.121136
                          ],
                          [
                            11.555448,
                            48.12039
                          ],
                          [
                            11.555797,
                            48.120206
                          ],
                          [
                            11.55632,
                            48.120592
                          ],
                          [
                            11.556716,
                            48.120919
                          ],
                          [
                            11.557326,
                            48.121345
                          ],
                          [
                            11.558901,
                            48.122364
                          ]
                        ]
                      },
                      "instructions": [
                        {
                          "distance": 672.954,
                          "heading": 89.04,
                          "sign": 0,
                          "interval": [
                            0,
                            6
                          ],
                          "text": "Continue onto Lindenschmitstraße",
                          "time": 144703,
                          "street_name": "Lindenschmitstraße"
                        },
                        {
                          "distance": 107.145,
                          "sign": -2,
                          "interval": [
                            6,
                            7
                          ],
                          "text": "Turn left",
                          "time": 22675,
                          "street_name": ""
                        },
                        {
                          "distance": 140.169,
                          "sign": 2,
                          "interval": [
                            7,
                            10
                          ],
                          "text": "Turn right onto Oberländerstraße",
                          "time": 28032,
                          "street_name": "Oberländerstraße"
                        },
                        {
                          "distance": 360.232,
                          "sign": 1,
                          "interval": [
                            10,
                            18
                          ],
                          "text": "Turn slight right",
                          "time": 72677,
                          "street_name": ""
                        },
                        {
                          "distance": 177.621,
                          "sign": 2,
                          "interval": [
                            18,
                            20
                          ],
                          "text": "Turn right onto Thalkirchner Straße",
                          "time": 35524,
                          "street_name": "Thalkirchner Straße"
                        },
                        {
                          "distance": 332.89,
                          "sign": -2,
                          "interval": [
                            20,
                            24
                          ],
                          "text": "Turn left onto Thalkirchner Straße",
                          "time": 67351,
                          "street_name": "Thalkirchner Straße"
                        },
                        {
                          "distance": 0,
                          "sign": 4,
                          "last_heading": 45.67046584987792,
                          "interval": [
                            24,
                            24
                          ],
                          "text": "Arrive at destination",
                          "time": 0,
                          "street_name": ""
                        }
                      ],
                      "legs": [],
                      "details": {},
                      "ascend": 6.3294677734375,
                      "descend": 25.0579833984375,
                      "snapped_waypoints": {
                        "type": "LineString",
                        "coordinates": [
                          [
                            11.539424,
                            48.118352
                          ],
                          [
                            11.558901,
                            48.122364
                          ]
                        ]
                      }
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Your request is not valid. For example, you specified too few or too many points.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GHError"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "description": "Authentication necessary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GHError"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "429": {
            "description": "API limit reached.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GHError"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error. We get notified automatically and fix this asap.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GHError"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        }
      }
    },
    "/isochrone": {
      "get": {
        "summary": "Compute an isochrone",
        "operationId": "getIsochrone",
        "parameters": [
          {
            "name": "point",
            "in": "query",
            "description": "Specify the start coordinate",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "time_limit",
            "in": "query",
            "description": "Specify which time the vehicle should travel. In seconds.",
            "schema": {
              "default": 600,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "distance_limit",
            "in": "query",
            "description": "Specify which distance the vehicle should travel. In meters.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "profile",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/VehicleProfileId"
            }
          },
          {
            "name": "buckets",
            "in": "query",
            "description": "Number by which to divide the given `time_limit` to create `buckets` nested isochrones of time intervals `time_limit-n*time_limit/buckets`. Applies analogously to `distance_limit`.",
            "schema": {
              "default": 1,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "reverse_flow",
            "in": "query",
            "description": "If `false` the flow goes from point to the polygon, if `true` the flow goes from the polygon \"inside\" to the point.\nExample use case for `false`&#58; *How many potential customer can be reached within 30min travel time from your store* vs. `true`&#58; *How many customers can reach your store within 30min travel time.*\n",
            "schema": {
              "default": false,
              "type": "boolean"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "source": "curl \"https://graphhopper.com/api/1/isochrone?point=51.131108,12.414551&key=api_key\""
          },
          {
            "lang": "Java",
            "source": "OkHttpClient client = new OkHttpClient();\nRequest request = new Request.Builder()\n        .url(\"https://graphhopper.com/api/1/isochrone?point=51.131108,12.414551&key=api_key\")\n        .get()\n        .build();\n\nResponse response = client.newCall(request).execute();"
          }
        ],
        "tags": [
          "Isochrones"
        ],
        "responses": {
          "200": {
            "description": "Isochrone Result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IsochroneResponse"
                }
              }
            }
          }
        }
      }
    },
    "/matrix": {
      "post": {
        "summary": "Compute a matrix",
        "description": "Calculate a matrix of travel times and/or distances between N origins and M destinations.\n\nThis includes the common cases of routes from one origin to many destinations, or from many origins to one\ndestination.\n",
        "operationId": "postMatrix",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/MatrixRequest"
                  },
                  {
                    "$ref": "#/components/schemas/SymmetricalMatrixRequest"
                  }
                ]
              }
            }
          }
        },
        "tags": [
          "Matrices"
        ],
        "responses": {
          "200": {
            "description": "Matrix API response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatrixResponse"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "Compute a matrix",
        "description": "For N origins and M destinations, compute routes from all origins to all destinations and output\nthe result as a matrix of travel times and/or distances.\n\nThis includes the common cases of routes from one origin to many destinations, or from many origins to one\ndestination.\n",
        "operationId": "getMatrix",
        "x-codeSamples": [
          {
            "lang": "curl",
            "source": "curl \"https://graphhopper.com/api/1/matrix?point=49.932707,11.588051&point=50.241935,10.747375&point=50.118817,11.983337&type=json&profile=car&out_array=weights&out_array=times&out_array=distances&key=api_key\""
          },
          {
            "lang": "Java",
            "source": "OkHttpClient client = new OkHttpClient();\nRequest request = new Request.Builder()\n        .url(\"https://graphhopper.com/api/1/matrix?point=49.932707,11.588051&point=50.241935,10.747375&point=50.118817,11.983337&type=json&profile=car&out_array=weights&out_array=times&out_array=distances&key=api_key\")\n        .get()\n        .build();\n\nResponse response = client.newCall(request).execute();"
          }
        ],
        "parameters": [
          {
            "name": "profile",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/VehicleProfileId"
            }
          },
          {
            "name": "point",
            "in": "query",
            "description": "Specify multiple points in `latitude,longitude` for which the weight-, route-, time- or distance-matrix should be calculated. In this case the starts are identical to the destinations. If there are N points, then NxN entries will be calculated. The order of the point parameter is important. Specify at least three points. Cannot be used together with from_point or to_point.",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "explode": true
          },
          {
            "name": "from_point",
            "in": "query",
            "description": "The origin points for the routes in `latitude,longitude`. E.g. if you want to calculate the three routes A-&gt;1, A-&gt;2, A-&gt;3 then you have one from_point parameter and three to_point parameters.",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "explode": true
          },
          {
            "name": "to_point",
            "in": "query",
            "description": "The destination points for the routes in `latitude,longitude`.",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "explode": true
          },
          {
            "name": "point_hint",
            "in": "query",
            "description": "Optional parameter. Specifies a hint for each `point` parameter to prefer a certain street for the closest location lookup. 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.",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "explode": true
          },
          {
            "name": "from_point_hint",
            "in": "query",
            "description": "For the from_point parameter. See point_hint",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "explode": true
          },
          {
            "name": "to_point_hint",
            "in": "query",
            "description": "For the to_point parameter. See point_hint",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "explode": true
          },
          {
            "name": "snap_prevention",
            "in": "query",
            "description": "Optional parameter. 'Snapping' is the process of finding the closest road location for GPS coordinates provided in the `point` parameter. The `snap_prevention` parameter allows you to prevent snapping to specific types of roads. For example, if `snap_prevention` is set to bridge, the routing engine will avoid snapping to a bridge, even if it is the closest road for the given `point`. Current supported values: `motorway`, `trunk`, `ferry`, `tunnel`, `bridge` and `ford`. Multiple values are specified like `snap_prevention=ferry&snap_prevention=motorway`. Note that once snapped the routing algorithm can still route over bridges (or the other values). To avoid this you need to use the `custom_model`.\n",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "explode": true
          },
          {
            "name": "curbside",
            "in": "query",
            "description": "Optional parameter. It specifies on which side a point should be relative to the driver when she leaves/arrives at a start/target/via point. You need to specify this parameter for either none or all points. Only supported for motor vehicles and OpenStreetMap.",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "any",
                  "right",
                  "left"
                ]
              }
            },
            "explode": true
          },
          {
            "name": "from_curbside",
            "in": "query",
            "description": "Curbside setting for the from_point parameter. See curbside.",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "any",
                  "right",
                  "left"
                ]
              }
            },
            "explode": true
          },
          {
            "name": "to_curbside",
            "in": "query",
            "description": "Curbside setting for the to_point parameter. See curbside.",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "any",
                  "right",
                  "left"
                ]
              }
            },
            "explode": true
          },
          {
            "name": "out_array",
            "in": "query",
            "description": "Specifies which arrays should be included in the response. Specify one or more of the following options 'weights', 'times', 'distances'. To specify more than one array use e.g. out_array=times&out_array=distances. The units of the entries of distances are meters, of times are seconds and of weights is arbitrary and it can differ for different vehicles or versions of this API.",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "explode": true
          },
          {
            "name": "fail_fast",
            "in": "query",
            "description": "Specifies whether or not the matrix calculation should return with an error as soon as possible in case some points cannot be found or some points are not connected. If set to `false` the time/weight/distance matrix will be calculated for all valid points and contain the `null` value for all entries that could not be calculated. The `hint` field of the response will also contain additional information about what went wrong (see its documentation).",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true
            }
          }
        ],
        "tags": [
          "Matrices"
        ],
        "responses": {
          "200": {
            "description": "Matrix API response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatrixResponse"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        }
      }
    },
    "/matrix/calculate": {
      "post": {
        "summary": "Submit a matrix computation job",
        "operationId": "calculateMatrix",
        "description": "An alternate endpoint for computing a large matrix asynchronously, where a request against the regular \nendpoint would result in a timeout.\n\nThe request format is the same, but instead of the result, you are given a job identification number that\nyou can use to retrieve the result once it is available.\n        \nIn most cases, prefer the regular endpoints.\n\nHere are some full examples via curl:\n```bash\n$ curl -X POST -H \"Content-Type: application/json\" \"https://graphhopper.com/api/1/matrix/calculate?key=[YOUR_KEY]\" -d '{\"points\":[[13.29895,52.48696],[13.370876,52.489575],[13.439026,52.511206]]}'\n{\"job_id\":\"7ac65787-fb99-4e02-a832-2c3010c70097\"}\n```\n\nPick the returned `job_id` and use it in the next GET requests:\n```bash\n$ curl -X GET \"https://graphhopper.com/api/1/matrix/solution/7ac65787-fb99-4e02-a832-2c3010c70097?key=[YOUR_KEY]\"\n{\"status\":\"waiting\"}\n```\n\nWhen the calculation is finished (`status:finished`) the JSON response will contain the full matrix JSON under `solution`:\n```bash\n$ curl -X GET \"https://graphhopper.com/api/1/matrix/solution/7ac65787-fb99-4e02-a832-2c3010c70097?key=[YOUR_KEY]\"\n{\"solution\":{\"weights\":[[0.0,470.453,945.414],[503.793,0.0,580.871],[970.49,569.511,0.0]],\"info\":{\"copyrights\":[\"GraphHopper\",\"OpenStreetMap contributors\"]}},\"status\":\"finished\"}\n```\n\nPlease note that if an error occured while calculation the JSON will not have a status but contain directly the error message e.g.:\n```json\n{\"message\":\"Cannot find from_points: 1\"}\n```\nAnd the optional `hints` array.\n",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/MatrixRequest"
                  },
                  {
                    "$ref": "#/components/schemas/SymmetricalMatrixRequest"
                  }
                ]
              }
            }
          }
        },
        "tags": [
          "Matrices"
        ],
        "responses": {
          "200": {
            "description": "A jobId you can use to retrieve your solution from the server.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobId"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        }
      }
    },
    "/matrix/solution/{jobId}": {
      "get": {
        "summary": "Retrieve result of a matrix computation job",
        "operationId": "getMatrixSolution",
        "parameters": [
          {
            "in": "path",
            "name": "jobId",
            "description": "The jobId you received when you submitted the job.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "Matrices"
        ],
        "responses": {
          "200": {
            "description": "A response containing the matrix",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "solution": {
                      "$ref": "#/components/schemas/MatrixResponse"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "processing",
                        "finished"
                      ]
                    }
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        }
      }
    },
    "/match": {
      "post": {
        "summary": "Map-match a GPX file",
        "operationId": "postGPX",
        "description": "To get a match response you send a GPX file in the body of an HTTP POST request and specify request parameters like the `key` and `profile` in the URL.\nSee below for more supported parameters.\n",
        "x-codeSamples": [
          {
            "lang": "curl",
            "source": "curl -XPOST -H \"Content-Type: application/gpx+xml\" \"https://graphhopper.com/api/1/match?profile=car&key=[YOUR_KEY]\" -d '\n  <gpx>\n    <trk>\n      <trkseg>\n        <trkpt lat=\"51.343657\" lon=\"12.360708\"></trkpt>\n        <trkpt lat=\"51.343796\" lon=\"12.361337\"></trkpt>\n        <trkpt lat=\"51.342784\" lon=\"12.361882\"></trkpt>\n      </trkseg>\n    </trk>\n  </gpx>'\n"
          },
          {
            "lang": "Java",
            "source": "OkHttpClient client = new OkHttpClient();\nRequestBody body = RequestBody.create(\"<gpx>\" +\n    \" <trk>\" +\n    \"  <trkseg>\" +\n    \"   <trkpt lat=\\\"51.343657\\\" lon=\\\"12.360708\\\"></trkpt>\" +\n    \"   <trkpt lat=\\\"51.343796\\\" lon=\\\"12.361337\\\"></trkpt>\" +\n    \"   <trkpt lat=\\\"51.342784\\\" lon=\\\"12.361882\\\"></trkpt>\" +\n    \"  </trkseg>\" +\n    \" </trk>\" +\n    \"</gpx>\", MediaType.parse(\"application/gpx+xml\"));\nRequest request = new Request.Builder()\n    .url(\"https://graphhopper.com/api/1/match?profile=car&key=[YOUR_KEY]\")\n    .post(body)\n    .build();\n\nResponse response = client.newCall(request).execute();\n"
          }
        ],
        "tags": [
          "Map Matching"
        ],
        "parameters": [
          {
            "name": "gps_accuracy",
            "in": "query",
            "description": "Specify the precision of a point, in meter",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "profile",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/VehicleProfileId"
            }
          },
          {
            "name": "locale",
            "in": "query",
            "description": "The locale of the resulting turn instructions. E.g. `pt_PT` for Portuguese or `de` for German.\n",
            "schema": {
              "type": "string",
              "default": "en"
            }
          },
          {
            "name": "elevation",
            "in": "query",
            "description": "If `true`, a third coordinate, the altitude, is included with all positions in the response.\nThis changes the format of the `points` and `snapped_waypoints` fields of the response, in both their\nencodings. Unless you switch off the `points_encoded` parameter, you need special code on the\nclient side that can handle three-dimensional coordinates.\n",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "details",
            "in": "query",
            "description": "Optional parameter. The following path details are available: `street_name`, `street_ref`, `street_destination`, `leg_time`, `leg_distance`, `roundabout`, `country`, `time`, `distance`, `max_speed`,\n`max_weight`, `max_width`, `toll`, `road_class`, `road_class_link`, `road_access`, `road_environment`, `hazmat`, `hazmat_tunnel`, `hazmat_water`, \n`lanes`, `surface`, `smoothness`, `hike_rating`, `mtb_rating`, `foot_network`, `bike_network`. Read more about the usage of path details [here](https://discuss.graphhopper.com/t/2539).\n",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "explode": true
          },
          {
            "name": "instructions",
            "in": "query",
            "description": "If instructions should be calculated and returned\n",
            "schema": {
              "type": "boolean",
              "default": true
            }
          },
          {
            "name": "calc_points",
            "in": "query",
            "description": "If the points for the route should be calculated at all.\n",
            "schema": {
              "type": "boolean",
              "default": true
            }
          },
          {
            "name": "points_encoded",
            "in": "query",
            "description": "Allows changing the encoding of location data in the response. The default is polyline encoding, which is compact\nbut requires special client code to unpack. (We provide it in our JavaScript client library!)\nSet this parameter to `false` to switch the encoding to simple coordinate pairs like `[lon,lat]`, or `[lon,lat,elevation]`.\nSee the description of the response format for more information.\n",
            "schema": {
              "type": "boolean",
              "default": true
            }
          }
        ],
        "requestBody": {
          "description": "A GPX document containing the map-matching input.",
          "content": {
            "application/gpx+xml": {
              "example": "<gpx>\n  <trk>\n    <trkseg>\n      <trkpt lat=\"51.343657\" lon=\"12.360708\"></trkpt>\n      <trkpt lat=\"51.343796\" lon=\"12.361337\"></trkpt>\n      <trkpt lat=\"51.342784\" lon=\"12.361882\"></trkpt>\n    </trkseg>\n  </trk>\n</gpx>\n"
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Map matching result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RouteResponse"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        }
      }
    },
    "/geocode": {
      "get": {
        "summary": "Geocoding Endpoint",
        "operationId": "getGeocode",
        "x-codeSamples": [
          {
            "lang": "curl",
            "source": "curl \"https://graphhopper.com/api/1/geocode?q=berlin&locale=de&key=api_key\""
          },
          {
            "lang": "Java",
            "source": "OkHttpClient client = new OkHttpClient();\nRequest request = new Request.Builder()\n        .url(\"https://graphhopper.com/api/1/geocode?q=berlin&locale=de&key=api_key\")\n        .get()\n        .build();\n\nResponse response = client.newCall(request).execute();"
          }
        ],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "description": "A textual description of the address you are looking for. Required for forward geocoding. Note that the `default` geocoding provider does prefix searches preferable for \"autocomplete\" use cases, but\nmay lead to sub-optimal results if used without user interaction. See e.g. `provider=nominatim` as an appropriate alternative for less interactive use cases.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "locale",
            "in": "query",
            "description": "Display the search results for the specified locale. For the default provider French (fr), English (en) and German (de) are supported. Otherwise leave the locale empty.",
            "schema": {
              "type": "string",
              "default": "en - for default provider"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Specify the maximum number of results to return",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 5
            }
          },
          {
            "name": "reverse",
            "in": "query",
            "description": "It is `required` to be `true` if you want to do a reverse geocoding request. If it is `true`, `point` must be defined as well, and `q` must not be used.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "debug",
            "in": "query",
            "description": "If `true`, the output will be formatted.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "point",
            "in": "query",
            "description": "_Forward geocoding_: The location bias in the format 'latitude,longitude' e.g. point=45.93272,11.58803. _Reverse geocoding_: The location to find amenities, cities.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "provider",
            "in": "query",
            "description": "The provider parameter is currently under development and can fall back to `default` at any time.\nThe intend is to provide alternatives to our default geocoder. Each provider has its own strenghts and might fit better for certain scenarios, so it's worth to compare the different providers.\nTo try it append the `provider`parameter to the URL like `&provider=nominatim`,\nthe result structure should be identical in all cases - if not, please report this back to us.\nKeep in mind that some providers do not support certain parameters or don't return some fields, for example `osm_id` and `osm_type` are not supported by every geocoding provider.\nIf you would like to use additional parameters of one of the providers, but it's not available for the GraphHopper Geocoding API, yet? Please contact us.\n\nThe credit costs can be different for all providers - see [here](https://support.graphhopper.com/support/solutions/articles/44000718211-what-is-one-credit-) for more information about it.\n\nCurrently, only the default provider and gisgraphy support autocompletion of partial search strings.\n\nAll providers support normal \"forward\" geocoding and reverse geocoding via `reverse=true`.\n\n#### Default (`provider=default`)\n\nThis provider returns results of our internal geocoding engine. It is best suited for use cases with user interaction as it does prefix searches required for an \"autocomplete\" use case\n(a user types an address into a search field).\n\nIn addition to the above documented parameters the following parameters are possible:\n\n* `osm_tag` - you can filter `key:value` or exclude places with certain OpenStreetMap tags `!key:value`. E.g. `osm_tag=tourism:museum` or just the key `osm_tag=tourism`. To exclude multiple tags you add multiple `osm_tag` parameters.\n* `location_bias_scale` - describes how much the prominence of a result should still be taken into account. Sensible values go from 0.0 (ignore prominence almost completely) to 1.0 (prominence has approximately the same influence as the location). The default is 0.2.\n* `zoom` - describes the radius around the center to focus on. This is a number that should correspond roughly to the map zoom parameter of a corresponding map. The default is zoom=16.\n* `bbox` - the expected format is `minLon,minLat,maxLon,maxLat`. This requires reverse=false.\n* `radius` - the search radius in km for the reverse search. This requires reverse=true.\n\n#### Nominatim (`provider=nominatim`)\n\nThe GraphHopper Directions API uses a commercially hosted Nominatim geocoder (hosted by [OpenCageData](https://opencagedata.com/)). It is best suited for use cases without or less user interaction\nlike batch processing or detailed location data retrieval. It is not suited for \"autocomplete\".\n\nIn addition to the above documented parameters we currently support the following parameters:\n\n* countrycode - The country code is a two letter code as defined by the ISO 3166-1 Alpha 2 standard. E.g. gb for the United Kingdom, fr for France, us for United States.\n* bounds - the expected format is `minLon,minLat,maxLon,maxLat`\n\n#### Gisgraphy (`provider=gisgraphy`)\n\nThis provider returns results from the Gisgraphy geocoder which you can try [here](https://services.gisgraphy.com/static/leaflet/index.html).\n\n**Limitations:** The `locale` parameter is not supported. Gisgraphy does not return OSM tags or an extent.\n\nGisgraphy has a special autocomplete API, which you can use by adding `autocomplete=true` (does not work with `reverse=true`). The autocomplete API is optimized on predicting text input, but returns less information.\n\nIn addition to the above documented parameters Gisgraphy allows to use the following parameters, which can be used as documented [here](https://www.gisgraphy.com/documentation/user-guide.php#geocodingservice):\n\n* `radius` - radius in meters\n* `country` - restrict search for the specified country. The value must be the ISO 3166 Alpha 2 code of the country.\n\n#### OpenCage Data (`provider=opencagedata`)\n\nThis provider returns results from the OpenCageData geocoder which you can try [here](https://geocoder.opencagedata.com/demo).\nThe difference to the `nominatim` provider is that [other geocoders](https://opencagedata.com/credits) might be used under the hood.\n\nIn addition to the above documented parameters OpenCage Data allows to use the following parameters, which can be used as documented [here](https://geocoder.opencagedata.com/api#forward-opt):\n\n* countrycode - The country code is a two letter code as defined by the ISO 3166-1 Alpha 2 standard. E.g. gb for the United Kingdom, fr for France, us for United States. \n* bounds - the expected format is `minLon,minLat,maxLon,maxLat`\n",
            "schema": {
              "type": "string",
              "default": "default"
            }
          }
        ],
        "tags": [
          "Geocoding"
        ],
        "responses": {
          "200": {
            "description": "An array found locations",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GeocodingResponse"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        }
      }
    },
    "/vrp": {
      "post": {
        "summary": "Solve a route optimization problem",
        "description": "\nStart by reading the [introduction](#tag/Route-Optimization-API) to the 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=<your_key>\n```\n\nIt returns the solution to this problem in the JSON response.\n\nPlease note that this endpoint is well suited for solving smaller problems.\nLarger vehicle routing problems that take longer than 10 seconds to solve cannot be processed using this endpoint.\nTo solve them, please use the [batch mode URL](#operation/asyncVRP) instead.\n",
        "operationId": "solveVRP",
        "requestBody": {
          "description": "The request that contains the vehicle routing problem to be solved.",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Request"
              },
              "example": {
                "vehicles": [
                  {
                    "vehicle_id": "vehicle-1",
                    "type_id": "cargo-bike",
                    "start_address": {
                      "location_id": "berlin",
                      "lon": 13.406,
                      "lat": 52.537
                    },
                    "earliest_start": 1554804329,
                    "latest_end": 1554808329,
                    "max_jobs": 3
                  },
                  {
                    "vehicle_id": "vehicle-2",
                    "type_id": "cargo-bike",
                    "start_address": {
                      "location_id": "berlin",
                      "lon": 13.406,
                      "lat": 52.537
                    },
                    "earliest_start": 1554804329,
                    "latest_end": 1554808329,
                    "max_jobs": 3,
                    "skills": [
                      "physical strength"
                    ]
                  }
                ],
                "vehicle_types": [
                  {
                    "type_id": "cargo-bike",
                    "capacity": [
                      10
                    ],
                    "profile": "bike"
                  }
                ],
                "services": [
                  {
                    "id": "s-1",
                    "name": "visit-Joe",
                    "address": {
                      "location_id": "13.375854_52.537338",
                      "lon": 13.375854,
                      "lat": 52.537338
                    },
                    "size": [
                      1
                    ],
                    "time_windows": [
                      {
                        "earliest": 1554805329,
                        "latest": 1554806329
                      }
                    ]
                  },
                  {
                    "id": "s-2",
                    "name": "serve-Peter",
                    "address": {
                      "location_id": "13.393364_52.525851",
                      "lon": 13.393364,
                      "lat": 52.525851
                    },
                    "size": [
                      1
                    ]
                  },
                  {
                    "id": "s-3",
                    "name": "visit-Michael",
                    "address": {
                      "location_id": "13.416882_52.523543",
                      "lon": 13.416882,
                      "lat": 52.523543
                    },
                    "size": [
                      1
                    ]
                  },
                  {
                    "id": "s-4",
                    "name": "do nothing",
                    "address": {
                      "location_id": "13.395767_52.514038",
                      "lon": 13.395767,
                      "lat": 52.514038
                    },
                    "size": [
                      1
                    ]
                  }
                ],
                "shipments": [
                  {
                    "id": "7fe77504-7df8-4497-843c-02d70b6490ce",
                    "name": "pickup and deliver pizza to Peter",
                    "priority": 1,
                    "pickup": {
                      "address": {
                        "location_id": "13.387613_52.529961",
                        "lon": 13.387613,
                        "lat": 52.529961
                      }
                    },
                    "delivery": {
                      "address": {
                        "location_id": "13.380575_52.513614",
                        "lon": 13.380575,
                        "lat": 52.513614
                      }
                    },
                    "size": [
                      1
                    ],
                    "required_skills": [
                      "physical strength"
                    ]
                  }
                ],
                "objectives": [
                  {
                    "type": "min",
                    "value": "vehicles"
                  },
                  {
                    "type": "min",
                    "value": "completion_time"
                  }
                ],
                "configuration": {
                  "routing": {
                    "calc_points": true,
                    "snap_preventions": [
                      "motorway",
                      "trunk",
                      "tunnel",
                      "bridge",
                      "ferry"
                    ]
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Route Optimization"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "source": "curl -X POST -H \"Content-Type: application/json\"   \"https://graphhopper.com/api/1/vrp?key=api_key\"   -d '{\n  \"vehicles\": [\n    {\n      \"vehicle_id\": \"my_vehicle\",\n      \"start_address\": {\n        \"location_id\": \"berlin\",\n        \"lon\": 13.406,\n        \"lat\": 52.537\n      }\n    }\n  ],\n  \"services\": [\n    {\n      \"id\": \"hamburg\",\n      \"name\": \"visit_hamburg\",\n      \"address\": {\n        \"location_id\": \"hamburg\",\n        \"lon\": 9.999,\n        \"lat\": 53.552\n      }\n    },\n    { \n     \"id\": \"munich\",\n      \"name\": \"visit_munich\",\n      \"address\": {\n        \"location_id\": \"munich\",\n        \"lon\": 11.57,\n        \"lat\": 48.145\n      }\n    }\n  ]}'"
          },
          {
            "lang": "Java",
            "source": "OkHttpClient client = new OkHttpClient();\nMediaType mediaType = MediaType.parse(\"application/json\");\nRequestBody body = RequestBody.create(mediaType, \"{\\n  \\\"vehicles\\\": [\\n    {\\n      \\\"vehicle_id\\\": \\\"my_vehicle\\\",\\n      \\\"start_address\\\": {\\n        \\\"location_id\\\": \\\"berlin\\\",\\n        \\\"lon\\\": 13.406,\\n        \\\"lat\\\": 52.537\\n      }\\n    }\\n  ],\\n  \\\"services\\\": [\\n    {\\n      \\\"id\\\": \\\"hamburg\\\",\\n      \\\"name\\\": \\\"visit_hamburg\\\",\\n      \\\"address\\\": {\\n        \\\"location_id\\\": \\\"hamburg\\\",\\n        \\\"lon\\\": 9.999,\\n        \\\"lat\\\": 53.552\\n      }\\n    },\\n    { \\n     \\\"id\\\": \\\"munich\\\",\\n      \\\"name\\\": \\\"visit_munich\\\",\\n      \\\"address\\\": {\\n        \\\"location_id\\\": \\\"munich\\\",\\n        \\\"lon\\\": 11.57,\\n        \\\"lat\\\": 48.145\\n      }\\n    }\\n  ]}\");\nRequest request = new Request.Builder()\n        .url(\"https://graphhopper.com/api/1/vrp?key=api_key\")\n        .post(body)\n        .addHeader(\"content-type\", \"application/json\")\n        .build();\n\nResponse response = client.newCall(request).execute();"
          }
        ],
        "responses": {
          "200": {
            "description": "A response containing the solution",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Response"
                },
                "example": {
                  "copyrights": [
                    "GraphHopper",
                    "OpenStreetMap contributors"
                  ],
                  "job_id": "d62fcadd-c84a-4298-90b5-28550125bec5",
                  "status": "finished",
                  "waiting_time_in_queue": 0,
                  "processing_time": 459,
                  "solution": {
                    "costs": 438,
                    "distance": 17994,
                    "time": 4094,
                    "transport_time": 4094,
                    "completion_time": 4172,
                    "max_operation_time": 2465,
                    "waiting_time": 78,
                    "service_duration": 0,
                    "preparation_time": 0,
                    "no_vehicles": 2,
                    "no_unassigned": 0,
                    "routes": [
                      {
                        "vehicle_id": "vehicle-2",
                        "distance": 10618,
                        "transport_time": 2465,
                        "completion_time": 2465,
                        "waiting_time": 0,
                        "service_duration": 0,
                        "preparation_time": 0,
                        "points": [
                          {
                            "coordinates": [
                              [
                                13.40608,
                                52.53701
                              ],
                              [
                                13.40643,
                                52.53631
                              ],
                              [
                                13.40554,
                                52.53616
                              ],
                              [
                                13.4054,
                                52.53608
                              ],
                              [
                                13.40445,
                                52.53513
                              ],
                              [
                                13.40436,
                                52.53509
                              ],
                              [
                                13.40428,
                                52.53508
                              ],
                              [
                                13.40463,
                                52.53419
                              ],
                              [
                                13.40451,
                                52.53419
                              ],
                              [
                                13.4034,
                                52.53401
                              ],
                              [
                                13.403,
                                52.53359
                              ],
                              [
                                13.40291,
                                52.53354
                              ],
                              [
                                13.40268,
                                52.53347
                              ],
                              [
                                13.39888,
                                52.53259
                              ],
                              [
                                13.39839,
                                52.53253
                              ],
                              [
                                13.39812,
                                52.53251
                              ],
                              [
                                13.39616,
                                52.53243
                              ],
                              [
                                13.39579,
                                52.5324
                              ],
                              [
                                13.38973,
                                52.53173
                              ],
                              [
                                13.39163,
                                52.53025
                              ],
                              [
                                13.38797,
                                52.52935
                              ],
                              [
                                13.38763,
                                52.52996
                              ]
                            ],
                            "type": "LineString"
                          },
                          {
                            "coordinates": [
                              [
                                13.38763,
                                52.52996
                              ],
                              [
                                13.38739,
                                52.53039
                              ],
                              [
                                13.38724,
                                52.53036
                              ],
                              [
                                13.38464,
                                52.52929
                              ],
                              [
                                13.38538,
                                52.52871
                              ],
                              [
                                13.38634,
                                52.52792
                              ],
                              [
                                13.38638,
                                52.52779
                              ],
                              [
                                13.38657,
                                52.52763
                              ],
                              [
                                13.38676,
                                52.52741
                              ],
                              [
                                13.38698,
                                52.52713
                              ],
                              [
                                13.38704,
                                52.52701
                              ],
                              [
                                13.38753,
                                52.524
                              ],
                              [
                                13.3877,
                                52.52307
                              ],
                              [
                                13.3878,
                                52.52282
                              ],
                              [
                                13.38788,
                                52.52252
                              ],
                              [
                                13.38802,
                                52.52174
                              ],
                              [
                                13.38519,
                                52.52009
                              ],
                              [
                                13.38539,
                                52.5191
                              ],
                              [
                                13.38548,
                                52.51852
                              ],
                              [
                                13.38042,
                                52.51819
                              ],
                              [
                                13.38071,
                                52.5167
                              ],
                              [
                                13.38076,
                                52.51652
                              ],
                              [
                                13.38084,
                                52.51634
                              ],
                              [
                                13.3821,
                                52.51396
                              ],
                              [
                                13.38055,
                                52.51365
                              ]
                            ],
                            "type": "LineString"
                          },
                          {
                            "coordinates": [
                              [
                                13.38055,
                                52.51365
                              ],
                              [
                                13.38229,
                                52.514
                              ],
                              [
                                13.38363,
                                52.51429
                              ],
                              [
                                13.3848,
                                52.51445
                              ],
                              [
                                13.38504,
                                52.51358
                              ],
                              [
                                13.39124,
                                52.51397
                              ],
                              [
                                13.3911,
                                52.51488
                              ],
                              [
                                13.39303,
                                52.51499
                              ],
                              [
                                13.39317,
                                52.5141
                              ],
                              [
                                13.39548,
                                52.51419
                              ],
                              [
                                13.39571,
                                52.51421
                              ]
                            ],
                            "type": "LineString"
                          },
                          {
                            "coordinates": [
                              [
                                13.39571,
                                52.51421
                              ],
                              [
                                13.39695,
                                52.51434
                              ],
                              [
                                13.39674,
                                52.51523
                              ],
                              [
                                13.39742,
                                52.51531
                              ],
                              [
                                13.39873,
                                52.51558
                              ],
                              [
                                13.39846,
                                52.51599
                              ],
                              [
                                13.39825,
                                52.51729
                              ],
                              [
                                13.39805,
                                52.51755
                              ],
                              [
                                13.39892,
                                52.51761
                              ],
                              [
                                13.39917,
                                52.51764
                              ],
                              [
                                13.39964,
                                52.51775
                              ],
                              [
                                13.40009,
                                52.51791
                              ],
                              [
                                13.40034,
                                52.51797
                              ],
                              [
                                13.4021,
                                52.51864
                              ],
                              [
                                13.40288,
                                52.51896
                              ],
                              [
                                13.40375,
                                52.51936
                              ],
                              [
                                13.40498,
                                52.52001
                              ],
                              [
                                13.40463,
                                52.5203
                              ],
                              [
                                13.40311,
                                52.52144
                              ],
                              [
                                13.40442,
                                52.52189
                              ],
                              [
                                13.40448,
                                52.52192
                              ],
                              [
                                13.40451,
                                52.52195
                              ],
                              [
                                13.40473,
                                52.52199
                              ],
                              [
                                13.40504,
                                52.52208
                              ],
                              [
                                13.40572,
                                52.52235
                              ],
                              [
                                13.40687,
                                52.52294
                              ],
                              [
                                13.40693,
                                52.52299
                              ],
                              [
                                13.40706,
                                52.52319
                              ],
                              [
                                13.40738,
                                52.52378
                              ],
                              [
                                13.40787,
                                52.52443
                              ],
                              [
                                13.4079,
                                52.52453
                              ],
                              [
                                13.40938,
                                52.52401
                              ],
                              [
                                13.40962,
                                52.52398
                              ],
                              [
                                13.41001,
                                52.52395
                              ],
                              [
                                13.41072,
                                52.52391
                              ],
                              [
                                13.41215,
                                52.52389
                              ],
                              [
                                13.41233,
                                52.52386
                              ],
                              [
                                13.4131,
                                52.5235
                              ],
                              [
                                13.41288,
                                52.52333
                              ],
                              [
                                13.41475,
                                52.52247
                              ],
                              [
                                13.41496,
                                52.52264
                              ],
                              [
                                13.41523,
                                52.52251
                              ],
                              [
                                13.41633,
                                52.52338
                              ],
                              [
                                13.41631,
                                52.52346
                              ],
                              [
                                13.41654,
                                52.52364
                              ],
                              [
                                13.41684,
                                52.52351
                              ]
                            ],
                            "type": "LineString"
                          },
                          {
                            "coordinates": [
                              [
                                13.41684,
                                52.52351
                              ],
                              [
                                13.41654,
                                52.52364
                              ],
                              [
                                13.41631,
                                52.52346
                              ],
                              [
                                13.4163,
                                52.52344
                              ],
                              [
                                13.41587,
                                52.52363
                              ],
                              [
                                13.41572,
                                52.5235
                              ],
                              [
                                13.41409,
                                52.5242
                              ],
                              [
                                13.41454,
                                52.52461
                              ],
                              [
                                13.41454,
                                52.52466
                              ],
                              [
                                13.41358,
                                52.52508
                              ],
                              [
                                13.41366,
                                52.52514
                              ],
                              [
                                13.41344,
                                52.52525
                              ],
                              [
                                13.4133,
                                52.52514
                              ],
                              [
                                13.41316,
                                52.5252
                              ],
                              [
                                13.41107,
                                52.52585
                              ],
                              [
                                13.41118,
                                52.52606
                              ],
                              [
                                13.41118,
                                52.52616
                              ],
                              [
                                13.41095,
                                52.52664
                              ],
                              [
                                13.41097,
                                52.52678
                              ],
                              [
                                13.41084,
                                52.52706
                              ],
                              [
                                13.41057,
                                52.52747
                              ],
                              [
                                13.41028,
                                52.52809
                              ],
                              [
                                13.41032,
                                52.52821
                              ],
                              [
                                13.4102,
                                52.52847
                              ],
                              [
                                13.40999,
                                52.52875
                              ],
                              [
                                13.40984,
                                52.52905
                              ],
                              [
                                13.40982,
                                52.52914
                              ],
                              [
                                13.40984,
                                52.52926
                              ],
                              [
                                13.4104,
                                52.52998
                              ],
                              [
                                13.4105,
                                52.53001
                              ],
                              [
                                13.41064,
                                52.53016
                              ],
                              [
                                13.41082,
                                52.5303
                              ],
                              [
                                13.41198,
                                52.53107
                              ],
                              [
                                13.4122,
                                52.53128
                              ],
                              [
                                13.41232,
                                52.53143
                              ],
                              [
                                13.41247,
                                52.53192
                              ],
                              [
                                13.41267,
                                52.53245
                              ],
                              [
                                13.41275,
                                52.53259
                              ],
                              [
                                13.41215,
                                52.5327
                              ],
                              [
                                13.40731,
                                52.53463
                              ],
                              [
                                13.40608,
                                52.53701
                              ]
                            ],
                            "type": "LineString"
                          }
                        ],
                        "activities": [
                          {
                            "type": "start",
                            "location_id": "berlin",
                            "address": {
                              "location_id": "berlin",
                              "lat": 52.537,
                              "lon": 13.406
                            },
                            "end_time": 1554804329,
                            "end_date_time": null,
                            "distance": 0,
                            "driving_time": 0,
                            "preparation_time": 0,
                            "waiting_time": 0,
                            "load_after": [
                              0
                            ]
                          },
                          {
                            "type": "pickupShipment",
                            "id": "7fe77504-7df8-4497-843c-02d70b6490ce",
                            "location_id": "13.387613_52.529961",
                            "address": {
                              "location_id": "13.387613_52.529961",
                              "lat": 52.529961,
                              "lon": 13.387613
                            },
                            "arr_time": 1554804789,
                            "arr_date_time": null,
                            "end_time": 1554804789,
                            "end_date_time": null,
                            "waiting_time": 0,
                            "distance": 2012,
                            "driving_time": 460,
                            "preparation_time": 0,
                            "load_before": [
                              0
                            ],
                            "load_after": [
                              1
                            ]
                          },
                          {
                            "type": "deliverShipment",
                            "id": "7fe77504-7df8-4497-843c-02d70b6490ce",
                            "location_id": "13.380575_52.513614",
                            "address": {
                              "location_id": "13.380575_52.513614",
                              "lat": 52.513614,
                              "lon": 13.380575
                            },
                            "arr_time": 1554805344,
                            "arr_date_time": null,
                            "end_time": 1554805344,
                            "end_date_time": null,
                            "waiting_time": 0,
                            "distance": 4560,
                            "driving_time": 1015,
                            "preparation_time": 0,
                            "load_before": [
                              1
                            ],
                            "load_after": [
                              0
                            ]
                          },
                          {
                            "type": "service",
                            "id": "s-4",
                            "location_id": "13.395767_52.514038",
                            "address": {
                              "location_id": "13.395767_52.514038",
                              "lat": 52.514038,
                              "lon": 13.395767
                            },
                            "arr_time": 1554805632,
                            "arr_date_time": null,
                            "end_time": 1554805632,
                            "end_date_time": null,
                            "waiting_time": 0,
                            "distance": 5887,
                            "driving_time": 1303,
                            "preparation_time": 0,
                            "load_before": [
                              0
                            ],
                            "load_after": [
                              1
                            ]
                          },
                          {
                            "type": "service",
                            "id": "s-3",
                            "location_id": "13.416882_52.523543",
                            "address": {
                              "location_id": "13.416882_52.523543",
                              "lat": 52.523543,
                              "lon": 13.416882
                            },
                            "arr_time": 1554806253,
                            "arr_date_time": null,
                            "end_time": 1554806253,
                            "end_date_time": null,
                            "waiting_time": 0,
                            "distance": 8486,
                            "driving_time": 1924,
                            "preparation_time": 0,
                            "load_before": [
                              1
                            ],
                            "load_after": [
                              2
                            ]
                          },
                          {
                            "type": "end",
                            "location_id": "berlin",
                            "address": {
                              "location_id": "berlin",
                              "lat": 52.537,
                              "lon": 13.406
                            },
                            "arr_time": 1554806794,
                            "arr_date_time": null,
                            "distance": 10618,
                            "driving_time": 2465,
                            "preparation_time": 0,
                            "waiting_time": 0,
                            "load_before": [
                              2
                            ]
                          }
                        ]
                      },
                      {
                        "vehicle_id": "vehicle-1",
                        "distance": 7376,
                        "transport_time": 1629,
                        "completion_time": 1707,
                        "waiting_time": 78,
                        "service_duration": 0,
                        "preparation_time": 0,
                        "points": [
                          {
                            "coordinates": [
                              [
                                13.40608,
                                52.53701
                              ],
                              [
                                13.40674,
                                52.53571
                              ],
                              [
                                13.40433,
                                52.53313
                              ],
                              [
                                13.40271,
                                52.53149
                              ],
                              [
                                13.40246,
                                52.53121
                              ],
                              [
                                13.40148,
                                52.52999
                              ],
                              [
                                13.40128,
                                52.52993
                              ],
                              [
                                13.40118,
                                52.52988
                              ],
                              [
                                13.40133,
                                52.5296
                              ],
                              [
                                13.40138,
                                52.52951
                              ],
                              [
                                13.40167,
                                52.52914
                              ],
                              [
                                13.40188,
                                52.52895
                              ],
                              [
                                13.398,
                                52.52885
                              ],
                              [
                                13.39289,
                                52.52748
                              ],
                              [
                                13.39354,
                                52.5264
                              ],
                              [
                                13.39358,
                                52.52628
                              ],
                              [
                                13.39324,
                                52.52575
                              ],
                              [
                                13.39334,
                                52.52573
                              ],
                              [
                                13.39339,
                                52.52584
                              ]
                            ],
                            "type": "LineString"
                          },
                          {
                            "coordinates": [
                              [
                                13.39339,
                                52.52584
                              ],
                              [
                                13.3934,
                                52.52599
                              ],
                              [
                                13.39358,
                                52.52628
                              ],
                              [
                                13.39354,
                                52.5264
                              ],
                              [
                                13.39242,
                                52.52823
                              ],
                              [
                                13.39381,
                                52.52852
                              ],
                              [
                                13.38973,
                                52.53173
                              ],
                              [
                                13.38717,
                                52.5315
                              ],
                              [
                                13.38678,
                                52.5315
                              ],
                              [
                                13.38641,
                                52.53147
                              ],
                              [
                                13.38617,
                                52.53143
                              ],
                              [
                                13.38607,
                                52.53155
                              ],
                              [
                                13.38526,
                                52.53225
                              ],
                              [
                                13.38501,
                                52.53252
                              ],
                              [
                                13.38316,
                                52.53418
                              ],
                              [
                                13.38179,
                                52.5355
                              ],
                              [
                                13.38084,
                                52.53523
                              ],
                              [
                                13.38081,
                                52.53531
                              ],
                              [
                                13.3795,
                                52.53677
                              ],
                              [
                                13.37941,
                                52.53682
                              ],
                              [
                                13.37935,
                                52.53683
                              ],
                              [
                                13.37919,
                                52.53682
                              ],
                              [
                                13.37617,
                                52.5361
                              ],
                              [
                                13.37502,
                                52.53698
                              ],
                              [
                                13.37584,
                                52.53734
                              ]
                            ],
                            "type": "LineString"
                          },
                          {
                            "coordinates": [
                              [
                                13.37584,
                                52.53734
                              ],
                              [
                                13.37566,
                                52.53726
                              ],
                              [
                                13.37515,
                                52.53763
                              ],
                              [
                                13.37644,
                                52.53841
                              ],
                              [
                                13.37807,
                                52.53935
                              ],
                              [
                                13.37946,
                                52.5402
                              ],
                              [
                                13.3796,
                                52.54019
                              ],
                              [
                                13.37984,
                                52.54021
                              ],
                              [
                                13.37988,
                                52.54012
                              ],
                              [
                                13.38062,
                                52.53936
                              ],
                              [
                                13.38169,
                                52.53832
                              ],
                              [
                                13.38236,
                                52.5377
                              ],
                              [
                                13.38363,
                                52.53661
                              ],
                              [
                                13.38492,
                                52.53555
                              ],
                              [
                                13.38613,
                                52.53447
                              ],
                              [
                                13.38757,
                                52.53338
                              ],
                              [
                                13.38791,
                                52.53354
                              ],
                              [
                                13.38812,
                                52.53368
                              ],
                              [
                                13.38833,
                                52.53392
                              ],
                              [
                                13.38977,
                                52.53518
                              ],
                              [
                                13.39003,
                                52.53539
                              ],
                              [
                                13.39256,
                                52.53701
                              ],
                              [
                                13.39316,
                                52.53739
                              ],
                              [
                                13.39327,
                                52.53744
                              ],
                              [
                                13.3936,
                                52.53757
                              ],
                              [
                                13.40155,
                                52.53982
                              ],
                              [
                                13.40357,
                                52.53715
                              ],
                              [
                                13.40372,
                                52.53719
                              ],
                              [
                                13.40465,
                                52.53727
                              ],
                              [
                                13.4048,
                                52.53726
                              ],
                              [
                                13.4059,
                                52.53736
                              ],
                              [
                                13.40608,
                                52.53701
                              ]
                            ],
                            "type": "LineString"
                          }
                        ],
                        "activities": [
                          {
                            "type": "start",
                            "location_id": "berlin",
                            "address": {
                              "location_id": "berlin",
                              "lat": 52.537,
                              "lon": 13.406
                            },
                            "end_time": 1554804329,
                            "end_date_time": null,
                            "distance": 0,
                            "driving_time": 0,
                            "preparation_time": 0,
                            "waiting_time": 0,
                            "load_after": [
                              0
                            ]
                          },
                          {
                            "type": "service",
                            "id": "s-2",
                            "location_id": "13.393364_52.525851",
                            "address": {
                              "location_id": "13.393364_52.525851",
                              "lat": 52.525851,
                              "lon": 13.393364
                            },
                            "arr_time": 1554804743,
                            "arr_date_time": null,
                            "end_time": 1554804743,
                            "end_date_time": null,
                            "waiting_time": 0,
                            "distance": 1884,
                            "driving_time": 414,
                            "preparation_time": 0,
                            "load_before": [
                              0
                            ],
                            "load_after": [
                              1
                            ]
                          },
                          {
                            "type": "service",
                            "id": "s-1",
                            "location_id": "13.375854_52.537338",
                            "address": {
                              "location_id": "13.375854_52.537338",
                              "lat": 52.537338,
                              "lon": 13.375854
                            },
                            "arr_time": 1554805251,
                            "arr_date_time": null,
                            "end_time": 1554805329,
                            "end_date_time": null,
                            "waiting_time": 78,
                            "distance": 4205,
                            "driving_time": 922,
                            "preparation_time": 0,
                            "load_before": [
                              1
                            ],
                            "load_after": [
                              2
                            ]
                          },
                          {
                            "type": "end",
                            "location_id": "berlin",
                            "address": {
                              "location_id": "berlin",
                              "lat": 52.537,
                              "lon": 13.406
                            },
                            "arr_time": 1554806036,
                            "arr_date_time": null,
                            "distance": 7376,
                            "driving_time": 1629,
                            "preparation_time": 0,
                            "waiting_time": 0,
                            "load_before": [
                              2
                            ]
                          }
                        ]
                      }
                    ],
                    "unassigned": {
                      "services": [],
                      "shipments": [],
                      "breaks": [],
                      "details": []
                    }
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Error occurred when reading the request. Request is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BadRequest"
                }
              }
            }
          },
          "500": {
            "description": "Error occurred on server side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InternalErrorMessage"
                }
              }
            }
          }
        }
      }
    },
    "/vrp/optimize": {
      "post": {
        "summary": "Submit a route optimization job",
        "description": "\nTo solve a vehicle routing problem, perform the following steps:\n\n1.) Make a HTTP POST to this URL\n\n```\nhttps://graphhopper.com/api/1/vrp/optimize?key=<your_key>\n```\n\nIt returns a job id (`job_id`).\n\n2.) Take the job id and fetch the solution for the vehicle routing problem from this URL:\n\n```\nhttps://graphhopper.com/api/1/vrp/solution/<job_id>?key=<your_key>\n```\n\nWe recommend querying the solution every 500ms until it returns 'status=finished'.\n\n**Note**: Since the workflow is more complex and you lose some time fetching the solution, you should prefer\nthe [synchronous endpoint](#operation/solveVRP) when possible. Use the batch mode only for long-running problems.\n",
        "operationId": "asyncVRP",
        "requestBody": {
          "description": "The request that contains the problem to be solved.",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Request"
              },
              "example": {
                "vehicles": [
                  {
                    "vehicle_id": "vehicle-1",
                    "type_id": "cargo-bike",
                    "start_address": {
                      "location_id": "berlin",
                      "lon": 13.406,
                      "lat": 52.537
                    },
                    "earliest_start": 1554804329,
                    "latest_end": 1554808329,
                    "max_jobs": 3
                  },
                  {
                    "vehicle_id": "vehicle-2",
                    "type_id": "cargo-bike",
                    "start_address": {
                      "location_id": "berlin",
                      "lon": 13.406,
                      "lat": 52.537
                    },
                    "earliest_start": 1554804329,
                    "latest_end": 1554808329,
                    "max_jobs": 3,
                    "skills": [
                      "physical strength"
                    ]
                  }
                ],
                "vehicle_types": [
                  {
                    "type_id": "cargo-bike",
                    "capacity": [
                      10
                    ],
                    "profile": "bike"
                  }
                ],
                "services": [
                  {
                    "id": "s-1",
                    "name": "visit-Joe",
                    "address": {
                      "location_id": "13.375854_52.537338",
                      "lon": 13.375854,
                      "lat": 52.537338
                    },
                    "size": [
                      1
                    ],
                    "time_windows": [
                      {
                        "earliest": 1554805329,
                        "latest": 1554806329
                      }
                    ]
                  },
                  {
                    "id": "s-2",
                    "name": "serve-Peter",
                    "address": {
                      "location_id": "13.393364_52.525851",
                      "lon": 13.393364,
                      "lat": 52.525851
                    },
                    "size": [
                      1
                    ]
                  },
                  {
                    "id": "s-3",
                    "name": "visit-Michael",
                    "address": {
                      "location_id": "13.416882_52.523543",
                      "lon": 13.416882,
                      "lat": 52.523543
                    },
                    "size": [
                      1
                    ]
                  },
                  {
                    "id": "s-4",
                    "name": "do nothing",
                    "address": {
                      "location_id": "13.395767_52.514038",
                      "lon": 13.395767,
                      "lat": 52.514038
                    },
                    "size": [
                      1
                    ]
                  }
                ],
                "shipments": [
                  {
                    "id": "7fe77504-7df8-4497-843c-02d70b6490ce",
                    "name": "pickup and deliver pizza to Peter",
                    "priority": 1,
                    "pickup": {
                      "address": {
                        "location_id": "13.387613_52.529961",
                        "lon": 13.387613,
                        "lat": 52.529961
                      }
                    },
                    "delivery": {
                      "address": {
                        "location_id": "13.380575_52.513614",
                        "lon": 13.380575,
                        "lat": 52.513614
                      }
                    },
                    "size": [
                      1
                    ],
                    "required_skills": [
                      "physical strength"
                    ]
                  }
                ],
                "objectives": [
                  {
                    "type": "min",
                    "value": "vehicles"
                  },
                  {
                    "type": "min",
                    "value": "completion_time"
                  }
                ],
                "configuration": {
                  "routing": {
                    "calc_points": true,
                    "snap_preventions": [
                      "motorway",
                      "trunk",
                      "tunnel",
                      "bridge",
                      "ferry"
                    ]
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Route Optimization"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "source": "curl -X POST -H \"Content-Type: application/json\"   \"https://graphhopper.com/api/1/vrp/optimize?key=api_key\"   -d '{\n  \"vehicles\": [\n    {\n      \"vehicle_id\": \"my_vehicle\",\n      \"start_address\": {\n        \"location_id\": \"berlin\",\n        \"lon\": 13.406,\n        \"lat\": 52.537\n      }\n    }\n  ],\n  \"services\": [\n    {\n      \"id\": \"hamburg\",\n      \"name\": \"visit_hamburg\",\n      \"address\": {\n        \"location_id\": \"hamburg\",\n        \"lon\": 9.999,\n        \"lat\": 53.552\n      }\n    },\n    { \n     \"id\": \"munich\",\n      \"name\": \"visit_munich\",\n      \"address\": {\n        \"location_id\": \"munich\",\n        \"lon\": 11.57,\n        \"lat\": 48.145\n      }\n    }\n  ]}'"
          },
          {
            "lang": "Java",
            "source": "OkHttpClient client = new OkHttpClient();\nMediaType mediaType = MediaType.parse(\"application/json\");\nRequestBody body = RequestBody.create(mediaType, \"{\\n  \\\"vehicles\\\": [\\n    {\\n      \\\"vehicle_id\\\": \\\"my_vehicle\\\",\\n      \\\"start_address\\\": {\\n        \\\"location_id\\\": \\\"berlin\\\",\\n        \\\"lon\\\": 13.406,\\n        \\\"lat\\\": 52.537\\n      }\\n    }\\n  ],\\n  \\\"services\\\": [\\n    {\\n      \\\"id\\\": \\\"hamburg\\\",\\n      \\\"name\\\": \\\"visit_hamburg\\\",\\n      \\\"address\\\": {\\n        \\\"location_id\\\": \\\"hamburg\\\",\\n        \\\"lon\\\": 9.999,\\n        \\\"lat\\\": 53.552\\n      }\\n    },\\n    { \\n     \\\"id\\\": \\\"munich\\\",\\n      \\\"name\\\": \\\"visit_munich\\\",\\n      \\\"address\\\": {\\n        \\\"location_id\\\": \\\"munich\\\",\\n        \\\"lon\\\": 11.57,\\n        \\\"lat\\\": 48.145\\n      }\\n    }\\n  ]}\");\nRequest request = new Request.Builder()\n        .url(\"https://graphhopper.com/api/1/vrp/optimize?key=api_key\")\n        .post(body)\n        .addHeader(\"content-type\", \"application/json\")\n        .build();\n\nResponse response = client.newCall(request).execute();"
          }
        ],
        "responses": {
          "200": {
            "description": "A jobId you can use to retrieve your solution from the server - see solution endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobId"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "links": {
              "GetSolutionByJobId": {
                "operationId": "getSolution",
                "parameters": {
                  "jobId": "$response.body#/job_id"
                },
                "description": "The `job_id` value returned in the response can be used as the `jobId` parameter in `GET /vrp/{jobId}`.\n"
              }
            }
          },
          "400": {
            "description": "Error occurred when reading client request. Request is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BadRequest"
                }
              }
            }
          },
          "500": {
            "description": "Error occurred on server side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InternalErrorMessage"
                }
              }
            }
          }
        }
      }
    },
    "/vrp/solution/{jobId}": {
      "get": {
        "summary": "Retrieve solution of a route optimization job",
        "description": "\nTake the job id and fetch the solution for the vehicle routing problem from this URL:\n\n```\nhttps://graphhopper.com/api/1/vrp/solution/<job_id>?key=<your_key>\n```\n\nYou get the job id by sending a vehicle routing problem to the [batch mode URL](#operation/asyncVRP).\n",
        "operationId": "getSolution",
        "parameters": [
          {
            "in": "path",
            "name": "jobId",
            "description": "Request solution with jobId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "Route Optimization"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "source": "curl -X GET \"https://graphhopper.com/api/1/vrp/solution/job_id?key=api_key\""
          },
          {
            "lang": "Java",
            "source": "OkHttpClient client = new OkHttpClient();\nRequest request = new Request.Builder()\n        .url(\"https://graphhopper.com/api/1/vrp/solution/job_id?key=api_key\")\n        .get()\n        .build();\n\nResponse response = client.newCall(request).execute();"
          }
        ],
        "responses": {
          "200": {
            "description": "A response containing the solution",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Response"
                },
                "example": {
                  "copyrights": [
                    "GraphHopper",
                    "OpenStreetMap contributors"
                  ],
                  "job_id": "d62fcadd-c84a-4298-90b5-28550125bec5",
                  "status": "finished",
                  "waiting_time_in_queue": 0,
                  "processing_time": 459,
                  "solution": {
                    "costs": 438,
                    "distance": 17994,
                    "time": 4094,
                    "transport_time": 4094,
                    "completion_time": 4172,
                    "max_operation_time": 2465,
                    "waiting_time": 78,
                    "service_duration": 0,
                    "preparation_time": 0,
                    "no_vehicles": 2,
                    "no_unassigned": 0,
                    "routes": [
                      {
                        "vehicle_id": "vehicle-2",
                        "distance": 10618,
                        "transport_time": 2465,
                        "completion_time": 2465,
                        "waiting_time": 0,
                        "service_duration": 0,
                        "preparation_time": 0,
                        "points": [
                          {
                            "coordinates": [
                              [
                                13.40608,
                                52.53701
                              ],
                              [
                                13.40643,
                                52.53631
                              ],
                              [
                                13.40554,
                                52.53616
                              ],
                              [
                                13.4054,
                                52.53608
                              ],
                              [
                                13.40445,
                                52.53513
                              ],
                              [
                                13.40436,
                                52.53509
                              ],
                              [
                                13.40428,
                                52.53508
                              ],
                              [
                                13.40463,
                                52.53419
                              ],
                              [
                                13.40451,
                                52.53419
                              ],
                              [
                                13.4034,
                                52.53401
                              ],
                              [
                                13.403,
                                52.53359
                              ],
                              [
                                13.40291,
                                52.53354
                              ],
                              [
                                13.40268,
                                52.53347
                              ],
                              [
                                13.39888,
                                52.53259
                              ],
                              [
                                13.39839,
                                52.53253
                              ],
                              [
                                13.39812,
                                52.53251
                              ],
                              [
                                13.39616,
                                52.53243
                              ],
                              [
                                13.39579,
                                52.5324
                              ],
                              [
                                13.38973,
                                52.53173
                              ],
                              [
                                13.39163,
                                52.53025
                              ],
                              [
                                13.38797,
                                52.52935
                              ],
                              [
                                13.38763,
                                52.52996
                              ]
                            ],
                            "type": "LineString"
                          },
                          {
                            "coordinates": [
                              [
                                13.38763,
                                52.52996
                              ],
                              [
                                13.38739,
                                52.53039
                              ],
                              [
                                13.38724,
                                52.53036
                              ],
                              [
                                13.38464,
                                52.52929
                              ],
                              [
                                13.38538,
                                52.52871
                              ],
                              [
                                13.38634,
                                52.52792
                              ],
                              [
                                13.38638,
                                52.52779
                              ],
                              [
                                13.38657,
                                52.52763
                              ],
                              [
                                13.38676,
                                52.52741
                              ],
                              [
                                13.38698,
                                52.52713
                              ],
                              [
                                13.38704,
                                52.52701
                              ],
                              [
                                13.38753,
                                52.524
                              ],
                              [
                                13.3877,
                                52.52307
                              ],
                              [
                                13.3878,
                                52.52282
                              ],
                              [
                                13.38788,
                                52.52252
                              ],
                              [
                                13.38802,
                                52.52174
                              ],
                              [
                                13.38519,
                                52.52009
                              ],
                              [
                                13.38539,
                                52.5191
                              ],
                              [
                                13.38548,
                                52.51852
                              ],
                              [
                                13.38042,
                                52.51819
                              ],
                              [
                                13.38071,
                                52.5167
                              ],
                              [
                                13.38076,
                                52.51652
                              ],
                              [
                                13.38084,
                                52.51634
                              ],
                              [
                                13.3821,
                                52.51396
                              ],
                              [
                                13.38055,
                                52.51365
                              ]
                            ],
                            "type": "LineString"
                          },
                          {
                            "coordinates": [
                              [
                                13.38055,
                                52.51365
                              ],
                              [
                                13.38229,
                                52.514
                              ],
                              [
                                13.38363,
                                52.51429
                              ],
                              [
                                13.3848,
                                52.51445
                              ],
                              [
                                13.38504,
                                52.51358
                              ],
                              [
                                13.39124,
                                52.51397
                              ],
                              [
                                13.3911,
                                52.51488
                              ],
                              [
                                13.39303,
                                52.51499
                              ],
                              [
                                13.39317,
                                52.5141
                              ],
                              [
                                13.39548,
                                52.51419
                              ],
                              [
                                13.39571,
                                52.51421
                              ]
                            ],
                            "type": "LineString"
                          },
                          {
                            "coordinates": [
                              [
                                13.39571,
                                52.51421
                              ],
                              [
                                13.39695,
                                52.51434
                              ],
                              [
                                13.39674,
                                52.51523
                              ],
                              [
                                13.39742,
                                52.51531
                              ],
                              [
                                13.39873,
                                52.51558
                              ],
                              [
                                13.39846,
                                52.51599
                              ],
                              [
                                13.39825,
                                52.51729
                              ],
                              [
                                13.39805,
                                52.51755
                              ],
                              [
                                13.39892,
                                52.51761
                              ],
                              [
                                13.39917,
                                52.51764
                              ],
                              [
                                13.39964,
                                52.51775
                              ],
                              [
                                13.40009,
                                52.51791
                              ],
                              [
                                13.40034,
                                52.51797
                              ],
                              [
                                13.4021,
                                52.51864
                              ],
                              [
                                13.40288,
                                52.51896
                              ],
                              [
                                13.40375,
                                52.51936
                              ],
                              [
                                13.40498,
                                52.52001
                              ],
                              [
                                13.40463,
                                52.5203
                              ],
                              [
                                13.40311,
                                52.52144
                              ],
                              [
                                13.40442,
                                52.52189
                              ],
                              [
                                13.40448,
                                52.52192
                              ],
                              [
                                13.40451,
                                52.52195
                              ],
                              [
                                13.40473,
                                52.52199
                              ],
                              [
                                13.40504,
                                52.52208
                              ],
                              [
                                13.40572,
                                52.52235
                              ],
                              [
                                13.40687,
                                52.52294
                              ],
                              [
                                13.40693,
                                52.52299
                              ],
                              [
                                13.40706,
                                52.52319
                              ],
                              [
                                13.40738,
                                52.52378
                              ],
                              [
                                13.40787,
                                52.52443
                              ],
                              [
                                13.4079,
                                52.52453
                              ],
                              [
                                13.40938,
                                52.52401
                              ],
                              [
                                13.40962,
                                52.52398
                              ],
                              [
                                13.41001,
                                52.52395
                              ],
                              [
                                13.41072,
                                52.52391
                              ],
                              [
                                13.41215,
                                52.52389
                              ],
                              [
                                13.41233,
                                52.52386
                              ],
                              [
                                13.4131,
                                52.5235
                              ],
                              [
                                13.41288,
                                52.52333
                              ],
                              [
                                13.41475,
                                52.52247
                              ],
                              [
                                13.41496,
                                52.52264
                              ],
                              [
                                13.41523,
                                52.52251
                              ],
                              [
                                13.41633,
                                52.52338
                              ],
                              [
                                13.41631,
                                52.52346
                              ],
                              [
                                13.41654,
                                52.52364
                              ],
                              [
                                13.41684,
                                52.52351
                              ]
                            ],
                            "type": "LineString"
                          },
                          {
                            "coordinates": [
                              [
                                13.41684,
                                52.52351
                              ],
                              [
                                13.41654,
                                52.52364
                              ],
                              [
                                13.41631,
                                52.52346
                              ],
                              [
                                13.4163,
                                52.52344
                              ],
                              [
                                13.41587,
                                52.52363
                              ],
                              [
                                13.41572,
                                52.5235
                              ],
                              [
                                13.41409,
                                52.5242
                              ],
                              [
                                13.41454,
                                52.52461
                              ],
                              [
                                13.41454,
                                52.52466
                              ],
                              [
                                13.41358,
                                52.52508
                              ],
                              [
                                13.41366,
                                52.52514
                              ],
                              [
                                13.41344,
                                52.52525
                              ],
                              [
                                13.4133,
                                52.52514
                              ],
                              [
                                13.41316,
                                52.5252
                              ],
                              [
                                13.41107,
                                52.52585
                              ],
                              [
                                13.41118,
                                52.52606
                              ],
                              [
                                13.41118,
                                52.52616
                              ],
                              [
                                13.41095,
                                52.52664
                              ],
                              [
                                13.41097,
                                52.52678
                              ],
                              [
                                13.41084,
                                52.52706
                              ],
                              [
                                13.41057,
                                52.52747
                              ],
                              [
                                13.41028,
                                52.52809
                              ],
                              [
                                13.41032,
                                52.52821
                              ],
                              [
                                13.4102,
                                52.52847
                              ],
                              [
                                13.40999,
                                52.52875
                              ],
                              [
                                13.40984,
                                52.52905
                              ],
                              [
                                13.40982,
                                52.52914
                              ],
                              [
                                13.40984,
                                52.52926
                              ],
                              [
                                13.4104,
                                52.52998
                              ],
                              [
                                13.4105,
                                52.53001
                              ],
                              [
                                13.41064,
                                52.53016
                              ],
                              [
                                13.41082,
                                52.5303
                              ],
                              [
                                13.41198,
                                52.53107
                              ],
                              [
                                13.4122,
                                52.53128
                              ],
                              [
                                13.41232,
                                52.53143
                              ],
                              [
                                13.41247,
                                52.53192
                              ],
                              [
                                13.41267,
                                52.53245
                              ],
                              [
                                13.41275,
                                52.53259
                              ],
                              [
                                13.41215,
                                52.5327
                              ],
                              [
                                13.40731,
                                52.53463
                              ],
                              [
                                13.40608,
                                52.53701
                              ]
                            ],
                            "type": "LineString"
                          }
                        ],
                        "activities": [
                          {
                            "type": "start",
                            "location_id": "berlin",
                            "address": {
                              "location_id": "berlin",
                              "lat": 52.537,
                              "lon": 13.406
                            },
                            "end_time": 1554804329,
                            "end_date_time": null,
                            "distance": 0,
                            "driving_time": 0,
                            "preparation_time": 0,
                            "waiting_time": 0,
                            "load_after": [
                              0
                            ]
                          },
                          {
                            "type": "pickupShipment",
                            "id": "7fe77504-7df8-4497-843c-02d70b6490ce",
                            "location_id": "13.387613_52.529961",
                            "address": {
                              "location_id": "13.387613_52.529961",
                              "lat": 52.529961,
                              "lon": 13.387613
                            },
                            "arr_time": 1554804789,
                            "arr_date_time": null,
                            "end_time": 1554804789,
                            "end_date_time": null,
                            "waiting_time": 0,
                            "distance": 2012,
                            "driving_time": 460,
                            "preparation_time": 0,
                            "load_before": [
                              0
                            ],
                            "load_after": [
                              1
                            ]
                          },
                          {
                            "type": "deliverShipment",
                            "id": "7fe77504-7df8-4497-843c-02d70b6490ce",
                            "location_id": "13.380575_52.513614",
                            "address": {
                              "location_id": "13.380575_52.513614",
                              "lat": 52.513614,
                              "lon": 13.380575
                            },
                            "arr_time": 1554805344,
                            "arr_date_time": null,
                            "end_time": 1554805344,
                            "end_date_time": null,
                            "waiting_time": 0,
                            "distance": 4560,
                            "driving_time": 1015,
                            "preparation_time": 0,
                            "load_before": [
                              1
                            ],
                            "load_after": [
                              0
                            ]
                          },
                          {
                            "type": "service",
                            "id": "s-4",
                            "location_id": "13.395767_52.514038",
                            "address": {
                              "location_id": "13.395767_52.514038",
                              "lat": 52.514038,
                              "lon": 13.395767
                            },
                            "arr_time": 1554805632,
                            "arr_date_time": null,
                            "end_time": 1554805632,
                            "end_date_time": null,
                            "waiting_time": 0,
                            "distance": 5887,
                            "driving_time": 1303,
                            "preparation_time": 0,
                            "load_before": [
                              0
                            ],
                            "load_after": [
                              1
                            ]
                          },
                          {
                            "type": "service",
                            "id": "s-3",
                            "location_id": "13.416882_52.523543",
                            "address": {
                              "location_id": "13.416882_52.523543",
                              "lat": 52.523543,
                              "lon": 13.416882
                            },
                            "arr_time": 1554806253,
                            "arr_date_time": null,
                            "end_time": 1554806253,
                            "end_date_time": null,
                            "waiting_time": 0,
                            "distance": 8486,
                            "driving_time": 1924,
                            "preparation_time": 0,
                            "load_before": [
                              1
                            ],
                            "load_after": [
                              2
                            ]
                          },
                          {
                            "type": "end",
                            "location_id": "berlin",
                            "address": {
                              "location_id": "berlin",
                              "lat": 52.537,
                              "lon": 13.406
                            },
                            "arr_time": 1554806794,
                            "arr_date_time": null,
                            "distance": 10618,
                            "driving_time": 2465,
                            "preparation_time": 0,
                            "waiting_time": 0,
                            "load_before": [
                              2
                            ]
                          }
                        ]
                      },
                      {
                        "vehicle_id": "vehicle-1",
                        "distance": 7376,
                        "transport_time": 1629,
                        "completion_time": 1707,
                        "waiting_time": 78,
                        "service_duration": 0,
                        "preparation_time": 0,
                        "points": [
                          {
                            "coordinates": [
                              [
                                13.40608,
                                52.53701
                              ],
                              [
                                13.40674,
                                52.53571
                              ],
                              [
                                13.40433,
                                52.53313
                              ],
                              [
                                13.40271,
                                52.53149
                              ],
                              [
                                13.40246,
                                52.53121
                              ],
                              [
                                13.40148,
                                52.52999
                              ],
                              [
                                13.40128,
                                52.52993
                              ],
                              [
                                13.40118,
                                52.52988
                              ],
                              [
                                13.40133,
                                52.5296
                              ],
                              [
                                13.40138,
                                52.52951
                              ],
                              [
                                13.40167,
                                52.52914
                              ],
                              [
                                13.40188,
                                52.52895
                              ],
                              [
                                13.398,
                                52.52885
                              ],
                              [
                                13.39289,
                                52.52748
                              ],
                              [
                                13.39354,
                                52.5264
                              ],
                              [
                                13.39358,
                                52.52628
                              ],
                              [
                                13.39324,
                                52.52575
                              ],
                              [
                                13.39334,
                                52.52573
                              ],
                              [
                                13.39339,
                                52.52584
                              ]
                            ],
                            "type": "LineString"
                          },
                          {
                            "coordinates": [
                              [
                                13.39339,
                                52.52584
                              ],
                              [
                                13.3934,
                                52.52599
                              ],
                              [
                                13.39358,
                                52.52628
                              ],
                              [
                                13.39354,
                                52.5264
                              ],
                              [
                                13.39242,
                                52.52823
                              ],
                              [
                                13.39381,
                                52.52852
                              ],
                              [
                                13.38973,
                                52.53173
                              ],
                              [
                                13.38717,
                                52.5315
                              ],
                              [
                                13.38678,
                                52.5315
                              ],
                              [
                                13.38641,
                                52.53147
                              ],
                              [
                                13.38617,
                                52.53143
                              ],
                              [
                                13.38607,
                                52.53155
                              ],
                              [
                                13.38526,
                                52.53225
                              ],
                              [
                                13.38501,
                                52.53252
                              ],
                              [
                                13.38316,
                                52.53418
                              ],
                              [
                                13.38179,
                                52.5355
                              ],
                              [
                                13.38084,
                                52.53523
                              ],
                              [
                                13.38081,
                                52.53531
                              ],
                              [
                                13.3795,
                                52.53677
                              ],
                              [
                                13.37941,
                                52.53682
                              ],
                              [
                                13.37935,
                                52.53683
                              ],
                              [
                                13.37919,
                                52.53682
                              ],
                              [
                                13.37617,
                                52.5361
                              ],
                              [
                                13.37502,
                                52.53698
                              ],
                              [
                                13.37584,
                                52.53734
                              ]
                            ],
                            "type": "LineString"
                          },
                          {
                            "coordinates": [
                              [
                                13.37584,
                                52.53734
                              ],
                              [
                                13.37566,
                                52.53726
                              ],
                              [
                                13.37515,
                                52.53763
                              ],
                              [
                                13.37644,
                                52.53841
                              ],
                              [
                                13.37807,
                                52.53935
                              ],
                              [
                                13.37946,
                                52.5402
                              ],
                              [
                                13.3796,
                                52.54019
                              ],
                              [
                                13.37984,
                                52.54021
                              ],
                              [
                                13.37988,
                                52.54012
                              ],
                              [
                                13.38062,
                                52.53936
                              ],
                              [
                                13.38169,
                                52.53832
                              ],
                              [
                                13.38236,
                                52.5377
                              ],
                              [
                                13.38363,
                                52.53661
                              ],
                              [
                                13.38492,
                                52.53555
                              ],
                              [
                                13.38613,
                                52.53447
                              ],
                              [
                                13.38757,
                                52.53338
                              ],
                              [
                                13.38791,
                                52.53354
                              ],
                              [
                                13.38812,
                                52.53368
                              ],
                              [
                                13.38833,
                                52.53392
                              ],
                              [
                                13.38977,
                                52.53518
                              ],
                              [
                                13.39003,
                                52.53539
                              ],
                              [
                                13.39256,
                                52.53701
                              ],
                              [
                                13.39316,
                                52.53739
                              ],
                              [
                                13.39327,
                                52.53744
                              ],
                              [
                                13.3936,
                                52.53757
                              ],
                              [
                                13.40155,
                                52.53982
                              ],
                              [
                                13.40357,
                                52.53715
                              ],
                              [
                                13.40372,
                                52.53719
                              ],
                              [
                                13.40465,
                                52.53727
                              ],
                              [
                                13.4048,
                                52.53726
                              ],
                              [
                                13.4059,
                                52.53736
                              ],
                              [
                                13.40608,
                                52.53701
                              ]
                            ],
                            "type": "LineString"
                          }
                        ],
                        "activities": [
                          {
                            "type": "start",
                            "location_id": "berlin",
                            "address": {
                              "location_id": "berlin",
                              "lat": 52.537,
                              "lon": 13.406
                            },
                            "end_time": 1554804329,
                            "end_date_time": null,
                            "distance": 0,
                            "driving_time": 0,
                            "preparation_time": 0,
                            "waiting_time": 0,
                            "load_after": [
                              0
                            ]
                          },
                          {
                            "type": "service",
                            "id": "s-2",
                            "location_id": "13.393364_52.525851",
                            "address": {
                              "location_id": "13.393364_52.525851",
                              "lat": 52.525851,
                              "lon": 13.393364
                            },
                            "arr_time": 1554804743,
                            "arr_date_time": null,
                            "end_time": 1554804743,
                            "end_date_time": null,
                            "waiting_time": 0,
                            "distance": 1884,
                            "driving_time": 414,
                            "preparation_time": 0,
                            "load_before": [
                              0
                            ],
                            "load_after": [
                              1
                            ]
                          },
                          {
                            "type": "service",
                            "id": "s-1",
                            "location_id": "13.375854_52.537338",
                            "address": {
                              "location_id": "13.375854_52.537338",
                              "lat": 52.537338,
                              "lon": 13.375854
                            },
                            "arr_time": 1554805251,
                            "arr_date_time": null,
                            "end_time": 1554805329,
                            "end_date_time": null,
                            "waiting_time": 78,
                            "distance": 4205,
                            "driving_time": 922,
                            "preparation_time": 0,
                            "load_before": [
                              1
                            ],
                            "load_after": [
                              2
                            ]
                          },
                          {
                            "type": "end",
                            "location_id": "berlin",
                            "address": {
                              "location_id": "berlin",
                              "lat": 52.537,
                              "lon": 13.406
                            },
                            "arr_time": 1554806036,
                            "arr_date_time": null,
                            "distance": 7376,
                            "driving_time": 1629,
                            "preparation_time": 0,
                            "waiting_time": 0,
                            "load_before": [
                              2
                            ]
                          }
                        ]
                      }
                    ],
                    "unassigned": {
                      "services": [],
                      "shipments": [],
                      "breaks": [],
                      "details": []
                    }
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Error occurred on client side such as invalid input.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BadRequest"
                }
              }
            }
          },
          "404": {
            "description": "Requested solution could not be found.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message",
                      "example": "Invalid job_id 73314c89-ee4b-459c-aca4-0ad6d6e558da"
                    },
                    "status": {
                      "type": "string",
                      "description": "status",
                      "default": "finished",
                      "example": "finished"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error occurred on server side."
          }
        }
      }
    },
    "/cluster": {
      "post": {
        "summary": "Solve a clustering problem",
        "description": "\nThe Cluster endpoint is used with a POST request towards\n`https://graphhopper.com/api/1/cluster?key=<your_key>`. The solution will be provided in the JSON response.\nPlease note that for problems that take longer than 10 seconds a bad request error is returned.\nIn this case please use the asynchronous [Batch Cluster Endpoint](#operation/asyncClusteringProblem) instead.\n",
        "operationId": "solveClusteringProblem",
        "requestBody": {
          "description": "Request object that contains the problem to be solved",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClusterRequest"
              }
            }
          }
        },
        "tags": [
          "Clustering"
        ],
        "responses": {
          "200": {
            "description": "A response containing the solution",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClusterResponse"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Error occurred when reading the request. Request is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BadRequest"
                }
              }
            }
          },
          "500": {
            "description": "Error occurred on server side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InternalErrorMessage"
                }
              }
            }
          }
        }
      }
    },
    "/cluster/calculate": {
      "post": {
        "summary": "Submit a clustering job",
        "description": "\nPrefer the [synchronous endpoint](#operation/solveClusteringProblem) and use this Batch Cluster endpoint for\nlong running problems only. The work flow is asynchronous:\n\n- send a POST request towards `https://graphhopper.com/api/1/cluster/calculate?key=<your_key>` and fetch the job_id.\n- poll the solution every 500ms until it gives `status=finished`. Do this with a GET request\n  towards `https://graphhopper.com/api/1/cluster/solution/<job_id>?key=<your_key>`.\n",
        "operationId": "asyncClusteringProblem",
        "requestBody": {
          "description": "Request object that contains the problem to be solved",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClusterRequest"
              }
            }
          }
        },
        "tags": [
          "Clustering"
        ],
        "responses": {
          "200": {
            "description": "A jobId you can use to retrieve your solution from the server - see solution endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobId"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "links": {
              "GetSolutionByJobId": {
                "operationId": "getSolution",
                "parameters": {
                  "jobId": "$response.body#/job_id"
                },
                "description": "The `job_id` value returned in the response can be used as the `jobId` parameter in `GET /vrp/{jobId}`.\n"
              }
            }
          },
          "400": {
            "description": "Error occurred when reading client request. Request is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BadRequest"
                }
              }
            }
          },
          "500": {
            "description": "Error occurred on server side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InternalErrorMessage"
                }
              }
            }
          }
        }
      }
    },
    "/cluster/solution/{jobId}": {
      "get": {
        "summary": "Retrieve solution of a clustering job",
        "description": "This endpoint returns the solution of the clustering problems submitted to the [Batch Cluster endpoint](#operation/asyncClusteringProblem).\nYou can fetch it with the job_id, you have been sent.\n",
        "operationId": "getClusterSolution",
        "parameters": [
          {
            "in": "path",
            "name": "jobId",
            "description": "Request solution with jobId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "Clustering"
        ],
        "responses": {
          "200": {
            "description": "A response containing the solution",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClusterResponse"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Error occurred on client side such as invalid input.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BadRequest"
                }
              }
            }
          },
          "404": {
            "description": "Requested solution could not be found.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message",
                      "example": "Invalid job_id 73314c89-ee4b-459c-aca4-0ad6d6e558da"
                    },
                    "status": {
                      "type": "string",
                      "description": "status",
                      "default": "finished",
                      "example": "finished"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error occurred on server side."
          }
        }
      }
    },
    "/profiles": {
      "post": {
        "summary": "Create a custom routing profile",
        "operationId": "postProfile",
        "tags": [
          "Custom Profiles"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProfileRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Profile created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProfileResponse"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List your custom routing profiles",
        "operationId": "getProfile",
        "tags": [
          "Custom Profiles"
        ],
        "responses": {
          "200": {
            "description": "Your profiles",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProfileGetResponse"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        }
      }
    },
    "/profiles/calculate": {
      "post": {
        "summary": "Submit a profile creation job",
        "operationId": "calculateProfile",
        "description": "An alternate endpoint for computing a profile for a large boundary asynchronously, where a request against the regular\nendpoint would result in a timeout.\n\nThe request format is the same, but instead of the result, you are given a job identification number that\nyou can use to retrieve the result once it is available.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProfileRequest"
              }
            }
          }
        },
        "tags": [
          "Custom Profiles"
        ],
        "responses": {
          "200": {
            "description": "A jobId you can use to retrieve the calculated profile.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobId"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        }
      }
    },
    "/profiles/solution/{jobId}": {
      "get": {
        "summary": "Retrieve result of a profile creation job",
        "operationId": "getProfileSolution",
        "parameters": [
          {
            "in": "path",
            "name": "jobId",
            "description": "The jobId you received when you submitted the job.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "Custom Profiles"
        ],
        "responses": {
          "200": {
            "description": "A response containing the custom profile",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "solution": {
                      "$ref": "#/components/schemas/ProfileResponse"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "processing",
                        "finished"
                      ]
                    }
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Credits": {
                "description": "The credit costs for this request. Note it could be a decimal and even negative number, e.g. when an async request failed.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        }
      }
    },
    "/profiles/{profileId}": {
      "delete": {
        "summary": "Delete a custom routing profile",
        "operationId": "deleteProfile",
        "tags": [
          "Custom Profiles"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "profileId",
            "description": "The profile to delete",
            "required": true,
            "schema": {
              "type": "string",
              "example": "cp_shc_1_4390ba24-e6cb-406b-acc6-3402dd4d229d"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A response containing the status",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    }
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Your current daily credit limit.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Your remaining credits until the reset.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "The number of seconds that you have to wait before a reset of the credit count is done.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        }
      }
    }
  },
  "security": [
    {
      "key": []
    }
  ],
  "components": {
    "securitySchemes": {
      "key": {
        "type": "apiKey",
        "name": "key",
        "in": "query"
      }
    },
    "schemas": {
      "ClusterResponse": {
        "type": "object",
        "properties": {
          "copyrights": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "GraphHopper",
              "OpenStreetMap contributors"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "waiting_in_queue",
              "processing",
              "finished"
            ],
            "description": "Indicates the current status of the job",
            "example": "finished"
          },
          "waiting_time_in_queue": {
            "type": "number",
            "format": "double"
          },
          "processing_time": {
            "type": "number",
            "format": "double",
            "example": 4900
          },
          "clusters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Cluster"
            }
          }
        }
      },
      "Cluster": {
        "type": "object",
        "properties": {
          "quantity": {
            "type": "number",
            "format": "int32",
            "description": "Cluster size",
            "example": 40
          },
          "ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Array of customer ids assigned to this specific cluster",
            "example": [
              "GraphHopper GmbH"
            ]
          }
        }
      },
      "ClusterRequest": {
        "type": "object",
        "properties": {
          "configuration": {
            "$ref": "#/components/schemas/ClusterConfiguration"
          },
          "clusters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Clusters"
            }
          },
          "customers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClusterCustomer"
            }
          }
        }
      },
      "ClusterConfiguration": {
        "type": "object",
        "properties": {
          "response_type": {
            "type": "string",
            "description": "Specifies the response format. You can either choose `geojson` or `json`.",
            "default": "json",
            "example": "json"
          },
          "routing": {
            "$ref": "#/components/schemas/ClusterConfigurationRouting"
          },
          "clustering": {
            "$ref": "#/components/schemas/ClusterConfigurationClustering"
          }
        }
      },
      "Clusters": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "id of customer",
            "example": "GraphHopper GmbH"
          },
          "center": {
            "$ref": "#/components/schemas/ClusterCustomerAddress"
          },
          "min_quantity": {
            "type": "number",
            "format": "int32",
            "description": "Specifies min. quantity of this cluster",
            "example": 10
          },
          "max_quantity": {
            "type": "number",
            "format": "int32",
            "description": "Specifies max. quantity of this cluster",
            "example": 10
          }
        }
      },
      "ClusterCustomer": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "id of customer",
            "example": "GraphHopper GmbH"
          },
          "address": {
            "$ref": "#/components/schemas/ClusterCustomerAddress"
          },
          "quantity": {
            "type": "number",
            "format": "int32",
            "description": "demand of customer",
            "example": 10
          }
        }
      },
      "ClusterCustomerAddress": {
        "type": "object",
        "properties": {
          "lon": {
            "type": "number",
            "format": "double",
            "description": "Longitude",
            "example": 11.53941
          },
          "lat": {
            "type": "number",
            "format": "double",
            "description": "Latitude",
            "example": 48.118434
          },
          "street_hint": {
            "type": "string",
            "description": "Optional parameter. Provide a hint that includes only the street name 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.",
            "example": "Lindenschmitstraße 52"
          }
        }
      },
      "ClusterConfigurationRouting": {
        "type": "object",
        "properties": {
          "profile": {
            "$ref": "#/components/schemas/VehicleProfileId"
          },
          "cost_per_second": {
            "type": "number",
            "format": "double",
            "description": "Cost per second (travel time)",
            "example": 1
          },
          "cost_per_meter": {
            "type": "number",
            "format": "double",
            "description": "Cost per meter (travel distance)",
            "example": 0
          }
        }
      },
      "ClusterConfigurationClustering": {
        "type": "object",
        "properties": {
          "num_clusters": {
            "type": "number",
            "format": "int32",
            "description": "Specifies the number of clusters",
            "example": 10
          },
          "max_quantity": {
            "type": "number",
            "format": "int32",
            "description": "Specifies max. quantity in a cluster",
            "example": 50
          },
          "min_quantity": {
            "type": "number",
            "format": "int32",
            "description": "Specifies min. quantity in a cluster",
            "example": 30
          }
        }
      },
      "GeocodingResponse": {
        "properties": {
          "hits": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/GeocodingLocation"
            }
          },
          "took": {
            "type": "number",
            "format": "int64",
            "description": "in ms"
          }
        },
        "example": {
          "hits": [
            {
              "osm_id": 240109189,
              "osm_type": "N",
              "country": "Deutschland",
              "osm_key": "place",
              "city": "Berlin",
              "osm_value": "city",
              "postcode": "10117",
              "name": "Berlin",
              "point": {
                "lng": 13.3888599,
                "lat": 52.5170365
              }
            },
            {
              "osm_id": 62422,
              "osm_type": "R",
              "extent": [
                13.088345,
                52.6755087,
                13.7611609,
                52.33826
              ],
              "country": "Deutschland",
              "osm_key": "place",
              "osm_value": "city",
              "name": "Berlin",
              "point": {
                "lng": 13.4385964,
                "lat": 52.5198535
              }
            },
            {
              "osm_id": 120456814,
              "osm_type": "W",
              "extent": [
                13.3906703,
                52.5200704,
                13.3948873,
                52.5175007
              ],
              "country": "Deutschland",
              "osm_key": "amenity",
              "city": "Berlin",
              "street": "Dorotheenstraße",
              "osm_value": "university",
              "postcode": "10117",
              "name": "Humboldt-Universität zu Berlin",
              "point": {
                "lng": 13.393560493637775,
                "lat": 52.51875685
              }
            },
            {
              "osm_id": 6647,
              "osm_type": "R",
              "extent": [
                13.3924346,
                52.5191829,
                13.3948768,
                52.517526
              ],
              "country": "Deutschland",
              "osm_key": "building",
              "housenumber": "6",
              "city": "Berlin",
              "street": "Unter den Linden",
              "osm_value": "yes",
              "postcode": "10117",
              "name": "Humboldt-Universität zu Berlin",
              "point": {
                "lng": 13.392908021752554,
                "lat": 52.51840935
              }
            },
            {
              "osm_id": 38862723,
              "osm_type": "W",
              "extent": [
                13.2364563,
                52.5161915,
                13.2433375,
                52.5129557
              ],
              "country": "Deutschland",
              "osm_key": "leisure",
              "housenumber": "3",
              "city": "Berlin",
              "street": "Olympischer Platz",
              "osm_value": "stadium",
              "postcode": "14053",
              "name": "Olympiastadion Berlin",
              "point": {
                "lng": 13.239776301622072,
                "lat": 52.5147077
              }
            },
            {
              "osm_id": 583306346,
              "osm_type": "W",
              "extent": [
                13.3739245,
                52.528547,
                13.3818019,
                52.5229778
              ],
              "country": "Deutschland",
              "osm_key": "amenity",
              "city": "Berlin",
              "street": "Hufelandweg",
              "osm_value": "hospital",
              "postcode": "10117",
              "name": "Charité Universitätsmedizin Berlin",
              "point": {
                "lng": 13.377739577932736,
                "lat": 52.52585125
              }
            },
            {
              "osm_id": 180594,
              "osm_type": "R",
              "extent": [
                13.3906159,
                52.5190301,
                13.3923847,
                52.5174089
              ],
              "country": "Deutschland",
              "osm_key": "amenity",
              "housenumber": "8",
              "city": "Berlin",
              "street": "Unter den Linden",
              "osm_value": "library",
              "postcode": "10117",
              "name": "Staatsbibliothek zu Berlin",
              "point": {
                "lng": 13.391516532100738,
                "lat": 52.5182233
              }
            },
            {
              "osm_id": 3856100103,
              "osm_type": "N",
              "country": "Deutschland",
              "osm_key": "railway",
              "city": "Berlin",
              "street": "Washingtonplatz",
              "osm_value": "station",
              "postcode": "10557",
              "name": "Berlin Hauptbahnhof",
              "point": {
                "lng": 13.3696614,
                "lat": 52.5249451
              }
            },
            {
              "osm_id": 1078631331,
              "osm_type": "N",
              "country": "Deutschland",
              "osm_key": "historic",
              "city": "Berlin",
              "street": "Gertrud-Kolmar-Straße",
              "osm_value": "battlefield",
              "postcode": "10117",
              "name": "Schlacht um Berlin",
              "point": {
                "lng": 13.3814231,
                "lat": 52.5127537
              }
            },
            {
              "osm_id": 1154556,
              "osm_type": "R",
              "extent": [
                13.3807495,
                52.5083344,
                13.3822459,
                52.5074359
              ],
              "country": "Deutschland",
              "osm_key": "office",
              "housenumber": "5",
              "city": "Berlin",
              "street": "Niederkirchnerstraße",
              "osm_value": "government",
              "postcode": "10117",
              "name": "Abgeordnetenhaus von Berlin",
              "point": {
                "lng": 13.381504320489928,
                "lat": 52.50786655
              }
            }
          ],
          "took": 37
        }
      },
      "GeocodingLocation": {
        "type": "object",
        "properties": {
          "point": {
            "$ref": "#/components/schemas/GeocodingPoint"
          },
          "osm_id": {
            "type": "integer",
            "format": "int64",
            "description": "The OSM ID of the entity"
          },
          "osm_type": {
            "type": "string",
            "description": "N = node, R = relation, W = way"
          },
          "osm_key": {
            "type": "string",
            "description": "The OSM key of the entity"
          },
          "name": {
            "type": "string",
            "description": "The name of the entity. Can be a boundary, POI, address, etc"
          },
          "country": {
            "type": "string",
            "description": "The country of the address"
          },
          "city": {
            "type": "string",
            "description": "The city of the address"
          },
          "state": {
            "type": "string",
            "description": "The state of the address"
          },
          "street": {
            "type": "string",
            "description": "The street of the address"
          },
          "housenumber": {
            "type": "string",
            "description": "The housenumber of the address"
          },
          "postcode": {
            "type": "string",
            "description": "The postcode of the address"
          }
        }
      },
      "GeocodingPoint": {
        "type": "object",
        "properties": {
          "lat": {
            "type": "number",
            "format": "double",
            "description": "Latitude"
          },
          "lng": {
            "type": "number",
            "format": "double",
            "description": "Longitude"
          }
        }
      },
      "MatrixRequest": {
        "type": "object",
        "properties": {
          "profile": {
            "$ref": "#/components/schemas/VehicleProfileId"
          },
          "from_points": {
            "description": "The origin points for the routes in an array of `[longitude,latitude]`.",
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            }
          },
          "to_points": {
            "description": "The destination points for the routes in an array of `[longitude,latitude]`.",
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            }
          },
          "from_point_hints": {
            "description": "See `point_hints`of symmetrical matrix",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "to_point_hints": {
            "description": "See `point_hints`of symmetrical matrix",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "snap_preventions": {
            "description": "See `snap_preventions` of symmetrical matrix",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "from_curbsides": {
            "description": "See `curbsides`of symmetrical matrix",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "to_curbsides": {
            "description": "See `curbsides`of symmetrical matrix",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "out_arrays": {
            "description": "Specifies which matrices should be included in the response. Specify one or more of the following options `weights`, `times`, `distances`. The units of the entries of `distances` are meters, of `times` are seconds and of `weights` is arbitrary and it can differ for different vehicles or versions of this API.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "fail_fast": {
            "description": "Specifies whether or not the matrix calculation should return with an error as soon as possible in case some points cannot be found or some points are not connected. If set to `false` the time/weight/distance matrix will be calculated for all valid points and contain the `null` value for all entries that could not be calculated. The `hint` field of the response will also contain additional information about what went wrong (see its documentation).",
            "type": "boolean",
            "default": true
          }
        },
        "example": {
          "from_points": [
            [
              -0.11379003524780275,
              51.53664617804063
            ],
            [
              -0.10866165161132814,
              51.538621486960956
            ],
            [
              -0.11059284210205078,
              51.53245503603458
            ]
          ],
          "to_points": [
            [
              -0.09576559066772462,
              51.512882367963456
            ],
            [
              -0.08797645568847656,
              51.51317615367198
            ]
          ],
          "from_point_hints": [
            "Copenhagen Street",
            "Richmond Avenue",
            "White Lion Street"
          ],
          "to_point_hints": [
            "Cannon",
            "Cornhill"
          ],
          "out_arrays": [
            "weights",
            "times",
            "distances"
          ],
          "vehicle": "car"
        }
      },
      "SymmetricalMatrixRequest": {
        "type": "object",
        "properties": {
          "profile": {
            "$ref": "#/components/schemas/VehicleProfileId"
          },
          "points": {
            "description": "Specify multiple points for which the weight-, route-, time- or distance-matrix should be calculated as follows: `[longitude,latitude]`. In this case the origins are identical to the destinations. Thus, if there are N points, NxN entries are calculated. The order of the point parameter is important. Specify at least three points. Cannot be used together with `from_point` or `to_point.`.",
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            }
          },
          "point_hints": {
            "description": "Optional parameter. Specifies a hint for each point in the `points` array to prefer a certain street for the closest location lookup. 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.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "snap_preventions": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "motorway",
                "trunk",
                "bridge",
                "ford",
                "tunnel",
                "ferry"
              ]
            },
            "description": "Optional parameter. 'Snapping' is the process of finding the closest road location for GPS coordinates provided in the `points` array. The `snap_preventions` array allows you to prevent snapping to specific types of roads. For example, if the array includes `bridge`, then the routing engine will avoid snapping to a bridge, even if it is the closest road for the given point. Note that once snapped the routing algorithm can still route over bridges (or the other values). To avoid this you need to use the `custom_model`.",
            "example": [
              "motorway",
              "trunk",
              "bridge",
              "tunnel",
              "ferry",
              "ford"
            ]
          },
          "curbsides": {
            "description": "Optional parameter. It specifies on which side a point should be relative to the driver when she leaves/arrives at a start/target/via point. You need to specify this parameter for either none or all points. Only supported for motor vehicles and OpenStreetMap.",
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "right",
                "left",
                "any"
              ]
            }
          },
          "out_arrays": {
            "description": "Specifies which matrices should be included in the response. Specify one or more of the following options `weights`, `times`, `distances`. The units of the entries of `distances` are meters, of `times` are seconds and of `weights` is arbitrary and it can differ for different vehicle profiles or versions of this API.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "fail_fast": {
            "description": "Specifies whether or not the matrix calculation should return with an error as soon as possible in case some points cannot be found or some points are not connected. If set to `false` the time/weight/distance matrix will be calculated for all valid points and contain the `null` value for all entries that could not be calculated. The `hint` field of the response will also contain additional information about what went wrong (see its documentation).",
            "type": "boolean",
            "default": true
          }
        },
        "example": {
          "points": [
            [
              -0.11379003524780275,
              51.53664617804063
            ],
            [
              -0.10866165161132814,
              51.538621486960956
            ],
            [
              -0.11059284210205078,
              51.53245503603458
            ]
          ],
          "point_hints": [
            "Copenhagen Street",
            "Richmond Avenue",
            "White Lion Street"
          ],
          "out_arrays": [
            "weights",
            "times",
            "distances"
          ],
          "vehicle": "car"
        }
      },
      "MatrixResponse": {
        "type": "object",
        "properties": {
          "distances": {
            "description": "The distance matrix for the specified points in the same order as the time matrix. The distances are in meters. If `fail_fast=false` the matrix will contain `null` for connections that could not be found.",
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "int64"
              }
            }
          },
          "times": {
            "description": "The time matrix for the specified points in the order [[from1->to1, from1->to2, ...], [from2->to1, from2->to2, ...], ...]. The times are in seconds. If `fail_fast=false` the matrix will contain `null` for connections that could not be found.",
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "int64"
              }
            }
          },
          "weights": {
            "description": "The weight matrix for the specified points in the same order as the time matrix. The weights for different vehicle profiles can have a different unit but the weights array is perfectly suited as input for Vehicle Routing Problems as it is currently faster to calculate. If `fail_fast=false` the matrix will contain `null` for connections that could not be found.",
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            }
          },
          "info": {
            "$ref": "#/components/schemas/ResponseInfo"
          },
          "hints": {
            "description": "Optional. Additional response data.",
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "message": {
                  "description": "Short description of this hint",
                  "type": "string"
                },
                "details": {
                  "description": "Details of this hint",
                  "type": "string"
                },
                "invalid_from_points": {
                  "description": "Optional. An array of from_point indices of points that could not be found. Will only be added if `fail_fast=false` and some `from_point`s were not found.`",
                  "type": "array",
                  "items": {
                    "type": "number",
                    "format": "int32"
                  }
                },
                "invalid_to_points": {
                  "description": "Optional. An array of to_point indices of points that could not be found. Will only be added if `fail_fast=false` and some `to_point`s were not found.`",
                  "type": "array",
                  "items": {
                    "type": "number",
                    "format": "int32"
                  }
                },
                "point_pairs": {
                  "description": "Optional. An array of two-element arrays representing the from/to_point indices of points for which no connection could be found. Will only be added if `fail_fast=false` and some connections were not found.",
                  "type": "array",
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "number",
                      "format": "int32"
                    }
                  }
                }
              }
            }
          }
        },
        "example": {
          "distances": [
            [
              0,
              97653,
              48887
            ],
            [
              97426,
              0,
              121035
            ],
            [
              49006,
              121049,
              0
            ]
          ],
          "times": [
            [
              0,
              4197,
              2994
            ],
            [
              4192,
              0,
              6074
            ],
            [
              3006,
              6062,
              0
            ]
          ],
          "weights": [
            [
              0,
              5662.551,
              3727.147
            ],
            [
              5653.807,
              0,
              7889.653
            ],
            [
              3741.528,
              7878.365,
              0
            ]
          ],
          "info": {
            "copyrights": [
              "GraphHopper",
              "OpenStreetMap contributors"
            ]
          }
        }
      },
      "RouteRequest": {
        "type": "object",
        "properties": {
          "profile": {
            "$ref": "#/components/schemas/VehicleProfileId"
          },
          "points": {
            "description": "The query points used to calculate the route, requiring at least a start and a destination point, with optional via-points in between.\n",
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number",
                "format": "double"
              }
            },
            "example": [
              [
                11.539421,
                48.118477
              ],
              [
                11.559023,
                48.12228
              ]
            ]
          },
          "point_hints": {
            "description": "Optional parameter. Specifies a hint for each point in the `points` array to prefer a certain street for the closest location lookup. 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. Make sure you do not include the house number of city name and only the street name to improve the quality of the matching.",
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "Lindenschmitstraße",
              "Thalkirchener Str."
            ]
          },
          "snap_preventions": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "motorway",
                "trunk",
                "bridge",
                "ford",
                "tunnel",
                "ferry"
              ]
            },
            "description": "Optional parameter. 'Snapping' is the process of finding the closest road location for GPS coordinates provided in the `points` array. The `snap_preventions` array allows you to prevent snapping to specific types of roads. For example, if the array includes `bridge`, then the routing engine will avoid snapping to a bridge, even if it is the closest road for the given point. Note that once snapped the routing algorithm can still route over bridges (or the other values). To avoid this you need to use the `custom_model`.",
            "example": [
              "motorway",
              "trunk",
              "bridge",
              "tunnel",
              "ferry",
              "ford"
            ]
          },
          "curbsides": {
            "description": "Optional parameter. It specifies on which side a point should be relative to the driver when she leaves/arrives at a start/target/via point. You need to specify this parameter for either none or all points. Only supported for motor vehicle profiles and OpenStreetMap.",
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "any",
                "right",
                "left"
              ]
            },
            "example": [
              "any",
              "right"
            ]
          },
          "locale": {
            "description": "The locale of the resulting turn instructions. E.g. `pt_PT` for Portuguese or `de` for German.\n",
            "type": "string",
            "default": "en"
          },
          "elevation": {
            "type": "boolean",
            "description": "If `true`, a third coordinate, the altitude, is included with all positions in the response.\nThis changes the format of the `points` and `snapped_waypoints` fields of the response, in both their\nencodings. Unless you switch off the `points_encoded` parameter, you need special code on the\nclient side that can handle three-dimensional coordinates.\n",
            "default": false
          },
          "details": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Optional parameter. The following path details are available: `street_name`, `street_ref`, `street_destination`, `leg_time`, `leg_distance`, `roundabout`, `country`, `time`, `distance`, `max_speed`,\n`max_weight`, `max_width`, `toll`, `road_class`, `road_class_link`, `road_access`, `road_environment`, `hazmat`, `hazmat_tunnel`, `hazmat_water`, \n`lanes`, `surface`, `smoothness`, `hike_rating`, `mtb_rating`, `foot_network`, `bike_network`. Read more about the usage of path details [here](https://discuss.graphhopper.com/t/2539).\n"
          },
          "optimize": {
            "type": "string",
            "default": "false",
            "description": "Normally, the calculated route will visit the points in the order you specified them.\nIf you have more than two points, you can set this parameter to `\"true\"` and the points may be re-ordered to minimize the total travel time.\nKeep in mind that the limits on the number of locations of the Route Optimization API applies, and the request costs more credits.\n"
          },
          "instructions": {
            "type": "boolean",
            "default": true,
            "description": "If instructions should be calculated and returned\n"
          },
          "calc_points": {
            "type": "boolean",
            "default": true,
            "description": "If the points for the route should be calculated at all.\n"
          },
          "debug": {
            "type": "boolean",
            "default": false,
            "description": "If `true`, the output will be formatted.\n"
          },
          "points_encoded": {
            "type": "boolean",
            "default": true,
            "description": "Allows changing the encoding of location data in the response. The default is polyline encoding, which is compact\nbut requires special client code to unpack. (We provide it in our JavaScript client library!)\nSet this parameter to `false` to switch the encoding to simple coordinate pairs like `[lon,lat]`, or `[lon,lat,elevation]`.\nSee the description of the response format for more information.\n"
          },
          "ch.disable": {
            "type": "boolean",
            "default": false,
            "description": "Use `true` to enable the flexible mode to use the `custom_model` or any of the following options below.\n"
          },
          "custom_model": {
            "$ref": "#/components/schemas/CustomModel"
          },
          "headings": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "description": "Favour a heading direction for a certain point. Specify either one heading for the start point or as many as there are points.\nIn this case headings are associated by their order to the specific points. Headings are given as north based clockwise angle between 0 and 360 degree.\nThis headings parameter also influences the tour generated with `algorithm=round_trip` and forces the initial direction.  Requires `ch.disable=true`.\n"
          },
          "heading_penalty": {
            "type": "integer",
            "format": "int32",
            "default": 300,
            "description": "Time penalty in seconds for not obeying a specified heading. Requires `ch.disable=true`.\n"
          },
          "pass_through": {
            "type": "boolean",
            "default": false,
            "description": "If `true`, u-turns are avoided at via-points with regard to the `heading_penalty`. Requires `ch.disable=true`.\n"
          },
          "algorithm": {
            "type": "string",
            "enum": [
              "round_trip",
              "alternative_route"
            ],
            "description": "Rather than looking for the shortest or fastest path, this parameter lets you solve two different problems related to routing:\nWith `alternative_route`, we give you not one but several routes that are close to optimal, but\nnot too similar to each other. \nWith `round_trip`, the route will get you back to where you started. This is meant for fun (think of\na bike trip), so we will add some randomness.\nYou can control both of these features with additional parameters, see below. \n"
          },
          "round_trip.distance": {
            "type": "integer",
            "format": "int32",
            "default": 10000,
            "description": "If `algorithm=round_trip`, this parameter configures approximative length of the resulting round trip.\n"
          },
          "round_trip.seed": {
            "type": "integer",
            "format": "int64",
            "description": "If `algorithm=round_trip`, this sets the random seed. Change this to get a different tour for each value.\n"
          },
          "alternative_route.max_paths": {
            "type": "integer",
            "format": "int32",
            "default": 2,
            "description": "If `algorithm=alternative_route`, this parameter sets the number of maximum paths which should be calculated. Increasing can lead to worse alternatives.\n"
          },
          "alternative_route.max_weight_factor": {
            "type": "number",
            "default": 1.4,
            "description": "If `algorithm=alternative_route`, this parameter sets the factor by which the alternatives routes can be longer than the optimal route. Increasing can lead to worse alternatives.\n"
          },
          "alternative_route.max_share_factor": {
            "type": "number",
            "default": 0.6,
            "description": "If `algorithm=alternative_route`, this parameter specifies how similar an alternative route can be to the optimal route. Increasing can lead to worse alternatives.\n"
          }
        },
        "example": {
          "profile": "bike",
          "points": [
            [
              11.539421,
              48.118477
            ],
            [
              11.559023,
              48.12228
            ]
          ],
          "point_hints": [
            "Lindenschmitstraße",
            "Thalkirchener Str."
          ],
          "snap_preventions": [
            "motorway",
            "ferry",
            "tunnel"
          ],
          "details": [
            "road_class",
            "surface"
          ]
        }
      },
      "CustomModel": {
        "type": "object",
        "properties": {
          "speed": {
            "description": "See [speed customization](#tag/Custom-Model/Customizing-speed)",
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "priority": {
            "description": "See [priority customization](#tag/Custom-Model/Customizing-priority)",
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "distance_influence": {
            "description": "Use higher values to prefer shorter routes. See [here](#tag/Custom-Model/Customizing-distance_influence) for more details.",
            "type": "number",
            "default": 70
          },
          "areas": {
            "type": "object",
            "$ref": "#/components/schemas/FeatureCollection",
            "description": "Areas are given in a GeoJson format as FeatureCollection. See more details and an example [here](#tag/Custom-Model/Define-areas).\n"
          }
        },
        "description": "The custom_model modifies the routing behaviour of the specified profile. See the [detailed documentation](#tag/Custom-Model). \nBelow is a complete request example in Berlin that limits all speeds to 100km/h, excludes motorways and makes shorter routes a bit more likely than the default due to a higher distance_influence. \nNote that it also includes the `\"ch.disable\": true` parameter which is required to make use of `custom_model`.\n\n```json\n{\n  \"points\": [\n    [\n      13.31543,\n      52.509535\n    ],\n    [\n      13.29779,\n      52.512434\n    ]\n  ],\n  \"profile\": \"car\",\n  \"ch.disable\": true,\n  \"custom_model\": {\n    \"speed\": [\n      {\n        \"if\": \"true\",\n        \"limit_to\": \"100\"\n      }\n    ],\n    \"priority\": [\n      {\n        \"if\": \"road_class == MOTORWAY\",\n        \"multiply_by\": \"0\"\n      }\n    ],\n    \"distance_influence\": 100\n  }\n} \n```\n"
      },
      "CustomModelForProfile": {
        "type": "object",
        "properties": {
          "speed": {
            "description": "See [speed customization](#tag/Custom-Model/Customizing-speed)",
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "priority": {
            "description": "See [priority customization](#tag/Custom-Model/Customizing-priority)",
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "distance_influence": {
            "description": "Use higher values to prefer shorter routes. See [here](#tag/Custom-Model/Customizing-distance_influence) for more details.",
            "type": "number",
            "default": 70
          },
          "areas": {
            "type": "object",
            "description": "Areas are given in a GeoJson format. Currently only one format is supported: one object with type Feature, a geometry with type Polygon and optional (but ignored) id and properties fields. See more details and an example [here](#tag/Custom-Model/Define-areas).\n"
          }
        },
        "description": "The custom_model modifies the routing behaviour of the given `profile`. See the [detailed documentation](#tag/Custom-Model). \nHere is a complete example that limits all speeds to 100km/h, avoids motorways and makes shorter routes a bit more likely than the default due to a higher distance_influence.\n\n```json\n{\n  \"speed\": [\n    {\n      \"if\": \"true\",\n      \"limit_to\": 100\n    }\n  ],\n  \"priority\": [\n    {\n      \"if\": \"road_class == MOTORWAY\",\n      \"multiply_by\": 0.1\n    }\n  ],\n  \"distance_influence\": 100\n}\n```        \n"
      },
      "ProfileRequest": {
        "type": "object",
        "properties": {
          "profile": {
            "type": "string",
            "description": "The built-in profile your new custom profile shall be based on.",
            "enum": [
              "foot",
              "bike",
              "ecargobike",
              "car",
              "small_truck",
              "truck",
              "scooter"
            ]
          },
          "bounds": {
            "type": "object",
            "anyOf": [
              {
                "$ref": "#/components/schemas/BBox"
              },
              {
                "$ref": "#/components/schemas/FeatureCollection"
              }
            ]
          },
          "custom_model": {
            "$ref": "#/components/schemas/CustomModelForProfile"
          }
        },
        "example": {
          "bounds": {
            "bbox": [
              11.45462,
              48.00954,
              11.77322,
              48.2076
            ]
          },
          "custom_model": {
            "priority": [
              {
                "if": "road_access == PRIVATE",
                "multiply_by": "0"
              },
              {
                "if": "road_class == MOTORWAY",
                "multiply_by": "0"
              }
            ]
          },
          "profile": "car"
        }
      },
      "ProfileResponse": {
        "type": "object",
        "properties": {
          "profile": {
            "type": "string",
            "description": "The built-in profile this custom profile is based on."
          },
          "bounds": {
            "type": "object",
            "properties": {
              "bbox": {
                "type": "array",
                "description": "A rectangular area given as an array [minLon, minLat, maxLon, maxLat]. The profile will only work in this area.",
                "items": {
                  "type": "number",
                  "format": "double"
                }
              }
            }
          },
          "custom_model": {
            "$ref": "#/components/schemas/CustomModelForProfile"
          },
          "id": {
            "type": "string",
            "description": "The name of the created profile. Use this as the `profile` parameter for the /route API etc. For route optimization requests you need to define a vehicle_type where you can enter the custom profile."
          }
        },
        "example": {
          "id": "cp_shc_1_6544924f-4d20-4f71-b86d-6b1f0740fcf8",
          "profile": "car",
          "bounds": {
            "bbox": [
              11.45462,
              48.00954,
              11.77322,
              48.2076
            ]
          },
          "custom_model": {
            "areas": {
              "type": "FeatureCollection",
              "features": []
            },
            "priority": [
              {
                "if": "road_access == PRIVATE",
                "multiply_by": "0"
              },
              {
                "if": "road_class == MOTORWAY",
                "multiply_by": "0"
              }
            ],
            "speed": []
          }
        }
      },
      "ProfileGetResponse": {
        "type": "array",
        "description": "The existing custom profiles including their ids",
        "items": {
          "$ref": "#/components/schemas/ProfileResponse"
        }
      },
      "RouteResponse": {
        "type": "object",
        "properties": {
          "paths": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RouteResponsePath"
            }
          },
          "info": {
            "$ref": "#/components/schemas/ResponseInfo"
          }
        }
      },
      "EncodedLineString": {
        "type": "string",
        "description": "A polyline-encoded list of positions. You'll need to decode this string in client code. We provide open source code in [Java](https://github.com/graphhopper/graphhopper/blob/e649aaed8d3f4378bf2d8889bbbc2318261eabb2/web-api/src/main/java/com/graphhopper/http/WebHelper.java#L54) and [JavaScript](https://github.com/graphhopper/directions-api-js-client/blob/cf43d1a5bc93a3e8007a44fcfc551117e4fa49bc/src/GHUtil.js#L27)."
      },
      "BBox": {
        "type": "object",
        "properties": {
          "bbox": {
            "type": "array",
            "description": "A rectangular area given as an array [minLon, minLat, maxLon, maxLat]. The created profile will only work in this area. The maximum area size is 160 000 square kilometers.",
            "items": {
              "type": "number",
              "format": "double"
            }
          }
        }
      },
      "FeatureCollection": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "FeatureCollection"
            ]
          },
          "features": {
            "description": "A FeatureCollection is an array of type \"Feature\" from GeoJSON",
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "enum": [
                    "Feature"
                  ]
                },
                "geometry": {
                  "$ref": "#/components/schemas/Polygon"
                }
              }
            }
          }
        }
      },
      "RouteResponsePath": {
        "type": "object",
        "properties": {
          "distance": {
            "description": "The total distance, in meters. To get this information for one 'leg' please read [this blog post](https://www.graphhopper.com/blog/2019/11/28/routing-api-using-path-details/).\n",
            "type": "number",
            "format": "double"
          },
          "time": {
            "description": "The total travel time, in milliseconds. To get this information for one 'leg' please read [this blog post](https://www.graphhopper.com/blog/2019/11/28/routing-api-using-path-details/).\n",
            "type": "integer",
            "format": "int64"
          },
          "ascend": {
            "description": "The total ascent, in meters.\n",
            "type": "number",
            "format": "double"
          },
          "descend": {
            "description": "The total descent, in meters.\n",
            "type": "number",
            "format": "double"
          },
          "points": {
            "allOf": [
              {
                "description": "The geometry of the route. The format depends on the value of `points_encoded`.\n"
              },
              {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/EncodedLineString"
                  },
                  {
                    "$ref": "#/components/schemas/LineString"
                  }
                ]
              }
            ]
          },
          "snapped_waypoints": {
            "allOf": [
              {
                "description": "The snapped input points. The format depends on the value of `points_encoded`.\n"
              },
              {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/EncodedLineString"
                  },
                  {
                    "$ref": "#/components/schemas/LineString"
                  }
                ]
              }
            ]
          },
          "points_encoded": {
            "description": "Whether the `points` and `snapped_waypoints` fields are polyline-encoded strings rather than JSON arrays\nof coordinates. See the field description for more information on the two formats.\n",
            "type": "boolean"
          },
          "bbox": {
            "description": "The bounding box of the route geometry. Format: `[minLon, minLat, maxLon, maxLat]`.\n",
            "type": "array",
            "items": {
              "type": "number",
              "format": "double"
            }
          },
          "instructions": {
            "type": "array",
            "description": "The instructions for this route. This feature is under active development, and our instructions can sometimes be misleading,\nso be mindful when using them for navigation.\n",
            "items": {
              "type": "object",
              "properties": {
                "text": {
                  "type": "string",
                  "description": "A description what the user has to do in order to follow the route. The language depends on the locale parameter."
                },
                "street_name": {
                  "type": "string",
                  "description": "The name of the street to turn onto in order to follow the route."
                },
                "heading": {
                  "type": "number",
                  "format": "double",
                  "description": "The optional heading for this roundabout instruction."
                },
                "last_heading": {
                  "type": "number",
                  "format": "double",
                  "description": "The optional last heading for this roundabout instruction."
                },
                "distance": {
                  "type": "number",
                  "format": "double",
                  "description": "The distance for this instruction, in meters."
                },
                "time": {
                  "type": "integer",
                  "format": "int32",
                  "description": "The duration for this instruction, in milliseconds."
                },
                "interval": {
                  "type": "array",
                  "items": {
                    "type": "integer",
                    "format": "int32"
                  },
                  "description": "Two indices into `points`, referring to the beginning and the end of the segment of the route\nthis instruction refers to.\n"
                },
                "sign": {
                  "type": "integer",
                  "format": "int32",
                  "description": "A number which specifies the sign to show:\n\n| sign | description  |\n|---|---|\n|-98| an U-turn without the knowledge if it is a right or left U-turn |\n| -8| a left U-turn |\n| -7| keep left |\n| -6| **not yet used**: leave roundabout |\n| -3| turn sharp left |\n| -2| turn left |\n| -1| turn slight left |\n|  0| continue on street |\n|  1| turn slight right |\n|  2| turn right |\n|  3| turn sharp right |\n|  4| the finish instruction before the last point |\n|  5| the instruction before a via point |\n|  6| the instruction before entering a roundabout |\n|  7| keep right |\n|  8| a right U-turn |\n|  *| **For future compatibility** it is important that all clients are able to handle also unknown instruction sign numbers\n"
                },
                "exit_number": {
                  "type": "integer",
                  "format": "int32",
                  "description": "Only available for roundabout instructions (sign is 6). The count of exits at which the route leaves the roundabout.\n"
                },
                "turn_angle": {
                  "type": "number",
                  "format": "double",
                  "description": "Only available for roundabout instructions (sign is 6). The radian of the route within the roundabout `0 < r < 2*PI` for clockwise and\n`-2*PI < r < 0` for counterclockwise turns.\n"
                }
              }
            }
          },
          "details": {
            "type": "object",
            "description": "Details, as requested with the `details` parameter. Consider the value `{\"street_name\": [[0,2,\"Frankfurter Straße\"],[2,6,\"Zollweg\"]]}`.\nIn this example, the route uses two streets: The first, Frankfurter Straße, is\nused between `points[0]` and `points[2]`, and the second, Zollweg, between `points[2]` and `points[6]`.\nRead more about the usage of path details [here](https://discuss.graphhopper.com/t/2539).\n"
          },
          "points_order": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "An array of indices (zero-based), specifiying the order in which the input points are visited.\nOnly present if the `optimize` parameter was used.\n"
          }
        }
      },
      "ResponseInfo": {
        "type": "object",
        "description": "Additional information for your request",
        "properties": {
          "copyrights": {
            "description": "Attribution according to our documentation is necessary if no white-label option included.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "took": {
            "type": "number",
            "format": "double"
          }
        }
      },
      "IsochroneResponse": {
        "type": "object",
        "properties": {
          "polygons": {
            "type": "array",
            "description": "The list of polygons in GeoJson format. It can be used e.g. in the Leaflet framework:\n\n```\nL.geoJson(json.polygons).addTo(map)\n```\n\nThe number of polygon is identical to the specified buckets in the query. Every polygon contains the bucket number in the properties section of the GeoJson.\n",
            "items": {
              "$ref": "#/components/schemas/IsochroneResponsePolygon"
            }
          }
        },
        "example": {
          "polygons": [
            {
              "properties": {
                "bucket": 0
              },
              "type": "Feature",
              "geometry": {
                "type": "Polygon",
                "coordinates": [
                  [
                    13.351851,
                    52.51345
                  ],
                  [
                    13.350402,
                    52.516949
                  ],
                  [
                    13.352598,
                    52.522252
                  ],
                  [
                    13.351851,
                    52.51345
                  ]
                ]
              }
            }
          ]
        }
      },
      "IsochroneResponsePolygon": {
        "type": "object",
        "description": "A found path",
        "properties": {
          "properties": {
            "type": "object",
            "properties": {
              "bucket": {
                "type": "integer",
                "format": "int32"
              }
            }
          },
          "type": {
            "type": "string"
          },
          "geometry": {
            "$ref": "#/components/schemas/Polygon"
          }
        }
      },
      "LineString": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string"
          },
          "coordinates": {
            "type": "array",
            "description": "A list of coordinate pairs or triples, `[lon,lat]` or `[lon,lat,elevation]`.\n",
            "items": {
              "type": "array",
              "items": {
                "type": "number"
              }
            }
          }
        }
      },
      "Polygon": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "Polygon"
            ]
          },
          "coordinates": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "array",
                "items": {
                  "type": "number"
                }
              }
            }
          }
        }
      },
      "GHError": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "hints": {
            "description": "Optional error information.",
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "JobId": {
        "type": "object",
        "properties": {
          "job_id": {
            "type": "string",
            "format": "uuid",
            "description": "UUID. Unique id for your job/request with which you can fetch your solution",
            "example": "44886560-b584-4da5-b245-768151dacd8f"
          }
        }
      },
      "BadRequest": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Short error message",
            "example": "Bad Request"
          },
          "hints": {
            "type": "array",
            "description": "Optional error information.",
            "items": {
              "$ref": "#/components/schemas/ErrorMessage"
            }
          },
          "status": {
            "type": "string",
            "description": "status",
            "default": "finished",
            "example": "finished"
          }
        }
      },
      "ErrorMessage": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "error message",
            "example": "unsupported json property [vehiles]. allowed properties: [vehicles, vehicle_types, services, shipments, relations, algorithm, objectives, cost_matrices, configuration]"
          },
          "details": {
            "type": "string",
            "description": "Details",
            "example": "class java.lang.IllegalArgumentException"
          }
        }
      },
      "InternalErrorMessage": {
        "type": "object",
        "properties": {
          "code": {
            "type": "integer",
            "format": "int32",
            "default": 500,
            "example": 500
          },
          "message": {
            "type": "string",
            "description": "Details",
            "example": "There has been an internal server error."
          }
        }
      },
      "Request": {
        "type": "object",
        "properties": {
          "vehicles": {
            "type": "array",
            "description": "Specifies the available vehicles.",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/Vehicle"
            }
          },
          "vehicle_types": {
            "type": "array",
            "description": "Specifies the available vehicle types. These types can be assigned to vehicles.",
            "items": {
              "$ref": "#/components/schemas/VehicleType"
            }
          },
          "services": {
            "type": "array",
            "description": "Specifies the orders of the type \"service\". These are, for example, pickups, deliveries, or other stops to be visited by the specified vehicles. Each of these orders contains only one location.",
            "items": {
              "$ref": "#/components/schemas/Service"
            }
          },
          "shipments": {
            "type": "array",
            "description": "Specifies the available shipments. Each shipment consists of a pickup and a delivery. For a single shipment, the pickup must always occur before the delivery. However, pickups and deliveries from multiple shipments can be sequenced independently.",
            "items": {
              "$ref": "#/components/schemas/Shipment"
            }
          },
          "relations": {
            "type": "array",
            "description": "Defines additional relationships between orders.",
            "items": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/JobRelation"
                },
                {
                  "$ref": "#/components/schemas/GroupRelation"
                }
              ]
            }
          },
          "algorithm": {
            "$ref": "#/components/schemas/Algorithm"
          },
          "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": {
              "$ref": "#/components/schemas/Objective"
            },
            "example": [
              {
                "type": "min",
                "value": "vehicles"
              },
              {
                "type": "min",
                "value": "completion_time"
              }
            ]
          },
          "cost_matrices": {
            "type": "array",
            "description": "Specifies your own transport time and distance matrices.",
            "items": {
              "$ref": "#/components/schemas/CostMatrix"
            }
          },
          "configuration": {
            "$ref": "#/components/schemas/Configuration",
            "description": "Specifies general configurations."
          }
        }
      },
      "Vehicle": {
        "type": "object",
        "properties": {
          "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.",
            "example": "vehicle-1"
          },
          "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.",
            "default": "default-type",
            "example": "my-own-type"
          },
          "shifts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Shift"
            },
            "description": "An array of shift configurations for this vehicle."
          },
          "start_address": {
            "$ref": "#/components/schemas/Address"
          },
          "end_address": {
            "$ref": "#/components/schemas/Address",
            "description": "If this is omitted AND return_to_depot is true then the vehicle needs to return to its start_address."
          },
          "break": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TimeWindowBreak"
              },
              {
                "$ref": "#/components/schemas/DriveTimeBreak"
              }
            ]
          },
          "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.",
            "default": true
          },
          "earliest_start": {
            "type": "integer",
            "format": "int64",
            "description": "Earliest start of vehicle in seconds. It is recommended to use the unix timestamp.",
            "default": 0
          },
          "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. Omit this field to indicate no limit."
          },
          "skills": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "An array of skills, i.e. an array of strings (not case sensitive).",
            "example": [
              "drilling_machine",
              "screw_driver"
            ]
          },
          "max_distance": {
            "type": "integer",
            "format": "int64",
            "description": "Specifies the maximum distance (in meters) a vehicle can go.",
            "example": 400000
          },
          "max_driving_time": {
            "type": "integer",
            "format": "int64",
            "description": "Specifies the maximum driving time (in seconds) a vehicle/driver is allowed, i.e. the maximum time spent on the road (service and waiting times are not included).",
            "example": 28800
          },
          "max_jobs": {
            "type": "integer",
            "format": "int32",
            "description": "Specifies the maximum number of jobs a vehicle can load.",
            "example": 12
          },
          "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.",
            "example": 12
          },
          "max_activities": {
            "type": "integer",
            "format": "int32",
            "description": "Specifies the maximum number of activities a vehicle can conduct.",
            "example": 24
          },
          "move_to_end_address": {
            "type": "boolean",
            "description": "Indicates whether a vehicle should be moved even though it has not been assigned any jobs."
          }
        },
        "required": [
          "vehicle_id"
        ]
      },
      "VehicleProfileId": {
        "type": "string",
        "description": "The routing profile. It determines the network, speed and other physical attributes used when computing the route. See the section about [routing profiles](#tag/Map-Data-and-Routing-Profiles) for more details and valid profile values.",
        "default": "car"
      },
      "Shift": {
        "type": "object",
        "description": "Shift of vehicle.",
        "properties": {
          "shift_id": {
            "type": "string",
            "description": "A unique identifier for this vehicle's shift."
          },
          "start_address": {
            "$ref": "#/components/schemas/Address"
          },
          "end_address": {
            "$ref": "#/components/schemas/Address",
            "description": "If this is omitted AND return_to_depot is true then the vehicle needs to return to its start_address."
          },
          "earliest_start": {
            "type": "integer",
            "format": "int64",
            "description": "Earliest start of vehicle in seconds. It is recommended to use the unix timestamp.",
            "default": 0
          },
          "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. Omit this field to indicate no limit."
          },
          "return_to_depot": {
            "type": "boolean",
            "description": "If true, vehicle returns to its start location (or specified end location). If false, vehicle can end at any customer location that optimizes the objective function.",
            "default": true
          },
          "break": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TimeWindowBreak"
              },
              {
                "$ref": "#/components/schemas/DriveTimeBreak"
              }
            ]
          }
        }
      },
      "Algorithm": {
        "type": "object",
        "description": "Use `objectives` instead.",
        "deprecated": true,
        "properties": {
          "problem_type": {
            "type": "string",
            "enum": [
              "min",
              "min-max"
            ]
          },
          "objective": {
            "type": "string",
            "enum": [
              "transport_time",
              "completion_time"
            ]
          }
        }
      },
      "Address": {
        "type": "object",
        "properties": {
          "location_id": {
            "type": "string",
            "description": "Specifies the id of the location.",
            "example": "550e8400-e29b-11d4-a716-446655440000"
          },
          "name": {
            "type": "string",
            "description": "Name of location.",
            "example": "Queens Victoria Street 70, Second Floor, Flat 245"
          },
          "lon": {
            "format": "double",
            "type": "number",
            "description": "Longitude of location.",
            "example": -0.092869
          },
          "lat": {
            "format": "double",
            "type": "number",
            "description": "Latitude of location.",
            "example": 51.512665
          },
          "street_hint": {
            "type": "string",
            "description": "Optional parameter. Specifies a hint containing the street name to better snap the coordinates (lon,lat) to the road network. For example, if an address or building has two or more neighboring streets, you can control which street is used to find the closest location.",
            "example": "Queens Victoria Street 70"
          },
          "curbside": {
            "type": "string",
            "enum": [
              "right",
              "left",
              "any"
            ],
            "default": "any",
            "description": "Optional parameter. Specifies on which side a point should be relative to the driver when they leave/arrive at a start/target/via point. Only supported for motor vehicles and OpenStreetMap.\nIf you would like to arrive at this address without having to cross the street, use `curbside=right/left` for countries with right/left-hand driving. Using `curbside=any` is the same as not specifying this parameter at all.\n"
          }
        },
        "required": [
          "location_id",
          "lon",
          "lat"
        ]
      },
      "ResponseAddress": {
        "type": "object",
        "description": "Address of activity",
        "properties": {
          "location_id": {
            "type": "string",
            "description": "Specifies the id of the location.",
            "example": "550e8400-e29b-11d4-a716-446655440000"
          },
          "name": {
            "type": "string",
            "description": "Name of location.",
            "example": "Queens Victoria Street 70, Second Floor, Flat 245"
          },
          "lon": {
            "format": "double",
            "type": "number",
            "description": "Longitude of location.",
            "example": -0.092869
          },
          "lat": {
            "format": "double",
            "type": "number",
            "description": "Latitude of location.",
            "example": 51.512665
          },
          "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.",
            "example": "Queens Victoria Street 70"
          },
          "snapped_waypoint": {
            "$ref": "#/components/schemas/SnappedWaypoint"
          }
        }
      },
      "SnappedWaypoint": {
        "type": "object",
        "description": "Access point to the road network. It is only available if `return_snapped_waypoints` is true (by default it is false).",
        "properties": {
          "lon": {
            "format": "double",
            "type": "number",
            "description": "Longitude of location.",
            "example": -0.092869
          },
          "lat": {
            "format": "double",
            "type": "number",
            "description": "Latitude of location.",
            "example": 51.512665
          }
        }
      },
      "DriveTimeBreak": {
        "type": "object",
        "properties": {
          "duration": {
            "type": "integer",
            "format": "int64",
            "description": "Specifies the duration of the break in seconds.",
            "example": 2700
          },
          "max_driving_time": {
            "type": "integer",
            "format": "int64",
            "description": "Specifies the max driving time (in a row) without break in seconds.",
            "example": 14400
          },
          "initial_driving_time": {
            "type": "integer",
            "format": "int64",
            "description": "Specifies the initial (current) driving time of a driver to allow dynamic adaptations in seconds.",
            "example": 3600
          },
          "possible_split": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Array specifying how a break duration (in seconds) can be split into several smaller breaks",
            "example": [
              900,
              1800
            ]
          }
        },
        "required": [
          "duration",
          "max_driving_time"
        ]
      },
      "TimeWindowBreak": {
        "type": "object",
        "properties": {
          "earliest": {
            "type": "integer",
            "format": "int64",
            "description": "Specifies the earliest start time of the break in seconds.",
            "example": 1550136467
          },
          "latest": {
            "type": "integer",
            "format": "int64",
            "description": "Specifies the latest start time of break in seconds.",
            "example": 1550148467
          },
          "duration": {
            "type": "integer",
            "format": "int64",
            "description": "Specifies the duration of the break in seconds.",
            "example": 2700
          }
        },
        "required": [
          "earliest",
          "latest",
          "duration"
        ]
      },
      "VehicleType": {
        "type": "object",
        "properties": {
          "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.",
            "example": "my-own-type"
          },
          "profile": {
            "$ref": "#/components/schemas/VehicleProfileId"
          },
          "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"
            },
            "default": [
              0
            ],
            "example": [
              100,
              500
            ]
          },
          "speed_factor": {
            "format": "double",
            "type": "number",
            "description": "Specifies a speed factor for this vehicle type. For example, if a vehicle using this type should travel at half the speed calculated by our routing engine, set the speed factor to 0.5.",
            "default": 1
          },
          "service_time_factor": {
            "format": "double",
            "type": "number",
            "description": "Specifies a service time factor for this vehicle type. For example, if a vehicle/driver using this type can complete services twice as fast as specified in the service or shipment, set this to 0.5.",
            "default": 1
          },
          "cost_per_meter": {
            "format": "double",
            "type": "number",
            "description": "**_BETA feature_**! Cost parameter per distance unit, here meter is used"
          },
          "cost_per_second": {
            "format": "double",
            "type": "number",
            "description": "**_BETA feature_**! Cost parameter per time unit, here second is used"
          },
          "cost_per_activation": {
            "format": "double",
            "type": "number",
            "description": "**_BETA feature_**! Cost parameter vehicle activation, i.e. fixed costs per vehicle"
          },
          "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 information is used. Traffic data is not yet available for \"openstreetmap\", so setting this to true has no effect when using OpenStreetMap.",
            "default": false
          },
          "network_data_provider": {
            "type": "string",
            "description": "Specifies the network data provider. Either use [`openstreetmap`](#tag/Map-Data-and-Routing-Profiles/OpenStreetMap) (default) or [`tomtom`](#tag/Map-Data-and-Routing-Profiles/TomTom) (add-on required).",
            "enum": [
              "openstreetmap",
              "tomtom"
            ],
            "default": "openstreetmap"
          }
        },
        "required": [
          "type_id"
        ]
      },
      "Service": {
        "type": "object",
        "properties": {
          "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.",
            "example": "7fe77504-7df8-4497-843c-02d70b6490ce"
          },
          "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"
            ],
            "default": "service",
            "example": "delivery"
          },
          "priority": {
            "type": "integer",
            "format": "int32",
            "description": "Specifies the priority. Can be 1 = high priority to 10 = low priority. Priority only affects the solution when not all services can be assigned  (e.g., due to insufficient vehicle capacity, conflicting time windows,  or vehicle constraints). In these cases, the optimizer preferentially  assigns high-priority services and leaves low-priority services unassigned.  The lower the priority, the earlier these services are omitted from  the solution. When all services can be served within the given constraints,  priority has no effect - all services are assigned regardless of their  priority values, and the optimizer focuses solely on the specified objective  (e.g., minimizing distance or number of vehicles).\n",
            "default": 2,
            "example": 1
          },
          "name": {
            "type": "string",
            "description": "A meaningful name for the service, e.g. `\"deliver pizza\"`.",
            "example": "deliver pizza"
          },
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "duration": {
            "type": "integer",
            "minimum": 0,
            "maximum": 604800,
            "format": "int64",
            "description": "Specifies the duration of the service in seconds, i.e. how long it takes to perform the actual service. This time is charged for each activity—if multiple services occur at the same location, their durations are summed.",
            "default": 0,
            "example": 1800
          },
          "preparation_time": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "maximum": 604800,
            "description": "Specifies the preparation time in seconds. This time is added after arrival and before the service can begin, modeling tasks like finding a parking spot. Preparation time is only charged once when the location differs from the previous stop—if multiple consecutive activities share the same location, it is applied only to the first.",
            "default": 0,
            "example": 300
          },
          "setup_time": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "maximum": 604800,
            "description": "Specifies the setup time in seconds. This is a fixed overhead charged when arriving at a new location (e.g., dock check-in, security clearance, equipment preparation). Unlike `duration`, setup time is only charged once per location—if multiple consecutive activities share the same location, it is applied only to the first. The activity timeline is: arrival → preparation_time → waiting (if early) → setup_time → duration.",
            "default": 0,
            "example": 600
          },
          "time_windows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TimeWindow"
            },
            "description": "Specifies an array of time window objects (see TimeWindow object below). Specify the time either with the recommended Unix timestamp (the number of seconds since 1970-01-01) or you can count the seconds relative to Monday morning 00:00 and define the whole week in seconds. For example, Monday 9am is represented by 9 hours * 3600 sec/hour = 32400. Wednesday 1pm corresponds to 2 days * 24 hours/day * 3600 sec/hour + 13 hours * 3600 sec/hour = 219600. See our tutorial for more information.",
            "example": [
              {
                "earliest": 32400,
                "latest": 36000
              },
              {
                "earliest": 50400,
                "latest": 54000
              }
            ]
          },
          "size": {
            "type": "array",
            "description": "Size can have multiple dimensions and should correspond to the capacity dimension array of the vehicle type. For example, if the item that needs to be delivered has two size dimensions, volume and weight, specify it as follows: [ 20, 5 ], assuming a volume of 20 and a weight of 5.",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "default": [
              0
            ],
            "example": [
              30,
              5,
              1
            ]
          },
          "required_skills": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Specifies an array of required skills, i.e. an array of strings (not case sensitive). For example, if this service needs to be performed by a technician with a `drilling_machine` and a `screw_driver`, specify the array as follows: `[\"drilling_machine\",\"screw_driver\"]`. This means that the service can only be done by a vehicle (technician) that has both `drilling_machine` AND `screw_driver` in its skill array. Otherwise, it remains unassigned.",
            "example": [
              "drilling_machine",
              "screw_driver"
            ]
          },
          "allowed_vehicles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Specifies an array of allowed vehicles, i.e. an array of vehicle IDs. For example, if this service can only be performed by EITHER `technician_peter` OR `technician_stefan`, specify this as follows: `[\"technician_peter\",\"technician_stefan\"]`.",
            "example": [
              "technician_peter",
              "technician_stefan"
            ]
          },
          "disallowed_vehicles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Specifies an array of disallowed vehicles, i.e. an array of vehicle IDs.",
            "example": [
              "driver-A",
              "driver-B"
            ]
          },
          "preferred_vehicles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PreferredVehicle"
            },
            "description": "Specifies an array of preferred vehicles."
          },
          "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\". Omit this field to indicate no limit.",
            "example": 900
          },
          "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.",
            "example": "group-A"
          }
        },
        "required": [
          "id"
        ]
      },
      "Shipment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Specifies the ID of the shipment. IDs must be unique, so there must not be two services/shipments with the same ID.",
            "example": "7fe77504-7df8-4497-843c-02d70b6490ce"
          },
          "name": {
            "type": "string",
            "description": "A meaningful name for the shipment, e.g. \"pick up and deliver pizza to Peter\".",
            "example": "pick up and deliver pizza to Peter"
          },
          "priority": {
            "type": "integer",
            "format": "int32",
            "description": "Specifies the priority. Can be 1 = high priority to 10 = low priority. Priority only affects the solution when not all shipments can be assigned  (e.g., due to insufficient vehicle capacity, conflicting time windows,  or vehicle constraints). In these cases, the optimizer preferentially  assigns high-priority shipments and leaves low-priority shipments unassigned.  The lower the priority, the earlier these shipments are omitted from  the solution. When all shipments can be served within the given constraints,  priority has no effect - all shipments are assigned regardless of their  priority values, and the optimizer focuses solely on the specified objective  (e.g., minimizing distance or number of vehicles).\n",
            "default": 2,
            "example": 1
          },
          "pickup": {
            "$ref": "#/components/schemas/Stop"
          },
          "delivery": {
            "$ref": "#/components/schemas/Stop"
          },
          "size": {
            "type": "array",
            "description": "Size can have multiple dimensions and should correspond to the capacity dimension array of the vehicle type. For example, if the item that needs to be delivered has two size dimensions, volume and weight, specify it as follows: [ 20, 5 ], assuming a volume of 20 and a weight of 5.",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "default": [
              0
            ],
            "example": [
              3
            ]
          },
          "required_skills": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Specifies an array of required skills, i.e. an array of strings (not case sensitive). For example, if this shipment needs to be handled by a technician with a `drilling_machine` and a `screw_driver`, specify the array as follows: `[\"drilling_machine\",\"screw_driver\"]`. This means that the shipment can only be done by a vehicle (technician) that has both `drilling_machine` AND `screw_driver` in its skill array. Otherwise, it remains unassigned.",
            "example": [
              "drilling_machine",
              "screw_driver"
            ]
          },
          "allowed_vehicles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Specifies an array of allowed vehicles, i.e. an array of vehicle IDs. For example, if this shipment can only be handled by EITHER \"technician_peter\" OR \"technician_stefan\", specify this as follows: [\"technician_peter\",\"technician_stefan\"].",
            "example": [
              "technician_peter",
              "technician_stefan"
            ]
          },
          "disallowed_vehicles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Specifies an array of disallowed vehicles, i.e. an array of vehicle IDs.",
            "example": [
              "driver-A",
              "driver-B"
            ]
          },
          "preferred_vehicles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PreferredVehicle"
            },
            "description": "Specifies an array of preferred vehicles."
          },
          "max_time_in_vehicle": {
            "type": "integer",
            "format": "int64",
            "description": "Specifies the maximum time in seconds a shipment can stay in the vehicle. Omit this field to indicate no limit.",
            "example": 1800
          }
        },
        "required": [
          "id",
          "pickup",
          "delivery"
        ]
      },
      "Pickup": {
        "$ref": "#/components/schemas/Stop"
      },
      "Stop": {
        "type": "object",
        "properties": {
          "address": {
            "$ref": "#/components/schemas/Address",
            "description": "Specifies pickup or delivery address."
          },
          "duration": {
            "type": "integer",
            "minimum": 0,
            "maximum": 604800,
            "format": "int64",
            "description": "Specifies the duration of the pickup or delivery in seconds, e.g. how long it takes to load or unload items. This time is charged for each stop—if multiple pickups or deliveries occur at the same location, their durations are summed.",
            "default": 0,
            "example": 1800
          },
          "preparation_time": {
            "type": "integer",
            "minimum": 0,
            "maximum": 604800,
            "format": "int64",
            "description": "Specifies the preparation time in seconds. This time is added after arrival and before the pickup or delivery can begin, modeling tasks like finding a parking spot. Preparation time is only charged once when the location differs from the previous stop—if multiple consecutive activities share the same location, it is applied only to the first.",
            "default": 0,
            "example": 300
          },
          "setup_time": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "maximum": 604800,
            "description": "Specifies the setup time in seconds. This is a fixed overhead charged when arriving at a new location (e.g., dock check-in, security clearance, equipment preparation). Unlike `duration`, setup time is only charged once per location—if multiple consecutive activities share the same location, it is applied only to the first. The activity timeline is: arrival → preparation_time → waiting (if early) → setup_time → duration.",
            "default": 0,
            "example": 600
          },
          "time_windows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TimeWindow"
            },
            "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).",
            "example": [
              {
                "earliest": 32400,
                "latest": 36000
              },
              {
                "earliest": 50400,
                "latest": 54000
              }
            ]
          },
          "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.",
            "example": "ASAP"
          }
        }
      },
      "TimeWindow": {
        "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.",
            "default": 0
          },
          "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. Omit this field to indicate no limit."
          }
        }
      },
      "PreferredVehicle": {
        "type": "object",
        "properties": {
          "vehicle_id": {
            "type": "string",
            "description": "Id of the preferred vehicle."
          },
          "priority": {
            "type": "integer",
            "format": "int64",
            "description": "Number between 1 and 10 which indicates the priority of the preferred vehicle. 1 indicates the highest priority, 10 the lowest.",
            "default": 2
          }
        }
      },
      "Configuration": {
        "type": "object",
        "description": "Specifies general configurations that are taken into account when solving the vehicle routing problem.",
        "properties": {
          "routing": {
            "$ref": "#/components/schemas/Routing"
          },
          "optimization": {
            "$ref": "#/components/schemas/Optimization"
          }
        }
      },
      "Optimization": {
        "type": "object",
        "description": "This contains all optimization specific configurations.",
        "properties": {
          "free_insertion": {
            "type": "boolean",
            "description": "If you use groups, you sometimes want to place orders without group assignment in the best position, i.e. sometimes in the middle of a group and not before or after the group. This is not allowed by default. However, if this field here is \"true\", these orders (without a group assignment) can be inserted freely.",
            "default": false
          },
          "free_insertion_exempt_groups": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "When `free_insertion` is enabled, ungrouped orders can be inserted anywhere, including inside groups. Use this property to specify groups where ungrouped orders should NOT be inserted. This is useful when you have groups like \"asap\" (must be served first) or \"last\" (must be served last) that should stay compact. For example, with `free_insertion_exempt_groups: [\"asap\", \"last\"]`, ungrouped orders can be inserted freely between other groups, but not inside the \"asap\" or \"last\" groups, and not between start and \"asap\" or between \"last\" and end when using `in_direct_sequence` relations with these groups."
          },
          "auto_assign_radius": {
            "type": "number",
            "description": "Radius in meters. When set to a positive value, ungrouped jobs are automatically assigned to the nearest existing group based on road distance. This is useful when you use groups and group-level `in_sequence` to define an area visit order, and want new jobs to automatically cluster into the right area. Jobs outside the radius of all groups remain ungrouped. Requires `free_insertion: true` for ungrouped jobs to be placed freely.",
            "default": 0
          }
        }
      },
      "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.",
            "default": false
          },
          "consider_traffic": {
            "type": "boolean",
            "description": "Indicates whether historical traffic information should be considered.",
            "default": false
          },
          "network_data_provider": {
            "type": "string",
            "description": "Specifies the data provider. Read more about it [here](#tag/Map-Data-and-Routing-Profiles).",
            "enum": [
              "openstreetmap",
              "tomtom"
            ],
            "default": "openstreetmap"
          },
          "curbside_strictness": {
            "type": "string",
            "default": "soft",
            "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 immediately when points cannot be connected.",
            "default": false
          },
          "return_snapped_waypoints": {
            "type": "boolean",
            "description": "Indicates whether the solution should include snapped waypoints. Unlike the address coordinates, a snapped waypoint is the access point to the road network.",
            "default": false
          },
          "snap_preventions": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "motorway",
                "trunk",
                "bridge",
                "ford",
                "tunnel",
                "ferry"
              ]
            },
            "description": "Optional parameter. 'Snapping' is the process of finding the closest road location for GPS coordinates provided in the `points` array. The `snap_preventions` array allows you to prevent snapping to specific types of roads. For example, if the array includes `bridge`, then the routing engine will avoid snapping to a bridge, even if it is the closest road for the given point. Note that once snapped the routing algorithm can still route over bridges (or the other values). To avoid this you need to use the `custom_model`.",
            "example": [
              "motorway",
              "trunk",
              "bridge",
              "tunnel",
              "ferry",
              "ford"
            ]
          }
        }
      },
      "Objective": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Type of objective function, i.e. `min`, `min-max`, or `balance`.\n\n * `min`: Minimizes the objective value.\n * `min-max`: Minimizes the maximum objective value.\n * `balance`: **(Beta)** Optimizes for balanced workloads across drivers. Use with `value: completion_time` to balance working time, or `value: activities` to balance the number of stops per driver.\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\n#### Balance Objective (Beta)\n\nThe `balance` objective type provides a more sophisticated approach to workload balancing compared to `min-max`.\nWhile `min-max` only minimizes the maximum route value, `balance` optimizes for equal distribution of work across all drivers\nby minimizing the coefficient of variation (CV) of workloads.\n\nUse `balance` with:\n * `value: completion_time` - Balance working time (service time + travel time + waiting time) across drivers\n * `value: activities` - Balance the number of stops per driver\n\nThe optional `level` parameter (1-3) controls how strongly to prioritize balance:\n * `level: 1` - Mild balance preference, allows some variation for better travel efficiency\n * `level: 2` - Moderate balance (default), good trade-off between balance and efficiency\n * `level: 3` - Strict balance, prioritizes equal workloads even at the cost of longer travel\n\nExample:\n```json\n\"objectives\" : [\n   {\n      \"type\": \"balance\",\n      \"value\": \"completion_time\",\n      \"level\": 2\n   }\n]\n```\n\n**When to use `balance` vs `min-max`:**\n * Use `balance` when you want all drivers to have similar workloads (fairness)\n * Use `min-max` when you only care about minimizing the longest route (makespan)\n\n**Note:** The `balance` objective currently only supports services. Requests that combine `balance` objectives with shipments will return a `400` error.\n",
            "default": "min",
            "enum": [
              "min",
              "min-max",
              "balance"
            ]
          },
          "value": {
            "type": "string",
            "default": "transport_time",
            "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.\nThe `completion_time_last_stop`, on the other hand, refers to the completion time of the very last order in a tour or, in other words,\nthe completion time without the last section from the last stop to the end of the tour.\nThis is typically used if the orders are to be processed as quickly as possible.\nIf you solely want to minimize route duration, you should use simply use `route_duration`.\nThe objective value `vehicles` can only be used along with `min` and minimizes vehicles.\n\nFor `balance` objective type, only `completion_time` and `activities` are supported.\n",
            "enum": [
              "completion_time",
              "completion_time_last_stop",
              "route_duration",
              "transport_time",
              "vehicles",
              "activities"
            ]
          },
          "level": {
            "type": "integer",
            "format": "int32",
            "minimum": 1,
            "maximum": 3,
            "default": 2,
            "description": "**(Beta)** Level for `balance` objectives (1-3). Controls how strongly to prioritize balanced workloads.\n\n * `1` - Accept some workload variation for better travel efficiency\n * `2` - Moderate balance (default)\n * `3` - Strictly equal workloads, even at cost of longer travel\n\nOnly valid when `type` is `balance`. Ignored for other objective types.\n"
          }
        },
        "example": {
          "type": "min",
          "value": "vehicles"
        },
        "required": [
          "type",
          "value"
        ]
      },
      "CostMatrix": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Type of cost matrix. Currently \"default\" and \"google\" are supported.",
            "enum": [
              "default",
              "google"
            ]
          },
          "location_ids": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "data": {
            "type": "object",
            "description": "JSON data of matrix response",
            "properties": {
              "times": {
                "minItems": 1,
                "type": "array",
                "items": {
                  "type": "array",
                  "items": {
                    "type": "integer",
                    "format": "int64"
                  }
                }
              },
              "distances": {
                "minItems": 1,
                "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"
                  }
                }
              }
            }
          },
          "profile": {
            "type": "string",
            "description": "Vehicle profile, or empty for a catch-all fallback."
          }
        }
      },
      "GroupRelation": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Specifies the type of relation. It must be either of type `in_sequence`, `in_direct_sequence` or `neighbor`.\n",
            "example": "in_direct_sequence"
          },
          "groups": {
            "type": "array",
            "description": "An array of groups that should be related",
            "items": {
              "type": "string",
              "description": "group of services or shipments"
            },
            "example": [
              "group-A",
              "group-B"
            ]
          }
        },
        "required": [
          "type",
          "groups"
        ]
      },
      "JobRelation": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Specifies the type of relation. It must be either of type `in_same_route`, `not_in_same_route`, `in_sequence`, `in_direct_sequence`, `neighbor` or `in_area_sequence`.\n\n`in_same_route`: As the name suggests, it enforces the specified services or shipments to be in the same route. It can be specified as follows:\n\n```json\n{\n   \"type\": \"in_same_route\",\n   \"ids\": [\"serv_i_id\",\"serv_j_id\"]\n}\n```\n\nThis enforces service i to be in the same route as service j no matter which vehicle will be employed. If a specific vehicle (driver) is required to conduct this, just add a `vehicle_id` like this:\n\n```\n{\n   \"type\": \"in_same_route\",\n   \"ids\": [\"serv_i_id\",\"serv_j_id\"],\n   \"vehicle_id\": \"vehicle1\"\n}\n```\n\nThis not only enforces service i and j to be in the same route, but also ensures that both services are in the route of `vehicle1`.\n\n*Tip*: This way initial loads and vehicle routes can be modelled. For example, if your vehicles are already on the road and new orders come in, then vehicles can still be rescheduled subject to the orders that have already been assigned to these vehicles.\n\n`not_in_same_route`: It ensures that 2 or more orders are not transported by the same vehicle. It can be specified as follows:\n\n```json\n{\n   \"type\": \"not_in_same_route\",\n   \"ids\": [\"serv_i_id\",\"serv_j_id\"]\n}\n```\n\n\n`in_sequence`: This relation type enforces n jobs to be in sequence. It can be specified as\n\n```json\n{\n   \"type\": \"in_sequence\",\n   \"ids\": [\"serv_i_id\",\"serv_j_id\"]\n}\n```\n\nwhich means that service j needs to be in the same route as service i AND it needs to occur somewhere after service i. As described above, if a specific vehicle needs to perform these services, just add `vehicle_id`.\n\n\n`in_direct_sequence`: This enforces n services or shipments to be in direct sequence. It can be specified as\n\n```json\n{\n   \"type\": \"in_direct_sequence\",\n   \"ids\": [\"serv_i_id\",\"serv_j_id\",\"serv_k_id\"]\n}\n```\n\nThis causes service j to occur directly after service i, and service k to occur directly after service j, i.e. in strict sequence. Again, a specific vehicle can be assigned by adding a `vehicle_id` to the relation.\n\n`neighbor`: This specifies a neighbor relationship, i.e., if services i and j are to be neighbors, i must be either immediately before or after j. It can be specified as follows:\n\n```json\n{\n    \"type\": \"neighbor\",\n    \"ids\": [\"serv_i_id\",\"serv_j_id\"]\n}\n```\n\n`in_area_sequence`: This defines an area-level visit order. You pick one job per area as an anchor and set a radius. All other jobs within the radius of an anchor are automatically clustered into that area. Areas are visited in the specified order, and within each area the optimizer handles the details. It can be specified as follows:\n\n```json\n{\n   \"type\": \"in_area_sequence\",\n   \"ids\": [\"job_area_a\",\"job_area_b\",\"job_area_c\"],\n   \"area_radius\": 5000\n}\n```\n\nThis means: visit the area around `job_area_a` first, then the area around `job_area_b`, then `job_area_c`. Any ungrouped job within 5000 meters (road distance) of an anchor is automatically assigned to that area. Jobs outside all radii are placed wherever fits best.\n\nYou can assign the area sequence to a specific vehicle:\n\n```json\n{\n   \"type\": \"in_area_sequence\",\n   \"ids\": [\"job_area_a\",\"job_area_b\"],\n   \"area_radius\": 5000,\n   \"vehicle_id\": \"vehicle1\"\n}\n```\n\nMultiple `in_area_sequence` relations can be used to assign different area sequences to different vehicles. If an anchor job already has a `group`, that group name is used instead of an auto-generated one, and nearby jobs are assigned to it.\n\n*Special IDs*:\nIf you look at the previous example and you want service i to be the first in the route, use the special ID `start` as follows:\n\n```json\n{\n   \"type\": \"in_direct_sequence\",\n   \"ids\": [\"start\",\"serv_i_id\",\"serv_j_id\",\"serv_k_id\"]\n}\n```\n\nThis enforces the direct sequence of i, j, and k at the beginning of the route. If this sequence should be at the end of the route, use the special ID `end` like this:\n\n```json\n{\n   \"type\": \"in_direct_sequence\",\n   \"ids\": [\"serv_i_id\",\"service_j_id\",\"serv_k_id\",\"end\"]\n}\n```\n\nIf you deal with services then you need to use the 'id' of your services in the field 'ids'. To also consider sequences of the pickups and deliveries of your shipments, you need to use a special ID, i.e. use the shipment id plus the keyword `_pickup` or `_delivery`. For example, to ensure that the pickup and delivery of the shipment with the id 'my_shipment' are direct neighbors, you need the following specification:\n\n```\n{\n   \"type\": \"in_direct_sequence\",\n   \"ids\": [\"my_ship_pickup\",\"my_ship_delivery\"]\n}\n```\n\n",
            "example": "in_direct_sequence"
          },
          "ids": {
            "type": "array",
            "description": "Specifies an array of shipment and/or service ids that are in relation. If you deal with services then you need to use the id of your services in ids. To also consider sequences of the pickups and deliveries of your shipments, you need to use a special ID, i.e. use your shipment id plus the keyword `_pickup` or `_delivery`. If you want to place a service or shipment activity at the beginning of your route, use the special ID `start`. In turn, use `end` to place it at the end of the route.",
            "items": {
              "type": "string"
            },
            "example": [
              "pickup-1",
              "pickup-2"
            ]
          },
          "vehicle_id": {
            "type": "string",
            "description": "Id of pre-assigned vehicle, i.e. the vehicle id that is determined to conduct the services and shipments in this relation.",
            "example": "driver-Peter"
          },
          "area_radius": {
            "type": "number",
            "description": "Radius in meters. Required for `in_area_sequence` relations. Jobs within this road distance of an anchor job are automatically assigned to that area.",
            "example": 5000
          }
        },
        "required": [
          "type",
          "ids"
        ]
      },
      "Response": {
        "type": "object",
        "properties": {
          "copyrights": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Attribution"
            },
            "example": [
              "GraphHopper",
              "OpenStreetMap contributors"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "waiting_in_queue",
              "processing",
              "finished"
            ],
            "description": "Indicates the current status of the job",
            "example": "finished"
          },
          "waiting_time_in_queue": {
            "type": "integer",
            "format": "int64",
            "description": "Waiting time in milliseconds.",
            "example": 300000
          },
          "processing_time": {
            "type": "integer",
            "format": "int64",
            "description": "Processing time in ms. If job is still waiting in queue, processing_time is 0",
            "example": 900000
          },
          "solution": {
            "$ref": "#/components/schemas/Solution"
          }
        }
      },
      "Solution": {
        "type": "object",
        "description": "Only available if status field indicates `finished`.",
        "properties": {
          "costs": {
            "type": "integer",
            "format": "int32",
            "deprecated": true
          },
          "distance": {
            "type": "integer",
            "format": "int32",
            "description": "Overall distance traveled in meters, i.e. the sum of each route's transport distance.",
            "example": 1200
          },
          "time": {
            "type": "integer",
            "format": "int64",
            "deprecated": true,
            "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.",
            "example": 12000
          },
          "max_operation_time": {
            "type": "integer",
            "format": "int64",
            "description": "Operation time of longest route in seconds.",
            "example": 4000
          },
          "waiting_time": {
            "type": "integer",
            "format": "int64",
            "description": "Overall waiting time in seconds.",
            "example": 200
          },
          "service_duration": {
            "type": "integer",
            "format": "int64",
            "description": "Overall service time in seconds.",
            "example": 1200
          },
          "preparation_time": {
            "type": "integer",
            "format": "int64",
            "description": "Overall preparation time in seconds."
          },
          "setup_time": {
            "type": "integer",
            "format": "int64",
            "description": "Overall setup time in seconds."
          },
          "completion_time": {
            "type": "integer",
            "format": "int64",
            "description": "Overall completion time in seconds, i.e. the sum of each route's operation time.",
            "example": 12000
          },
          "no_vehicles": {
            "type": "integer",
            "format": "int32",
            "description": "Number of employed vehicles.",
            "example": 10
          },
          "no_unassigned": {
            "type": "integer",
            "format": "int32",
            "description": "Number of jobs that could not be assigned to final solution.",
            "example": 1
          },
          "routes": {
            "type": "array",
            "description": "An array of routes",
            "items": {
              "$ref": "#/components/schemas/Route"
            }
          },
          "unassigned": {
            "type": "object",
            "properties": {
              "services": {
                "type": "array",
                "description": "An array of ids of unassigned services",
                "items": {
                  "type": "string",
                  "description": "Id of unassigned service"
                },
                "example": [
                  "service-1",
                  "service-3"
                ]
              },
              "shipments": {
                "type": "array",
                "description": "An array of ids of unassigned shipments",
                "example": [
                  "shipment-5"
                ],
                "items": {
                  "type": "string",
                  "description": "Id of unassigned shipments"
                }
              },
              "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": {
                  "$ref": "#/components/schemas/Detail"
                }
              },
              "activities": {
                "type": "array",
                "description": "Per-activity breakdown of every unassigned job. For each unassigned **service** there is exactly one entry; for each unassigned **shipment** there are two entries (one with `type: \"pickupShipment\"` and one with `type: \"deliverShipment\"`), both sharing the shipment id.\n\nSchedule-derived fields (`arr_time`, `end_time`, `waiting_time`, `distance`, `driving_time`, `preparation_time`, `setup_time`, `load_before`, `load_after`) are zero or omitted because the job was never placed on a route. The descriptive fields `name`, `priority`, and `group` are echoed from the original request when present, so consumers can render or audit unassigned stops without joining back to the request. `time_window` is omitted because the solver never picked one.\n",
                "items": {
                  "$ref": "#/components/schemas/Activity"
                }
              }
            }
          }
        }
      },
      "Detail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Id of unassigned service/shipment"
          },
          "code": {
            "type": "integer",
            "format": "int32",
            "description": "Reason code (most likely reason). See `reasons` array for additional probable reasons.\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\n29 | could not be assigned due to group relation constraint\n30 | could not be assigned due to driving time break\n50 | underlying location cannot be accessed over road network by at least one vehicle\n51 | location is isolated and cannot reach any other location over road network\n"
          },
          "reason": {
            "type": "string",
            "description": "Human readable reason as listed above (most likely reason)"
          },
          "reasons": {
            "type": "array",
            "description": "Array of probable reasons why this job could not be assigned, sorted by likelihood (most likely first).\nThis provides more context than the single `code`/`reason` fields, which only show the most likely reason.\nFor example, a job might fail due to a relation constraint (code 21), but the underlying cause\ncould be a time window violation (code 2). In this case, both reasons would appear in this array.\n",
            "items": {
              "$ref": "#/components/schemas/ReasonEntry"
            }
          }
        }
      },
      "ReasonEntry": {
        "type": "object",
        "description": "A single reason entry with code and human-readable description",
        "properties": {
          "code": {
            "type": "integer",
            "format": "int32",
            "description": "Reason code (see Detail.code for the full list of codes)"
          },
          "reason": {
            "type": "string",
            "description": "Human readable reason"
          }
        }
      },
      "Route": {
        "type": "object",
        "properties": {
          "vehicle_id": {
            "type": "string",
            "description": "Id of vehicle that operates route",
            "example": "driver-stefan"
          },
          "distance": {
            "type": "integer",
            "format": "int64",
            "description": "Distance of route in meters.",
            "example": 10000
          },
          "transport_time": {
            "type": "integer",
            "format": "int64",
            "description": "Transport time of route in seconds",
            "example": 1800
          },
          "completion_time": {
            "type": "integer",
            "format": "int64",
            "description": "Completion time of route in seconds",
            "example": 1800
          },
          "waiting_time": {
            "type": "integer",
            "format": "int64",
            "description": "Waiting time of route in seconds"
          },
          "service_duration": {
            "type": "integer",
            "format": "int64",
            "description": "Service duration of route in seconds"
          },
          "preparation_time": {
            "type": "integer",
            "format": "int64",
            "description": "Preparation time of route in seconds"
          },
          "setup_time": {
            "type": "integer",
            "format": "int64",
            "description": "Setup time of route in seconds"
          },
          "activities": {
            "type": "array",
            "description": "Array of activities",
            "items": {
              "$ref": "#/components/schemas/Activity"
            }
          },
          "points": {
            "type": "array",
            "description": "One entry for every vehicle",
            "items": {
              "allOf": [
                {
                  "description": "The geometry of the route. The format depends on the value of `points_encoded`."
                },
                {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/EncodedLineString"
                    },
                    {
                      "$ref": "#/components/schemas/LineString"
                    }
                  ]
                }
              ]
            }
          }
        }
      },
      "Activity": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "type of activity",
            "enum": [
              "start",
              "end",
              "service",
              "pickupShipment",
              "deliverShipment",
              "pickup",
              "delivery",
              "break"
            ]
          },
          "id": {
            "type": "string",
            "description": "Id referring to the underlying service or shipment, i.e. the shipment or service this activity belongs to"
          },
          "name": {
            "type": "string",
            "description": "Human-readable name copied from the underlying service or shipment, if one was set on the request. Omitted for `start`/`end` activities and when the request did not specify a name."
          },
          "location_id": {
            "type": "string",
            "description": "Id that refers to address"
          },
          "address": {
            "$ref": "#/components/schemas/ResponseAddress"
          },
          "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."
          },
          "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."
          },
          "end_date_time": {
            "type": "string",
            "format": "date-time",
            "description": "Translation of unix timestamp in `end_time` to end date time string with zone offset. It will be in the following ISO-8601 format: 2007-12-03T10:15:30+01:00."
          },
          "arr_date_time": {
            "type": "string",
            "format": "date-time",
            "description": "Translation of unix timestamp in `arr_time` to arrival date time string with zone offset. It will be in the following ISO-8601 format: 2007-12-03T10:15:30+01:00."
          },
          "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."
          },
          "preparation_time": {
            "type": "integer",
            "format": "int64",
            "description": "preparation time at this activity in seconds"
          },
          "setup_time": {
            "type": "integer",
            "format": "int64",
            "description": "Setup time at this activity in seconds. Setup time is charged when the location differs from the previous activity, representing location overhead like dock check-in or security clearance."
          },
          "distance": {
            "type": "integer",
            "format": "int64",
            "description": "Cumulative distance from start to this activity in meters."
          },
          "driving_time": {
            "type": "integer",
            "format": "int64",
            "description": "Cumulative driving time from start to this activity in seconds."
          },
          "load_before": {
            "type": "array",
            "description": "Array with size/capacity dimensions before this activity",
            "items": {
              "type": "integer",
              "format": "int32",
              "description": "dimension value"
            }
          },
          "load_after": {
            "type": "array",
            "description": "Array with size/capacity dimensions after this activity",
            "items": {
              "type": "integer",
              "format": "int32",
              "description": "dimension value"
            }
          },
          "priority": {
            "type": "integer",
            "format": "int32",
            "minimum": 1,
            "maximum": 10,
            "description": "Priority copied from the underlying service or shipment (1 = highest, 10 = lowest, default 2). Omitted for `start`/`end` activities."
          },
          "group": {
            "type": "string",
            "description": "Group identifier copied from the underlying activity (pickup or delivery side for shipments). Omitted for `start`/`end` activities and when the request did not specify a group."
          },
          "time_window": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TimeWindow"
              },
              {
                "description": "The time window the solver actually scheduled this activity into. Only present when the request specified at least one explicit, non-default time window for the activity; the trivial `[0, MAX]` window is suppressed."
              }
            ]
          }
        }
      }
    }
  }
}