GraphHopper Directions API (1.0.0)

Download OpenAPI specification:Download

With the GraphHopper Directions API you can integrate A-to-B route planning, turn-by-turn navigation, route optimization, isochrone calculations and other tools in your application.

The GraphHopper Directions API consists of the following RESTful web services:

Explore our APIs

Get started

  1. Sign up for GraphHopper
  2. Create an API key

Each API part has its own documentation. Jump to the desired API part and learn about the API through the given examples and tutorials.

API Client Libraries

To speed up development and make coding easier, we offer a JavaScript client and a Java client.

You can also try some examples on a map

Bandwidth reduction

If you create your own client, make sure it supports http/2 and gzipped responses for best speed. If you use the Matrix, the Route Optimization API or the Cluster API and want to solve large problems, we recommend you to reduce bandwidth by compressing your POST request and specifying the header as follows: Content-Encoding: gzip. This will also avoid the HTTP 413 error "Request Entity Too Large".

Contact Us

If you have problems or questions, please read the following information:

To stay informed about the latest developments, you can

Select the channel you like the most.

Map Data and Routing Profiles

Currently, our main data source is OpenStreetMap. We also integrated other network data providers. This chapter gives an overview about the options you have.

OpenStreetMap

Geographical Coverage

OpenStreetMap covers the whole world. If you want to see for yourself if we can provide data suitable for your region, please visit GraphHopper Maps. You can edit and modify OpenStreetMap data if you find that important information is missing, e.g. a weight limit for a bridge. Here 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.

Supported Routing Profiles

The Routing, Matrix and Route Optimization APIs support the following profiles:

Name Description Restrictions Icon
car Car mode car access, weight=2500kg, width=2m, height=2m car image
car_delivery Car mode car access including delivery and private roads. Use only in case your drivers are allowed to access these roads. car image
car_avoid_ferry Car mode car that heavily penalizes ferries car image
car_avoid_motorway Car mode car that heavily penalizes motorways car image
car_avoid_toll Car mode car that heavily penalizes tolls car image
small_truck Small truck like a Mercedes Sprinter, Ford Transit or Iveco Daily height=2.7m, width=2+0.34m, length=5.5m, weight=2080+1400 kg small truck image
small_truck_delivery Small truck Like small_truck but including delivery and private roads. Use only in case your drivers are allowed to access these roads. small truck image
truck 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
scooter 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
scooter_delivery Moped mode Like scooter but including delivery and private roads. Use only in case your drivers are allowed to access these roads. scooter image
foot Pedestrian or walking without dangerous SAC-scales foot access foot image
hike Pedestrian or walking with priority for more beautiful hiking tours and potentially a bit longer than foot. Walking duration is influenced by elevation differences. foot access hike image
bike Trekking bike avoiding hills bike access Bike image
mtb Mountainbike bike access Mountainbike image
racingbike Bike preferring roads bike access Racingbike image

Please note:

  • the free package supports only the routing profiles car, bike or foot
  • 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.
  • we offer custom routing profiles with different properties, different speed profiles or different access options. To find out more about custom profiles, please contact us.
  • a sophisticated motorcycle profile is available up on request. It is powered by the Kurviger Routing API and favors curves and slopes while avoiding cities and highways.

TomTom

If you want to include traffic, you can purchase the TomTom Add-on. This Add-on only uses TomTom's road network and historical traffic information. Live traffic is not yet considered. If you are interested to learn how we consider traffic information, we recommend that you read this article.

Please note the following:

Contact us if you want to buy this TomTom add-on.

Geographical Coverage

We offer

  • Europe including Russia
  • North, Central and South America
  • Saudi Arabia and United Arab Emirates
  • South Africa
  • Southeast Asia
  • Australia

Supported Vehicle Profiles

Name Description Restrictions Icon
car Car mode car access car image
small_truck Small truck like a Mercedes Sprinter, Ford Transit or Iveco Daily height=2.7m, width=2+0.4m, length=5.5m, weight=2080+1400 kg small truck image

Custom Model

A custom model allows you to modify the default routing behavior of a vehicle profile by specifying a set of rules in JSON language. There 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.

But first we will give an introductory example for each of these JSON properties. Let's start with speed:

{
  "speed": [{
    "if": "road_class == MOTORWAY",
    "limit_to": "90"
  }]
}

As you might have already guessed this limits the speed on motorways to 90km/h. Changing 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.

You can immediately try this out in the Browser on GraphHopper Maps. GraphHopper Maps offers an interactive text editor to comfortably enter custom models. You can open it by pressing the "custom" button. It will check the syntax of your custom model and mark errors in red. You can press Ctrl+Space or Alt+Enter to retrieve auto-complete suggestions. Pressing Ctrl+Enter will send a routing request for the custom model you entered. To disable the custom model you click the "custom" button again.

In the second example we show how to avoid certain road classes without changing the travel time:

{
  "priority": [{
    "if": "road_class == LIVING_STREET || road_class == RESIDENTIAL || road_class == UNCLASSIFIED",
    "multiply_by": "0.1"
  }]
}

This example avoids certain smaller streets. View it in GraphHopper Maps.

The third example shows how to prefer shortest paths:

{
  "distance_influence": 200
}

View this example in GraphHopper Maps.

There 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. Please read more about this and the other properties below and try some examples in GraphHopper Maps with the help of this blog post.

Customizing speed

When using custom models you do not need to define rules that specify a speed for every road segment, but rather GraphHopper assumes a default speed. All you need to do is adjust this default speed to your use-case as you will always use the custom model in conjunction with a routing profile which is used to determine the default speed.

The custom model is a JSON object and the first property we will learn about here is the speed property. The speed property's value is a list of conditional statements that modify the default speed. Every such statement consists of a condition and an operation. The different statements are applied to the default speed from top to bottom, i.e. statements that come later in the list are applied to the resulting value of previous operations. Each statement is only executed if the corresponding condition applies for the current road segment. This will become more clear in the following examples.

Currently the custom model language supports two operators:

  • multiply_by multiplies the speed value with a given number
  • limit_to limits the speed value to a given number

if statements and the multiply_by operation

Let's start with a simple example using multiply_by:

{
  "speed": [
    {
      "if": "road_class == MOTORWAY",
      "multiply_by": "0.5"
    }
  ]
}

This custom model reduces the speed of every road segment for which the road_class attribute is MOTORWAY to fifty percent of the default speed (the default speed is multiplied by 0.5). Again, the default speed is the speed that GraphHopper would normally use for the profile's vehicle. Note the if clause which means that the operation (multiply_by) is only applied if the condition road_class == MOTORWAY is fulfilled for the road segment under consideration. The == indicates equality, i.e. the condition reads "the road_class equals MOTORWAY". If you're a bit familiar with programming note that the condition (the value of the if key) is just a boolean condition in Java language (other programming languages like C or JavaScript are very similar in this regard). A more complex condition could look like this: road_class == PRIMARY || road_class == TERTIARY which uses the or (||) operator and literally means "road_class equals PRIMARY or road_class equals TERTIARY".

There can be multiple such 'if statements' in the speed section, and they are evaluated from top to bottom:

{
  "speed": [
    {
      "if": "road_class == MOTORWAY",
      "multiply_by": "0.5"
    },
    {
      "if": "road_class == PRIMARY || road_environment == TUNNEL",
      "multiply_by": "0.7"
    }
  ]
}

In this example the default speed of road segments with road_class == MOTORWAY will be multiplied by 0.5, the default speed of road segments with road_class == PRIMARY will be multiplied by 0.7 and for road segments with both road_class == MOTORWAY and road_environment == TUNNEL the default speed will be multiplied first by 0.5 and then by 0.7. So overall the default speed will be multiplied by 0.35. For road segments with road_class == PRIMARY and road_environment == TUNNEL we only multiply by 0.7, even though both parts of the second condition apply. It only matters whether the road segment matches the condition or not.

road_class and road_environment are road attributes of 'enum' type, i.e. their value can only be one of a fixed set of values, like MOTORWAY for road_class.

Other road attributes like get_off_bike are of boolean type. They can be used as conditions directly, for example:

{
  "speed": [
    {
      "if": "get_off_bike",
      "multiply_by": "0.6"
    }
  ]
}

which means that for road segments with get_off_bike==true the speed factor will be 0.6.

For attributes with numeric values, like max_width you should not use the == (equality) or != ( inequality) operators, but the numerical comparison operators "bigger" >, "bigger or equals" >=, "smaller" <, or "smaller or equals" <=, e.g.:

{
  "speed": [
    {
      "if": "max_width < 2.5",
      "multiply_by": "0.8"
    }
  ]
}

which means that for all road segments with max_width smaller than 2.5m the speed is multiplied by 0.8.

The limit_to operation

Besides the multiply_by operator there is also the limit_to operator. As the name suggests limit_to limits the current value to the given value. Take this example:

{
  "speed": [
    {
      "if": "road_class == MOTORWAY",
      "multiply_by": "0.8"
    },
    {
      "if": "surface == GRAVEL",
      "limit_to": "60"
    }
  ]
}

This implies that on all road segments with the GRAVEL value for surface the speed will be at most 60km/h, regardless of the default speed and the previous rules. So for a road segment with road_class == MOTORWAY, surface == GRAVEL and default speed 100 the first statement reduces the speed from 100 to 80 and the second statement further reduces the speed from 80 to 60. If the road_class was PRIMARY and the default speed was 50 the first rule would not apply and the second rule would do nothing, because limiting 50 to 60 still yields 50.

A common use-case for the limit_to operation is the following pattern:

{
  "speed": [
    {
      "if": "true",
      "limit_to": "90"
    }
  ]
}

which means that the speed is limited to 90km/h for all road segments regardless of its properties. The condition "true" is always fulfilled.

else and else_if statements

The else statement allows you to define that some operations should be applied if an road segment does not match a condition. So this example:

{
  "speed": [
    {
      "if": "road_class == MOTORWAY",
      "multiply_by": "0.5"
    },
    {
      "else": "",
      "limit_to": "50"
    }
  ]
}

means that for all road segments with road_class == MOTORWAY we multiply the default speed by 0.5 and for all others we limit the default speed to 50 (but never both).

In case you want to distinguish more than two cases (road segments that match or match not a condition) you can use else_if statements which are only evaluated in case the previous if or else_if statement did not match:

{
  "speed": [
    {
      "if": "road_class == MOTORWAY",
      "multiply_by": "0.5"
    },
    {
      "else_if": "road_environment == TUNNEL",
      "limit_to": "70"
    },
    {
      "else": "",
      "multiply_by": "0.9"
    }
  ]
}

So if the first condition matches (road_class == MOTORWAY) the default speed is multiplied by 0.5, but the other two statements are ignored. Only if the first statement does not match (e.g. road_class == PRIMARY) the second statement is even considered and only if it matches (road_environment == TUNNEL) the default speed is limited to 70. The last operation (multiply_by: "0.9") is only applied if both previous conditions did not match.

else and else_if statements always require a preceding if or else_if statement. However, there can be multiple 'blocks' of subsequent if/else_if/else statements in the list of rules for speed.

else_if is useful for example in case you have multiple multiply_by operations, but you do not want that the speed gets reduced by all of them. For the following model

{
  "speed": [
    {
      "if": "road_class == MOTORWAY",
      "multiply_by": "0.5"
    },
    {
      "else_if": "road_environment == TUNNEL",
      "multiply_by": "0.8"
    }
  ]
}

only the first factor (0.5) will be applied even for road segments that fulfill both conditions.

Limit rules to certain areas

You can not only modify the speed of road segments based on properties, like we saw in the previous examples, but you can also modify the speed of road segments based on their location. To do this you need to first create and add some areas to the areas section of the custom model. You can then use the name of these areas in the conditions of your if/else/else_if statements.

In the following example we multiply the speed of all road segments in an area called custom1 with 0.7 and also limit it to 50km/h. Note that each area's name needs to be prefixed with in_:

{
  "speed": [
    {
      "if": "in_custom1",
      "multiply_by": "0.7"
    },
    {
      "if": "in_custom1",
      "limit_to": "50"
    }
  ],
  "areas": {
    "custom1": {
      "type": "Feature",
      "id": "something",
      "properties": {},
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              1.525,
              42.511
            ],
            [
              1.510,
              42.503
            ],
            [
              1.531,
              42.495
            ],
            [
              1.542,
              42.505
            ],
            [
              1.525,
              42.511
            ]
          ]
        ]
      }
    }
  }
}

Areas are given in GeoJson format, but currently only the exact format in the above example is supported, i.e. one object with type Feature, a geometry with type Polygon and optional (but ignored) id and properties fields. Note that the coordinates array of Polygon is an array of arrays that each must describe a closed ring, i.e. the first point must be equal to the last. Each point is given as an array [longitude, latitude], so the coordinates array has three dimensions total.

Using the areas feature you can also block entire areas i.e. by multiplying the speed with 0, but for this you should rather use the priority section that we will explain next.

Customizing priority

Make sure you read the introductory section of this document to learn what the priority factor means. In short it allows similar modifications as speed, but instead of modifying the road segment weights and travel times it will only affect the weights. By default, the priority is 1 for every road segment, so it does not affect the weight. However, changing the priority of a road can yield a relative weight difference in comparison to other roads.

Customizing the priority works very much like changing the speed, so in case you did not read the section about speed you should go back there and read it now. The only real difference is that there is no limit_to operator for priority. As a quick reminder here is an example for priority:

{
  "priority": [
    {
      "if": "road_class == MOTORWAY",
      "multiply_by": "0.5"
    },
    {
      "else_if": "road_class == SECONDARY",
      "multiply_by": "0.9"
    },
    {
      "if": "road_environment == TUNNEL",
      "multiply_by": "0.1"
    }
  ]
}

means that road segments with road_class==MOTORWAY and road_environment==TUNNEL get priority 0.5*0.1=0.05 and those with road_class==SECONDARY and no TUNNEL, get priority 0.9 and so on.

Edges with lower priority values will be less likely part of the optimal route calculated by GraphHopper, higher values mean that these road segments shall be preferred. If you do not want to state which road segments shall be avoided, but rather which ones shall be preferred, you need to decrease the priority of others:

{
  "priority": [
    {
      "if": "road_class != CYCLEWAY",
      "multiply_by": "0.8"
    }
  ]
}

means decreasing the priority for all road_classes except cycleways.

Just like we saw for speed you can also adjust the priority for road segments in a certain area. It works exactly the same way:

{
  "priority": [
    {
      "if": "in_custom1",
      "multiply_by": "0.7"
    }
  ]
}

To block an entire area set the priority value to 0. You can even set the priority only for certain roads in an area like this:

{
  "priority": [
    {
      "if": "road_class == MOTORWAY && in_custom1",
      "multiply_by": "0.1"
    }
  ]
}

Some other useful attributes to restrict access to certain roads depending on your vehicle dimensions are the following:

{
  "priority": [
    {
      "if": "max_width < 2.5",
      "multiply_by": "0"
    },
    {
      "if": "max_length < 10",
      "multiply_by": "0"
    },
    {
      "if": "max_weight < 3.5",
      "multiply_by": "0"
    }
  ]
}

which means that the priority for all road segments that allow a maximum vehicle width of 2.5m, a maximum vehicle length of 10m or a maximum vehicle weight of 3.5tons, or less, is zero, i.e. these "narrow" road segments are blocked.

Customizing distance_influence

The distance_influence property allows you to control the trade-off between a fast route (minimum time) and a short route (minimum distance). The larger distance_influence is the more GraphHopper will prioritize routes with a small total distance. More precisely, the distance_influence is the time you need to save on a detour (a longer distance route option) such that you prefer taking the detour compared to a shorter route. Please note that this value is a number, not a string.

A value of 100 means that one extra kilometer of detour must save you 100s of travelling time or else you are not willing to take the detour. Or to put it another way, if a reference route takes 600s and is 10km long, distance_influence=100 means that you are willing to take an alternative route that is 11km long only if it takes no longer than 500s (saves 100s). Things get a bit more complicated when priority is not 1, but the effect stays the same: The larger distance_influence is, the more GraphHopper will focus on finding short routes.

Road attributes

GraphHopper stores different attributes for every road segment. Some frequently used are the following (some of their possible values are given in brackets):

  • road_class: (OTHER, MOTORWAY, TRUNK, PRIMARY, SECONDARY, TRACK, STEPS, CYCLEWAY, FOOTWAY, ...)
  • road_environment: (ROAD, FERRY, BRIDGE, TUNNEL, ...)
  • road_access: (DESTINATION, DELIVERY, PRIVATE, NO, ...)
  • surface: (PAVED, DIRT, SAND, GRAVEL, ...)
  • smoothness: (EXCELLENT, GOOD, INTERMEDIATE, ...)
  • toll: (MISSING, NO, HGV, ALL)
  • bike_network, foot_network: (MISSING, INTERNATIONAL, NATIONAL, REGIONAL, LOCAL, OTHER)
  • country: (MISSING or the country as a ISO3166-1:alpha3 code e.g. DEU)
  • hazmat: (YES, NO), hazmat_tunnel: (A, B, .., E), hazmat_water: (YES, PERMISSIVE, NO)
  • hgv: (MISSING, YES, DESIGNATED, ...)
  • track_type: (MISSING, GRADE1, GRADE2, ..., GRADE5)
  • urban_density: (RURAL, RESIDENTIAL, CITY)

To learn about all available encoded values you can query the /info endpoint

Besides this kind of categories, which can take multiple different string values, there are also some that represent a boolean value (they are either true or false for a given road segment), like:

  • get_off_bike
  • road_class_link
  • roundabout

There are also some that take on a numeric value, like:

  • 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
  • curvature: "beeline distance" / edge_distance (0..1) e.g. a curvy road is smaller than 1
  • 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
  • lanes: number of lanes
  • 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.
  • max_speed: the speed limit from a sign (km/h)
  • max_height (meter), max_width (meter), max_length (meter)
  • max_weight (ton), max_axle_load (in tons)

Limitations

Custom models are currently:

  1. only available for the POST Route Endpoint. If you are interested in using this for the Matrix or Route Optimization API please contact us to get access to an early alpha version. For the Isochrone API it is also planned.
  2. only available for the following parent profiles: foot, bike, scooter, car and small_truck.
  3. only available for OpenStreetMap.

This feature will strongly benefit from feedback, so do not hesitate to share your experience, your favorite custom model or some of the problems you ran into when you tried building your own with custom model.

Troubleshooting

Recommendations

For debugging you can use the custom model editor in GraphHopper Maps (click the 'custom' button).

When debugging problems with custom models you should first try if your request goes through without an error using an empty custom model.

For production you should avoid to include road_access and toll in the profile as we will change their values in the next weeks which could cause unexpected problems.

Route calculation is slower

The 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. Still for certain use cases you can make the calculation if you tune the custom_model and e.g. exclude certain ways via { "if": "road_class == TRACK || road_class == RESIDENTIAL", "multiply_by": "0" }.

All routes for my custom model fail

This could mean that either your custom model made some of the roads near the start and destination inaccessible, then usually we return a PointNotFoundException with the point_index with the "location snap" problem.

Or, the custom model made all roads between your start and destination inaccessible, then we return a ConnectionNotFoundException. This happens e.g. when you exclude tunnels, ferries or motorways but all routes between start and destination have these road attributes satisfied, i.e. we cannot find a route.

Solution: relax your custom model and e.g. instead of excluding certain road attributes via "multiply_by": "0" you should try to use "0.01".

Route Optimization API

Quickstart

The Route Optimization API can be used to solve traveling salesman or vehicle routing problems. Solve your first problem by following these steps. If you already have a GraphHopper account, start with step 2.

  1. Sign up for GraphHopper

  2. Create an API key

  3. Download simple traveling salesman problem and save it in a local folder

  4. Open your command line, go to that local folder and use cURL (What is cURL?) as follows:

    curl -X POST -H "Content-Type: application/json"   "https://graphhopper.com/api/1/vrp?key=YOUR_CREATED_API_KEY" --data "@tsp.json"
    

Alternatively, you can use our Editor to explore that API:

  1. Login to your GraphHopper account
  2. Go to Editor
  3. Click the Optimize button to solve your first problem
  4. Analyze the solution on the Map or as raw JSON Output

If you have successfully solved the first problem, we recommend this tutorial - Getting Started with the Optimization API. It shows and describes the essential elements to model your vehicle routing problem.

To explore the full specification, we recommend that you either use our route editor, which you can find in our dashboard, or use a REST client such as Insomnia or Postman, as described here.

POST route optimization problem

To get started with the Route Optimization API, please read the introduction.

To solve a new vehicle routing problem, make a HTTP POST to this URL

https://graphhopper.com/api/1/vrp?key=<your_key>

It returns the solution to this problem in the JSON response.

Please note that this URL is very well suited to solve minor problems. Larger vehicle routing problems, which take longer than 10 seconds to solve, cannot be solved. To solve them, please use the batch mode URL instead.

Securityapi_key
Request
Request Body schema: application/json

The request that contains the vehicle routing problem to be solved.

Array of objects (Vehicle) non-empty

Specifies the available vehicles.

Array of objects (VehicleType)

Specifies the available vehicle types. These types can be assigned to vehicles.

Array of objects (Service)

Specifies the orders of the type "service". These are, for example, pick-ups, deliveries or other stops that are to be approached by the specified vehicles. Each of these orders contains only one location.

Array of objects (Shipment)

Specifies the available shipments. Each shipment contains a pickup and a delivery stop, which must be processed one after the other.

Array of JobRelation (object) or GroupRelation (object)

Defines additional relationships between orders.

object (Algorithm)
Deprecated

Use objectives instead.

Array of objects (Objective)

Specifies an objective function. The vehicle routing problem is solved in such a way that this objective function is minimized.

Array of objects (CostMatrix)

Specifies your own tranport time and distance matrices.

object (Configuration)

Specifies general configurations that are taken into account when solving the vehicle routing problem.

Responses
200

A response containing the solution

400

Error occurred when reading the request. Request is invalid.

500

Error occurred on server side.

post/vrp
Request samples
application/json
{
  • "vehicles": [
    ],
  • "vehicle_types": [
    ],
  • "services": [
    ],
  • "shipments": [
    ],
  • "objectives": [
    ],
  • "configuration": {
    }
}
Response samples
application/json
{
  • "copyrights": [
    ],
  • "job_id": "d62fcadd-c84a-4298-90b5-28550125bec5",
  • "status": "finished",
  • "waiting_time_in_queue": 0,
  • "processing_time": 459,
  • "solution": {
    }
}

POST route optimization problem (batch mode)

To solve a vehicle routing problem, perform the following steps:

1.) Make a HTTP POST to this URL

https://graphhopper.com/api/1/vrp/optimize?key=<your_key>

It returns a job id (job_id).

2.) Take the job id and fetch the solution for the vehicle routing problem from this URL:

https://graphhopper.com/api/1/vrp/solution/<job_id>?key=<your_key>

We recommend to query the solution every 500ms until it returns 'status=finished'.

Note: Since the workflow is a bit more cumbersome and since you lose some time in fetching the solution, you should always prefer the synchronous endpoint. You should use the batch mode only for long running problems.

Securityapi_key
Request
Request Body schema: application/json

The request that contains the problem to be solved.

Array of objects (Vehicle) non-empty

Specifies the available vehicles.

Array of objects (VehicleType)

Specifies the available vehicle types. These types can be assigned to vehicles.

Array of objects (Service)

Specifies the orders of the type "service". These are, for example, pick-ups, deliveries or other stops that are to be approached by the specified vehicles. Each of these orders contains only one location.

Array of objects (Shipment)

Specifies the available shipments. Each shipment contains a pickup and a delivery stop, which must be processed one after the other.

Array of JobRelation (object) or GroupRelation (object)

Defines additional relationships between orders.

object (Algorithm)
Deprecated

Use objectives instead.

Array of objects (Objective)

Specifies an objective function. The vehicle routing problem is solved in such a way that this objective function is minimized.

Array of objects (CostMatrix)

Specifies your own tranport time and distance matrices.

object (Configuration)

Specifies general configurations that are taken into account when solving the vehicle routing problem.

Responses
200

A jobId you can use to retrieve your solution from the server - see solution endpoint.

400

Error occurred when reading client request. Request is invalid.

500

Error occurred on server side.

post/vrp/optimize
Request samples
application/json
{
  • "vehicles": [
    ],
  • "vehicle_types": [
    ],
  • "services": [
    ],
  • "shipments": [
    ],
  • "objectives": [
    ],
  • "configuration": {
    }
}
Response samples
application/json
{
  • "job_id": "44886560-b584-4da5-b245-768151dacd8f"
}

GET the solution (batch mode)

Take the job id and fetch the solution for the vehicle routing problem from this URL:

https://graphhopper.com/api/1/vrp/solution/<job_id>?key=<your_key>

You get the job id by sending a vehicle routing problem to the batch mode URL.

Securityapi_key
Request
path Parameters
jobId
required
string

Request solution with jobId

Responses
200

A response containing the solution

400

Error occurred on client side such as invalid input.

404

Requested solution could not be found.

500

Error occurred on server side.

get/vrp/solution/{jobId}
Request samples
curl -X GET "https://graphhopper.com/api/1/vrp/solution/job_id?key=api_key"
Response samples
application/json
{
  • "copyrights": [
    ],
  • "job_id": "d62fcadd-c84a-4298-90b5-28550125bec5",
  • "status": "finished",
  • "waiting_time_in_queue": 0,
  • "processing_time": 459,
  • "solution": {
    }
}

Routing API

Introduction

Routing screenshot

The Routing API is part of the GraphHopper Directions API. Routing is the process of finding the best path connecting two or more points, where the meaning of ''best'' depends on the vehicle profile and use case.

Tutorials

GET Route Endpoint

For the GET request you specify the parameters in the URL and can try it directly in every browser. However, it has some disadvantages when using many points (URL length limit) and the custom_model Feature cannot be used. Therefore, our recommended endpoint is the POST route endpoint.

Securityapi_key
Request
query Parameters
profile
string (VehicleProfileId)
Default: "car"

Specifies the vehicle profile of this type. The profile is used to determine the network, speed and other physical attributes to use for routing the vehicle or pedestrian. See the section about routing profiles for more details and valid profile values.

point
required
Array of strings

The points for which the route should be calculated. Format: latitude,longitude. Specify at least an origin and a destination. Via points are possible. The maximum number depends on your plan.

point_hint
Array of strings

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.

snap_prevention
Array of strings

Optional parameter to avoid snapping to a certain road class or road environment. Currently supported values are motorway, trunk, ferry, tunnel, bridge and ford. Multiple values are specified like snap_prevention=ferry&snap_prevention=motorway. Please note that in order to e.g. avoid motorways for the route (not for the "location snap") you need a different feature: a custom model.

curbside
Array of strings

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.

Items Enum: "any" "right" "left"
locale
string
Default: "en"

The locale of the resulting turn instructions. E.g. pt_PT for Portuguese or de for German.

elevation
boolean
Default: false

If true, a third coordinate, the altitude, is included with all positions in the response. This changes the format of the points and snapped_waypoints fields of the response, in both their encodings. Unless you switch off the points_encoded parameter, you need special code on the client side that can handle three-dimensional coordinates.

details
Array of strings

Optional parameter. The following path details are available: street_name, street_ref, street_destination, roundabout, country, time, distance, max_speed, max_weight, max_width, toll, road_class, road_class_link, road_access, road_environment, hazmat, hazmat_tunnel, hazmat_water, lanes, surface, smoothness, hike_rating, mtb_rating, foot_network, bike_network, get_off_bike. Read more about the usage of path details here.

optimize
string
Default: "false"

Normally, the calculated route will visit the points in the order you specified them. If 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. Keep in mind that the limits on the number of locations of the Route Optimization API applies, and the request costs more credits.

instructions
boolean
Default: true

If instructions should be calculated and returned

calc_points
boolean
Default: true

If the points for the route should be calculated at all.

debug
boolean
Default: false

If true, the output will be formatted.

points_encoded
boolean
Default: true

Allows changing the encoding of location data in the response. The default is polyline encoding, which is compact but requires special client code to unpack. (We provide it in our JavaScript client library!) Set this parameter to false to switch the encoding to simple coordinate pairs like [lon,lat], or [lon,lat,elevation]. See the description of the response format for more information.

ch.disable
boolean
Default: false

Use this parameter in combination with one or more parameters from below.

heading
Array of integers <int32>

Favour a heading direction for a certain point. Specify either one heading for the start point or as many as there are points. In 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. This parameter also influences the tour generated with algorithm=round_trip and forces the initial direction. Requires ch.disable=true.

heading_penalty
integer <int32>
Default: 120

Time penalty in seconds for not obeying a specified heading. Requires ch.disable=true.

pass_through
boolean
Default: false

If true, u-turns are avoided at via-points with regard to the heading_penalty. Requires ch.disable=true.

algorithm
string

Rather than looking for the shortest or fastest path, this parameter lets you solve two different problems related to routing: With alternative_route, we give you not one but several routes that are close to optimal, but not too similar to each other. With round_trip, the route will get you back to where you started. This is meant for fun (think of a bike trip), so we will add some randomness. The round_trip option requires ch.disable=true. You can control both of these features with additional parameters, see below.

Enum: "round_trip" "alternative_route"
round_trip.distance
integer <int32>
Default: 10000

If algorithm=round_trip, this parameter configures approximative length of the resulting round trip. Requires ch.disable=true.

round_trip.seed
integer <int64>

If algorithm=round_trip, this sets the random seed. Change this to get a different tour for each value.

alternative_route.max_paths
integer <int32>
Default: 2

If algorithm=alternative_route, this parameter sets the number of maximum paths which should be calculated. Increasing can lead to worse alternatives.

alternative_route.max_weight_factor
number
Default: 1.4

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.

alternative_route.max_share_factor
number
Default: 0.6

If algorithm=alternative_route, this parameter specifies how similar an alternative route can be to the optimal route. Increasing can lead to worse alternatives.

Responses
200

Routing Result

400

Your request is not valid. For example, you specified too few or too many points.

401

Authentication necessary

429

API limit reached.

500

Internal server error. We get notified automatically and fix this asap.

get/route
Request samples
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"
Response samples
application/json
{
  • "hints": {
    },
  • "info": {
    },
  • "paths": [
    ]
}

POST Route Endpoint

To do a request you send JSON data.

See the GET endpoint for an alternative query method which is slightly simpler to get started but has some disadvantages.

Please note that in contrast to the GET endpoint, points are specified in the order of [longitude, latitude] and some parameter names use the plural. For example the string point=10,11&point=20,22 will be converted to the points array (plural):

{ "points": [[11,10], [22,20]] }

So this points array uses a format similar to GeoJson.

Example:

curl -X POST -H "Content-Type: application/json" "https://graphhopper.com/api/1/route?key=[YOUR_KEY]" -d '{"elevation":false,"points":[[-0.087891,51.534377],[-0.090637,51.467697]],"profile":"car"}'
Securityapi_key
Request
Request Body schema: application/json
profile
string (VehicleProfileId)
Default: "car"

Specifies the vehicle profile of this type. The profile is used to determine the network, speed and other physical attributes to use for routing the vehicle or pedestrian. See the section about routing profiles for more details and valid profile values.

points
Array of numbers

The points for the route in an array of [longitude,latitude]. For instance, if you want to calculate a route from point A to B to C then you specify `points: [ [A_longitude, A_latitude], [B_longitude, B_latitude], [C_longitude, C_latitude]]

point_hints
Array of strings

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.

snap_preventions
Array of strings

Optional parameter to avoid snapping to a certain road class or road environment. Current supported values motorway, trunk, ferry, tunnel, bridge and ford. Please note that this feature does not e.g. avoid motorways for the route - it only avoids it for the "location snap".

curbsides
Array of strings

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.

Items Enum: "any" "right" "left"
locale
string
Default: "en"

The locale of the resulting turn instructions. E.g. pt_PT for Portuguese or de for German.

elevation
boolean
Default: false

If true, a third coordinate, the altitude, is included with all positions in the response. This changes the format of the points and snapped_waypoints fields of the response, in both their encodings. Unless you switch off the points_encoded parameter, you need special code on the client side that can handle three-dimensional coordinates.

details
Array of strings

Optional parameter. The following path details are available: street_name, street_ref, street_destination, roundabout, country, time, distance, max_speed, max_weight, max_width, toll, road_class, road_class_link, road_access, road_environment, hazmat, hazmat_tunnel, hazmat_water, lanes, surface, smoothness, hike_rating, mtb_rating, foot_network, bike_network, get_off_bike. Read more about the usage of path details here.

optimize
string
Default: "false"

Normally, the calculated route will visit the points in the order you specified them. If 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. Keep in mind that the limits on the number of locations of the Route Optimization API applies, and the request costs more credits.

instructions
boolean
Default: true

If instructions should be calculated and returned

calc_points
boolean
Default: true

If the points for the route should be calculated at all.

debug
boolean
Default: false

If true, the output will be formatted.

points_encoded
boolean
Default: true

Allows changing the encoding of location data in the response. The default is polyline encoding, which is compact but requires special client code to unpack. (We provide it in our JavaScript client library!) Set this parameter to false to switch the encoding to simple coordinate pairs like [lon,lat], or [lon,lat,elevation]. See the description of the response format for more information.

ch.disable
boolean
Default: false

Use this parameter in combination with one or more parameters from below.

object (CustomModel)

The custom_model modifies the routing behaviour of the specified profile. See the detailed documentation. Below is a complete request example in Berlin including the required "ch.disabled": true parameter.

{
  "points": [
    [
      13.31543,
      52.509535
    ],
    [
      13.29779,
      52.512434
    ]
  ],
  "profile": "car",
  "ch.disable": true,
  "custom_model": {
    "speed": [
      {
        "if": "true",
        "limit_to": "100"
      }
    ],
    "priority": [
      {
        "if": "road_class == MOTORWAY",
        "multiply_by": "0"
      }
    ],
    "distance_influence": 100
  }
} 
headings
Array of integers <int32>

Favour a heading direction for a certain point. Specify either one heading for the start point or as many as there are points. In 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. This parameter also influences the tour generated with algorithm=round_trip and forces the initial direction. Requires ch.disable=true.

heading_penalty
integer <int32>
Default: 120

Time penalty in seconds for not obeying a specified heading. Requires ch.disable=true.

pass_through
boolean
Default: false

If true, u-turns are avoided at via-points with regard to the heading_penalty. Requires ch.disable=true.

algorithm
string

Rather than looking for the shortest or fastest path, this parameter lets you solve two different problems related to routing: With alternative_route, we give you not one but several routes that are close to optimal, but not too similar to each other. With round_trip, the route will get you back to where you started. This is meant for fun (think of a bike trip), so we will add some randomness. The round_trip option requires ch.disable=true. You can control both of these features with additional parameters, see below.

Enum: "round_trip" "alternative_route"
round_trip.distance
integer <int32>
Default: 10000

If algorithm=round_trip, this parameter configures approximative length of the resulting round trip. Requires ch.disable=true.

round_trip.seed
integer <int64>

If algorithm=round_trip, this sets the random seed. Change this to get a different tour for each value.

alternative_route.max_paths
integer <int32>
Default: 2

If algorithm=alternative_route, this parameter sets the number of maximum paths which should be calculated. Increasing can lead to worse alternatives.

alternative_route.max_weight_factor
number
Default: 1.4

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.

alternative_route.max_share_factor
number
Default: 0.6

If algorithm=alternative_route, this parameter specifies how similar an alternative route can be to the optimal route. Increasing can lead to worse alternatives.

Responses
200

Routing Result

400

Your request is not valid. For example, you specified too few or too many points.

401

Authentication necessary

429

API limit reached.

500

Internal server error. We get notified automatically and fix this asap.

post/route
Request samples
application/json
{
  • "points": [
    ],
  • "point_hints": [
    ],
  • "snap_preventions": [
    ],
  • "details": [
    ],
  • "vehicle": "bike",
  • "locale": "en",
  • "instructions": true,
  • "calc_points": true,
  • "points_encoded": false
}
Response samples
application/json
{
  • "hints": {
    },
  • "info": {
    },
  • "paths": [
    ]
}

Coverage information

Use this to find out details about the supported vehicle profiles and features, or if you just need to ping the server.

Securityapi_key
Responses
200

Coverage Information

get/route/info
Request samples
Response samples
application/json
{
  • "build_date": "2014-02-21T16:52",
  • "bbox": [
    ],
  • "version": "0.4",
  • "features": {
    }
}

Matrix API

Introduction

Matrix Example

The Matrix API is part of the GraphHopper Directions API and with it you can calculate many-to-many distances and times a lot more efficient than calling the Routing API multiple times.

In the Routing API we support multiple points, so called 'via points', which results in one route being calculated. The Matrix API results in NxM routes, or more precise NxM distances or times being calculated but is a lot faster compared to NxM single requests.

The most simple example is a tourist trying to decide which pizza is close to her instead of using beeline distance she can calculate a 1x4 matrix. Or a delivery service often in the need of big NxN matrices to solve vehicle routing problems. For example the GraphHopper Route Optimization API uses the Matrix API under the hood to achieve this.

Some other use cases for the Matrix API:

  • Logistic problems often pick up many items from and deliver them to many locations.
  • Calculating detours with many possible points in-between and selecting the best e.g. interesting for ridesharing or taxi applications. For this 1-to-many requests are necessary.
  • Finding the best tour for a tourist in the need to visit as many points of interests as possible.
  • ...

API Clients and Examples

See the clients section in the main document and live examples.

Description

The Matrix API calculates the well known distance-matrix for a set of points, i.e. it calculates all the distances between every point combination. But we do not stop there, we also offer a time-, weight- and route-matrix. The weight-matrix can be used as raw input for e.g. a vehicle routing problem (VRP) and is more precise than a time- or distance-matrix. E.g. for bike routes the actual weight of a route (e.g. the "beauty") is what you want to decide if a route is 'better' and not always the taken time or distance.

A simple illustration for a 3x3 matrix with identical from and to points:

  •      |to_point1|to_point2|to_point3
    
    :-----------|:--------|:--------|:-------- from_point1 |0 |1->2 | 1->3 from_point2 |2->1 |0 | 2->3 from_point3 |3->1 |3->2 | 0

A simple illustration for a 1x3 matrix with different start- and end-points:

  •      | to_point1  | to_point2 | t_point3
    
    :-----------|:-----------|:----------|:-------- from_pointA |A->1 |A->2 |A->3

For every route 1->2, 1-3, ... or A->1,A->2,A->3 you can return only the weight, the time and the distance. To calculate full routes you can use the Routing API.

Limits and Counts

The cost for one request depends on the number of locations and is documented here.

One request should not exceed the Matrix API location limit, which depends on the subscription, see the pricing tab in our dashboard.

GET Matrix Endpoint

With this Matrix Endpoint you submit the points and parameters via URL parameters and is the most convenient as it works out-of-the-box in the browser. If possible you should prefer using the POST Matrix Endpoint that avoids problems with many locations and can also gzip the request. (Note, that all endpoints return gzipped responses).

Securityapi_key
Request
query Parameters
profile
string (VehicleProfileId)
Default: "car"

Specifies the vehicle profile of this type. The profile is used to determine the network, speed and other physical attributes to use for routing the vehicle or pedestrian. See the section about routing profiles for more details and valid profile values.

point
Array of strings

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.

from_point
Array of strings

The starting points for the routes in latitude,longitude. E.g. if you want to calculate the three routes A->1, A->2, A->3 then you have one from_point parameter and three to_point parameters.

to_point
Array of strings

The destination points for the routes in latitude,longitude.

point_hint
Array of strings

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.

from_point_hint
Array of strings

For the from_point parameter. See point_hint

to_point_hint
Array of strings

For the to_point parameter. See point_hint

snap_prevention
Array of strings

Optional parameter to avoid snapping to a certain road class or road environment. Current supported values motorway, trunk, ferry, tunnel, bridge and ford. Multiple values are specified like snap_prevention=ferry&snap_prevention=motorway. Please note that this feature does not e.g. avoid motorways for the route - it only avoids it for the "location snap".

curbside
Array of strings

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.

Items Enum: "any" "right" "left"
from_curbside
Array of strings

Curbside setting for the from_point parameter. See curbside.

Items Enum: "any" "right" "left"
to_curbside
Array of strings

Curbside setting for the to_point parameter. See curbside.

Items Enum: "any" "right" "left"
out_array
Array of strings

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.

fail_fast
boolean
Default: true

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).

Responses
200

Matrix API response

default

Unexpected Error

get/matrix
Request samples
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"
Response samples
application/json
{
  • "distances": [
    ],
  • "times": [
    ],
  • "weights": [
    ],
  • "info": {
    }
}

POST Matrix Endpoint

The GET endpoint has an URL length limitation, which hurts for many locations per request. In those cases use this POST endpoint with a JSON as input. The only parameter in the URL will be the key. Both request scenarios are identical except that all singular parameter names are named as their plural for a POST request. The effected parameters are: points, from_points, to_points, and out_arrays. For the remaining parameters please refer to the guide of the GET endpoint.

Please note that in contrast to GET endpoint the points have to be specified as [longitude, latitude] array (in that order, similar to GeoJson).

For example the query point=10,11&point=20,22&profile=car will be converted to the following JSON:

{ "points": [[11,10], [22,20]], "profile": "car" }

A complete curl Example:

curl -X POST -H "Content-Type: application/json" "https://graphhopper.com/api/1/matrix?key=[YOUR_KEY]" -d '{"elevation":false,"out_arrays":["weights", "times"],"from_points":[[-0.087891,51.534377],[-0.090637,51.467697],[-0.171833,51.521241],[-0.211487,51.473685]],"to_points":[[-0.087891,51.534377],[-0.090637,51.467697],[-0.171833,51.521241],[-0.211487,51.473685]],"profile":"car"}'
Securityapi_key
Request
Request Body schema: application/json
One of:
profile
string (VehicleProfileId)
Default: "car"

Specifies the vehicle profile of this type. The profile is used to determine the network, speed and other physical attributes to use for routing the vehicle or pedestrian. See the section about routing profiles for more details and valid profile values.

from_points
Array of numbers

The starting points for the routes in an array of [longitude,latitude]. For instance, if you want to calculate three routes from point A such as A->1, A->2, A->3 then you have one from_point parameter and three to_point parameters.

to_points
Array of numbers

The destination points for the routes in an array of [longitude,latitude].

from_point_hints
Array of strings

See point_hintsof symmetrical matrix

to_point_hints
Array of strings

See point_hintsof symmetrical matrix

snap_preventions
Array of strings

See snap_preventions of symmetrical matrix

from_curbsides
Array of strings

See curbsidesof symmetrical matrix

to_curbsides
Array of strings

See curbsidesof symmetrical matrix

out_arrays
Array of strings

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.

fail_fast
boolean
Default: true

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).

Responses
200

Matrix API response

default

Unexpected Error

post/matrix
Request samples
application/json
{
  • "from_points": [
    ],
  • "to_points": [
    ],
  • "from_point_hints": [
    ],
  • "to_point_hints": [
    ],
  • "out_arrays": [
    ],
  • "vehicle": "car"
}
Response samples
application/json
{
  • "distances": [
    ],
  • "times": [
    ],
  • "weights": [
    ],
  • "info": {
    }
}

Batch Matrix Endpoint

Prefer the synchronous endpoint and use this Batch endpoint for long running problems only.

The Batch Matrix endpoint allows using matrices with more locations and works asynchronously - similar to the Batch Route Optimization endpoint:

  • Create a HTTP POST request against /matrix/calculate and add the key in the URL: /matrix/calculate?key=[YOUR_KEY]. This will give you the job_id from the response json like { "job_id": "7ac65787-fb99-4e02-a832-2c3010c70097" }
  • Poll via HTTP GET requests every 500ms against /matrix/solution/[job_id]

Here are some full examples via curl:

$ 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]]}'
{"job_id":"7ac65787-fb99-4e02-a832-2c3010c70097"}

Pick the returned job_id and use it in the next GET requests:

$ curl -X GET "https://graphhopper.com/api/1/matrix/solution/7ac65787-fb99-4e02-a832-2c3010c70097?key=[YOUR_KEY]"
{"status":"waiting"}

When the calculation is finished (status:finished) the JSON response will contain the full matrix JSON under solution:

$ curl -X GET "https://graphhopper.com/api/1/matrix/solution/7ac65787-fb99-4e02-a832-2c3010c70097?key=[YOUR_KEY]"
{"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"}

Please note that if an error occured while calculation the JSON will not have a status but contain directly the error message e.g.:

{"message":"Cannot find from_points: 1"}

And the optional hints array.

Securityapi_key
Request
Request Body schema: application/json
One of:
profile
string (VehicleProfileId)
Default: "car"

Specifies the vehicle profile of this type. The profile is used to determine the network, speed and other physical attributes to use for routing the vehicle or pedestrian. See the section about routing profiles for more details and valid profile values.

from_points
Array of numbers

The starting points for the routes in an array of [longitude,latitude]. For instance, if you want to calculate three routes from point A such as A->1, A->2, A->3 then you have one from_point parameter and three to_point parameters.

to_points
Array of numbers

The destination points for the routes in an array of [longitude,latitude].

from_point_hints
Array of strings

See point_hintsof symmetrical matrix

to_point_hints
Array of strings

See point_hintsof symmetrical matrix

snap_preventions
Array of strings

See snap_preventions of symmetrical matrix

from_curbsides
Array of strings

See curbsidesof symmetrical matrix

to_curbsides
Array of strings

See curbsidesof symmetrical matrix

out_arrays
Array of strings

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.

fail_fast
boolean
Default: true

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).

Responses
200

A jobId you can use to retrieve your solution from the server.

default

Unexpected Error

post/matrix/calculate
Request samples
application/json
{
  • "from_points": [
    ],
  • "to_points": [
    ],
  • "from_point_hints": [
    ],
  • "to_point_hints": [
    ],
  • "out_arrays": [
    ],
  • "vehicle": "car"
}
Response samples
application/json
{
  • "job_id": "44886560-b584-4da5-b245-768151dacd8f"
}

GET Batch Matrix Endpoint

This endpoint returns the solution of a JSON submitted to the Batch Matrix endpoint. You can fetch it with the job_id, you have been sent.

Securityapi_key
Request
path Parameters
jobId
required
string

Request solution with jobId

Responses
200

A response containing the matrix

default

Unexpected Error

get/matrix/solution/{jobId}
Request samples
Response samples
application/json
{
  • "solution": {
    }
}

Geocoding API

Everything about geocoding

Geocoding Endpoint

Introduction

Geocoding Example

Geocoding describes the process of transforming an textual address representation to a coordinate (latitude,longitude). For example the conversion from Berlin to 52.5170365,13.3888599.

Reverse geocoding converts a coordinate to a textual address representation or place name. Find out more about Geocoding itself on Wikipedia.

Securityapi_key
Request
query Parameters
q
string

If you do forward geocoding, this is required and is a textual description of the address you are looking for.

locale
string
Default: "en"

Display the search results for the specified locale. Currently French (fr), English (en) and German (de) are explicitly supported. Otherwise leave the locale empty.

limit
integer <int32>
Default: 5

Specify the maximum number of results to return

reverse
boolean
Default: false

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.

debug
boolean
Default: false

If true, the output will be formatted.

point
string

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.

provider
string
Default: "default"

The provider parameter is currently under development and can fall back to default at any time. The 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. To try it append the providerparameter to the URL like &provider=nominatim, the result structure should be identical in all cases - if not, please report this back to us. Keep 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. If 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.

The credit costs can be different for all providers - see here for more information about it.

Currently, only the default provider and gisgraphy supports autocompletion of partial search strings.

All providers support normal "forward" geocoding and reverse geocoding via reverse=true.

Default (provider=default)

This provider returns results of our internal geocoding engine, as described above. In addition to the above documented parameters the following parameters are possible:

  • bbox - the expected format is minLon,minLat,maxLon,maxLat
  • 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.

Nominatim (provider=nominatim)

The GraphHopper Directions API uses a commercially hosted Nominatim geocoder (hosted by OpenCageData).

In addition to the above documented parameters we currently support the following parameters:

  • 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.
  • bounds - the expected format is minLon,minLat,maxLon,maxLat

Gisgraphy (provider=gisgraphy)

This provider returns results from the Gisgraphy geocoder which you can try here.

Limitations: The locale parameter is not supported. Gisgraphy does not return OSM tags or an extent.

Gisgraphy 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.

In addition to the above documented parameters Gisgraphy allows to use the following parameters, which can be used as documented here:

  • radius - radius in meters
  • country - restrict search for the specified country. The value must be the ISO 3166 Alpha 2 code of the country.

NetToolKit (provider=nettoolkit)

This provider returns results from the NetToolKit provider which is specialized for US addresses and provides a wrapper around Nominatim for other addresses. You can try it here.

The following additional NetToolKit parameters are supported (read here for more details):

  • source: User can choose which source provider to geocode the address, this value is "NetToolKit" by default
  • country_code: an iso-3166-2 country code (e.g : US) filter the results to the specify country code

Limitations: NetToolKit does not support the locale parameter. NetToolKit does not return OSM tags (e.g. osm_id, osm_type, osm_value).

OpenCage Data (provider=opencagedata)

This provider returns results from the OpenCageData geocoder which you can try here. The difference to the nominatim provider is that other geocoders might be used under the hood.

In addition to the above documented parameters OpenCage Data allows to use the following parameters, which can be used as documented here:

  • 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.
  • bounds - the expected format is minLon,minLat,maxLon,maxLat
Responses
200

An array found locations

default

Unexpected error

get/geocode
Request samples
curl "https://graphhopper.com/api/1/geocode?q=berlin&locale=de&key=api_key"
Response samples
application/json
{
  • "hits": [
    ],
  • "took": 37
}

Isochrone API

Everything about isochrones

Isochrone Endpoint

Example

You can get an example response via:

curl "https://graphhopper.com/api/1/isochrone?point=51.131108,12.414551&key=[YOUR_KEY]"

Don't forget to replace the placeholder with your own key.

Introduction

Isochrone screenshot

An isochrone of a location is ''a line connecting points at which a vehicle arrives at the same time'', see Wikipedia. With the same API you can also calculate isodistances, just use the parameter distance_limit instead of time_limit`.

Use Cases

Some possible areas in which this API may be useful to you:

  • real estate analysis
  • realtors
  • vehicle scheduling
  • geomarketing
  • reach of electric vehicles
  • transport planning
  • logistics (distribution and retail network planning)

API Clients and Examples

See the clients section in the main documentation, and live examples.

Securityapi_key
Request
query Parameters
point
required
string

Specify the start coordinate

time_limit
integer <int32>
Default: 600

Specify which time the vehicle should travel. In seconds.

distance_limit
integer <int32>

Specify which distance the vehicle should travel. In meters.

profile
string (VehicleProfileId)
Default: "car"

Specifies the vehicle profile of this type. The profile is used to determine the network, speed and other physical attributes to use for routing the vehicle or pedestrian. See the section about routing profiles for more details and valid profile values.

buckets
integer <int32>
Default: 1

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.

reverse_flow
boolean
Default: false

If false the flow goes from point to the polygon, if true the flow goes from the polygon "inside" to the point. Example use case for false: How many potential customer can be reached within 30min travel time from your store vs. true: How many customers can reach your store within 30min travel time.

Responses
200

Isochrone Result

default

Unexpected Error

get/isochrone
Request samples
Response samples
application/json
{
  • "polygons": [
    ]
}

Map Matching API

Everything about map matching aka "snap to road"

Map-match a GPX file

Example

You get an example response for a GPX via:

curl -XPOST -H "Content-Type: application/gpx+xml" "https://graphhopper.com/api/1/match?profile=car&key=[YOUR_KEY]" --data @/path/to/some.gpx

A minimal working GPX file looks like

<gpx>
 <trk>
  <trkseg>
   <trkpt lat="51.343657" lon="12.360708"></trkpt>
   <trkpt lat="51.343796" lon="12.361337"></trkpt>
   <trkpt lat="51.342784" lon="12.361882"></trkpt>
  </trkseg>
 </trk>
</gpx>

Introduction

Map Matching screenshot

The Map Matching API is part of the GraphHopper Directions API and with this API you can snap measured GPS points typically as GPX files to a digital road network to e.g. clean data or attach certain data like elevation or turn instructions to it. Read more at Wikipedia.

In the example screenshot above and demo you see the Map Matching API in action where the black line is the GPS track and the green one is matched result.

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. See below for more supported parameters.

API Clients and Examples

See the clients section in the main documentation, and live examples.

Limits and Counts

The cost for one request depends on the number of GPS location and is documented here.

One request should not exceed the Map Matching API location limit depending on the package, see the pricing in our dashboard.

Securityapi_key
Request
query Parameters
gps_accuracy
integer

Specify the precision of a point, in meter

profile
string (VehicleProfileId)
Default: "car"

Specifies the vehicle profile of this type. The profile is used to determine the network, speed and other physical attributes to use for routing the vehicle or pedestrian. See the section about routing profiles for more details and valid profile values.

locale
string
Default: "en"

The locale of the resulting turn instructions. E.g. pt_PT for Portuguese or de for German.

elevation
boolean
Default: false

If true, a third coordinate, the altitude, is included with all positions in the response. This changes the format of the points and snapped_waypoints fields of the response, in both their encodings. Unless you switch off the points_encoded parameter, you need special code on the client side that can handle three-dimensional coordinates.

details
Array of strings

Optional parameter. The following path details are available: street_name, street_ref, street_destination, roundabout, country, time, distance, max_speed, max_weight, max_width, toll, road_class, road_class_link, road_access, road_environment, hazmat, hazmat_tunnel, hazmat_water, lanes, surface, smoothness, hike_rating, mtb_rating, foot_network, bike_network, get_off_bike. Read more about the usage of path details here.

instructions
boolean
Default: true

If instructions should be calculated and returned

calc_points
boolean
Default: true

If the points for the route should be calculated at all.

points_encoded
boolean
Default: true

Allows changing the encoding of location data in the response. The default is polyline encoding, which is compact but requires special client code to unpack. (We provide it in our JavaScript client library!) Set this parameter to false to switch the encoding to simple coordinate pairs like [lon,lat], or [lon,lat,elevation]. See the description of the response format for more information.

Responses
200

Routing Result

default

Unexpected Error

post/match
Request samples
Response samples
application/json
{
  • "hints": {
    },
  • "info": {
    },
  • "paths": [