Integrate A-to-B route planning, turn-by-turn navigation, route optimization, isochrone calculations, location clustering and other tools into your application.
Integrate A-to-B route planning, turn-by-turn navigation, route optimization, isochrone calculations, location clustering and other tools into your application.
Authenticate to the API by passing your key as a query parameter in every request.
You can also try all API parts without registration in our API explorer.
To speed up development and make coding easier, we offer a JavaScript client and a Java client.
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 OkHttp library automatically reuses SSL/TLS sessions and also the browser takes care of this automatically. For python you can use the requests
library: first you create a session (session = requests.Session()
) and then do requests only with this session instead of directly using "requests".
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 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".
The default data source is OpenStreetMap and as an alternative we have also integrated TomTom.
The Route Optimization API can be used to solve traveling salesman or vehicle routing problems. You can use our API Explorer to explore Route Optimization. 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.
Further reading:
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. Besides path coordinates it can return turn-by-turn instructions, elevation, path details and other useful information about the route.
Use our API Explorer to explore the Routing API.
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.
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 may lead to sub-optimal results if used without user interaction. See e.g. provider=nominatim
as an appropriate alternative for less interactive use cases.
Display the search results for the specified locale. Currently French (fr), English (en) and German (de) are explicitly supported. Otherwise leave the locale empty.
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.
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.
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 provider
parameter 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 support autocompletion of partial search strings.
All providers support normal "forward" geocoding and reverse geocoding via reverse=true
.
provider=default
)This 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 (a user types an address into a search field).
In addition to the above documented parameters the following parameters are possible:
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.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.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.bbox
- the expected format is minLon,minLat,maxLon,maxLat
. This requires reverse=false.radius
- the search radius in km for the reverse search. This requires reverse=true.provider=nominatim
)The GraphHopper Directions API uses a commercially hosted Nominatim geocoder (hosted by OpenCageData). It is best suited for use cases without or less user interaction like batch processing or detailed location data retrieval. It is not suited for "autocomplete".
In addition to the above documented parameters we currently support the following parameters:
minLon,minLat,maxLon,maxLat
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 meterscountry
- restrict search for the specified country. The value must be the ISO 3166 Alpha 2 code of the country.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 defaultcountry_code
: an iso-3166-2 country code (e.g : US) filter the results to the specify country codeLimitations: NetToolKit does not support the locale
parameter. NetToolKit does not return OSM tags (e.g. osm_id, osm_type, osm_value).
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:
minLon,minLat,maxLon,maxLat
curl "https://graphhopper.com/api/1/geocode?q=berlin&locale=de&key=api_key"
An array found locations
The number of seconds that you have to wait before a reset of the credit count is done.
{ "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 }
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`.
Some possible areas in which this API may be useful to you:
See the clients section in the main documentation, and our API explorer.
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.
See the clients section in the main documentation, and our API explorer.
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.
It solves the “capacity clustering problem” by assigning a set of customers to a given number of distinct groups (called clusters). The API “clusters” by minimizing the total distance from each individual customer to its designated group median. It can also consider minimum and maximum capacity restrictions for each group.
Clustering can be used in many practical applications. For example, it can help to plan territories, i.e. territory optimization for field teams with large territories for field workers, or to solve large vehicle routing problems (VRP).
Try Clustering in our API Explorer!
The 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). We currently support two approaches.
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. This 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.
You can explicitly define clusters via "clusters". In this way, each individual cluster can be defined. This 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. In 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 explicitly, any configuration of "clustering" will be overwritten by these explicit clusters.
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.
You can create routing profiles that are customized to your needs. You can take advantage of all the modelling options described in the Custom Model section and use the created custom profile (prefix cp_
) with our Routing, Matrix and Route Optimization APIs.
Important notes
car
, bike
, foot
and ecargobike
. Contact us if you have different requirements. Motor vehicles can be emulated like done for truck
in this post.A curl example:
curl -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"}'
If you plan to tweak your custom_model frequently it is recommended to initially use the Routing API where a different custom model can be specified in every request. Or use GraphHopper Maps and click the gear button.
Creating custom profiles using the API Explorer
Besides using the /profiles
endpoint directly you can also create custom profiles from our API explorer.
id
from the output window (it starts with cp_
)."profile": "car"
(vehicle_types
section) with the profile id
and click "Send":You should now see that the solution no longer uses motorways. Keep in mind that this is a simple example. The custom model language is a lot more powerful than this. Make sure you read the Custom Model section to learn about all the details.
Note that you can use the profile id
just as well for the /matrix
or /route
endpoint. E.g. select "Routing API" and use the profile id
in the request: