Routing API
The Routing API works via HTTP GET requests and calculates routes between two or more waypoints. The API builds routes for automobiles, delivery trucks, cargo vans, bicycles, motor scooters, and walking or riding a bike. A returned result includes Directions and Turn-by-Turn navigation instructions.
You can now easily customize your routes using parameters to avoid specific road types and route parts, as well as locations that should be skipped. In addition, you can request detailed information like speed limits, route elevation profile, and more detailed navigation instructions.
We've created an API Playground where you can explore and examine the functionality of our API:
Authentication and API key
To use the Routing API, you'll need an API key. You can register and get a Routing API Key for free without a credit card.
We offer a free plan, so there's no need to stress about cost. Start for free and upgrade to a paid plan when the needs of your project increase. For more information on our plans, visit the Pricing page.
How to get Geoapify API key
- Register on Geoapify MyProjects page
- Create a new project.
- Go to the API Keys section. One API key is generated automatically. You can generate multiple API keys per project if required.
- Optionally, you can protect the API key by listing allowed IP addresses, HTTP referrers, origins, and CORS.
- Choose "Routing API" and an API key to generate a URL and programming code.
- Press the "Try" button to execute the API call and get the result object example.
API reference: inputs
The Routing API calculates routes between provided waypoints for different modes, from buses and delivery trucks to hiking and mountain bicycles. You can choose between JSON, GeoJSON, and XML output formats to integrate the solutions quickly into your project.
Request URL
https://api.geoapify.com/v1/routing?REQUEST_PARAMS
Here are Routing API requests examples (click on a URL to test the API):
A driving route between 2 waypoints in GeoJSON format:
https://api.geoapify.com/v1/routing?waypoints=50.679023,4.569876|50.66170,4.578667&mode=drive&apiKey=YOUR_API_KEYA light delivery truck route between 5 waypoints in JSON format:
https://api.geoapify.com/v1/routing?waypoints=49.266798,4.0152071|49.267243,4.0166331|49.267668,4.0181211|49.267796,4.019288|49.2676078,4.02000185&mode=light_truck&format=json&apiKey=YOUR_API_KEYA hiking route with elevation profile in JSON format:
https://api.geoapify.com/v1/routing?waypoints=lonlat:11.765165,46.556675|lonlat:11.793963,46.549250&mode=hike&details=elevation&format=json&apiKey=YOUR_API_KEYGet a road surface and road class information for a bicycle route:
https://api.geoapify.com/v1/routing?waypoints=47.774732,9.027492|47.789538,9.0549636&mode=bicycle&details=route_details&apiKey=YOUR_API_KEYGet detailed Turn-by-Turn navigation or Directions instructions:
https://api.geoapify.com/v1/routing?waypoints=48.776438,9.150830|48.535490,9.2707263&format=json&mode=drive&details=instruction_details&apiKey=YOUR_API_KEY
Request parameters
Name | Format | Description | Example |
---|---|---|---|
apiKey | Required parameter for API key | apiKey=c3da27885e3573e09e550d044bc55e22 | |
waypoints | lat,lon or lonlat:lon,lat |
Waypoints separated by a vertical bar (pipe "|") symbol. Each coordinate is a pair of latitude and longitude, separated by a comma. | waypoints=36.734770,-76.610637|36.761226,-76.488354 , waypoints=lonlat:-76.610655,36.734770|lonlat:-76.488354,36.76122 |
mode | See the Travel Modes table | Travel or transportation mode. The Travel Modes table contains detailed information about possible travel modes and vehicle types. | mode=drive |
type | Enum: balanced , short , less_maneuvers |
Route optimization type, the default value is balanced . Check Route optimization type for more information. |
type=short |
units | Enum: metric , imperial |
Distance units for the calculated route, the default valie is metric . |
units=imperial |
lang | See the Supported languages list | Language for Turn-by-Turn instructions | lang=es |
avoid | type:importance or type:value |
List of road types or locations to be avoided by the router separated by a vertical bar (pipe "|") symbol. Check Avoid parameter option for more details. | avoid=tolls:1|ferries|location:35.234045,-80.836392 |
details | instruction_details route_details elevation |
Comma-separated list of additional information added to the routing result. Check the Route details for more information. | details=instruction_details,route_details,elevation |
traffic | Enum: free_flow , approximated |
The traffic model for route calculation, the default value is free_flow , meaning that the route is calculated optimistically with no traffic influence. The approximated traffic model decreases speed for potentially heavy-loaded roads. The traffic model is only used for motorized vehicles modes, such as drive , truck , etc. |
traffic=approximated |
max_speed | number | The maximum speed that a vehicle can travel. This applies to driving mode, all truck modes, and bus modes. The max_speed should be specified within the range of 10 to 252 KPH (6.5 - 155 MPH). For trucks, the standard setting is 90 kilometers per hour (KPH), while for automobiles and buses, it's set at 140 KPH by default. | max_speed=80 |
format | Enum: geojson , json , xml |
The output format, the default value is geojson . |
format=json |
Travel modes
Here are the travel modes supported by the Routing API and their respective vehicle parameters:
Mode | Max vehicle weight | Max vehicle height | Description | |
---|---|---|---|---|
drive |
3.5t | 1.6m | A passenger car | |
light_truck |
3.5t | 3.2m | A light truck, for example, small delivery truck or camping car | |
medium_truck |
7.5t | 4.1m | A medium-size truck | |
truck |
22t | 4.1m | A truck | |
heavy_truck |
40t | 4.1m | A heavy truck | |
truck_dangerous_goods |
22t | 4.1m | A truck carrying dangerous goods | |
long_truck |
22t | 4.1m | A long truck with a maximal length of 34m | |
bus |
A bus. This mode checks bus access during the route calculation. | |||
scooter |
A motor scooter or moped. | |||
motorcycle |
A motorcycle. | |||
bicycle |
A city bicycle | |||
mountain_bike |
A mountain bicycle to ride on unpaved surfaces but slower on paved terrain. | |||
road_bike |
A road-style bicycle with narrow tires and lightweight construction. | |||
walk |
A pedestrian mode | |||
hike |
A hiking mode additionally to pedestrian mode uses hiking trails and higher difficulty trails | |||
transit |
A transit or public transport mode. | |||
approximated_transit |
A transit or public transport mode uses approximated (built on available in OSM transit routes) data for route calculation. |
Route optimization type
The routing algorithm calculates the best route using specified input parameters. To help you build a route according to your requirements, we offer the following route optimization types:
Type | Description | Example |
---|---|---|
balanced |
A balanced route is a compromise between three main factors: time, cost, and distance traveled. | the default value |
short |
Optimizes a route by distance. | type=short |
less_maneuvers |
Extends the balanced routing type, but adds additional penalties for maneuvers. | type=less_maneuvers |
Note! The less_maneuvers
route optimization type is supported only in combination with the following transportation modes: drive
, truck
, light_truck
, medium_truck
, truck_dangerous_goods
, heavy_truck
, long_truck
, bus
.
Note! The short
route optimization type is not supported in combination with the following transportation modes: transit
, approximated_transit
.
Supported languages
The lang parameter specifies the language for route directions instructions. The following languages are supported:
bg
, ca
, cs
, da
, de
, el
, en-GB
, en
, es
, et
, fi
, fr
, hi
, hu
, it
, ja
, nb-NO
, nl
, pl
, pt-BR
, pt
, ro
, ru
, sk
, sl
, sv
, tr
, uk
Route details
You can request details on the route by specifying the details parameter in the request's path:
Route detail | Description | Example |
---|---|---|
instruction_details |
Adds detailed instruction for each transition maneuver, including maneuver type, instruction before the maneuver, and instruction after the maneuver. | details=instruction_details |
route_details |
Extends the route result data by additional information about each route segment, such as road class, road name, surface, speed limits, etc. | details=route_details,elevation , details=route_details |
elevation |
Adds elevation information for each point of route geometry and the corresponding route elevation profile. | details=instruction_details,elevation , details=elevation |
Note! The route_details
and elevation
increase the API call cost.
Note! The route_details
and elevation
information is not supported in combination with the following transportation modes: transit
, approximated_transit
.
Avoid parameter options
You can specify the types of roads and locations that should be avoided when generating routes:
Avoid type | Format | Description | Examples |
---|---|---|---|
tolls |
tolls or tolls:importance |
Avoid roads with tolls. In addition, you can specify how important this rule is on a scale of 1 to 0, with 1 being the most relevant and 0 being not important at all. This rule works with drive , truck , light_truck , medium_truck , truck_dangerous_goods , heavy_truck , long_truck , bus modes only. |
avoid=tolls|ferries , avoid=tolls:0.8 |
ferries |
ferries or ferries:importance |
Avoid ferries. In addition, you can specify how important this rule is on a scale of 1 to 0, with 1 being the most relevant and 0 being not important at all. | avoid=highways|ferries , avoid=ferries:0.9 |
highways |
highways or highways:importance |
Avoid highways. In addition, you can specify how important this rule is on a scale of 1 to 0, with 1 being the most relevant and 0 being not important at all. This rule works with drive , truck , light_truck , medium_truck , truck_dangerous_goods , heavy_truck , long_truck , bus modes only. |
avoid=highways |
location |
location:lat,lon or location_lonlat:lon,lat |
Avoid some parts of the route and locations. This helps, for example, to escape temporarily closed routes and barriers. | avoid=location:35.234045,-80.836392 , avoid=location_lonlat:-80.836392,35.234045 |
Note! The routing algorithm will consider the avoids you've provided when it generates a route, but it won't exclude roads if there are no alternatives. Note! The avoids do increase the calculation time and add additional cost on the routing API call.
API reference: outputs
The route contains information about the route geometry and turn-by-turn navigation instructions. The resulting structure will differ depending on the requested output format.
Terminology
Before describing the Route object, let's clarify the terminology we will be using. The following picture shows a possible route schema for three waypoints. Let's use it as an example!
Here is the terminology we use for the route results:
Name | Description | Example |
---|---|---|
Waypoint | Locations provided as input parameters to calculate a route between them | In the picture below, three waypoints or two pairs of waypoints |
Leg | A route part between 2 waypoints | The picture below shows how the calculated route object const of two legs - the first from the first waypoint to the second, and the second one - from the second waypoint to the third. |
Step | A route segment that has some individual properties and may contain turn-by-turn instruction. A leg is usually composed of multiple steps. | The first route leg consists of four steps in the picture below, and the second leg has three. |
Geometry | A route geometry is a MultiLineString (array of lines or LineStrings) object. Each line is an array of points. Every line corresponds to a route leg. | In the picture below, a route will contain two route lines. |
Result object structure
Depending on the format
parameter, the Routing API returns a GeoJSON.FeatureCollection object, JSON object or XML. Here are the response object structures riding on the result format:
GeoJSON.FeatureCollection object
Name | Description |
---|---|
type | "FeatureCollection" |
properties | Input parameters used for route calculation. Typically, this is a JSON object containing the request parameters. |
features | array of GeoJSON.Feature. Every feature corresponds to a calculated route. The feature geometry consists of an array of LineStrings, each LineString representing one route between a pair of waypoints. By default, only the response contains only one feature. More features can be returned when route alternatives are requested. |
Click to get an example of a GeoJSON response object:
https://api.geoapify.com/v1/routing?waypoints=50.679023,4.569876|50.66170,4.578667&mode=drive&apiKey=YOUR_API_KEY
JSON object or XML
JSON object (or XML object) differ a little bit from GeoJSON:
Name | Description |
---|---|
properties | Input parameters used for route calculation. Typically, this is a JSON object containing the request parameters. |
results | An array of resulting routes. Each item in the array corresponds to a calculated route, which contains route legs, steps, and route geometry. By default, only the results array has only one element. More routes are returned when more than one route is requested in one API call. |
Here is an example of a JSON response object:
https://api.geoapify.com/v1/routing?waypoints=50.679023,4.569876|50.66170,4.578667&format=json&mode=drive&apiKey=YOUR_API_KEY
Route object
The route object contains information such as the calculated distance and estimated time of arrival at the destination, as well as turn-by-turn navigation instructions:
Name | Description |
---|---|
distance | Distance of the entire route |
distance_units | Distance units. "Miles" or "Meters" depending on the units input parameter. |
time | Estimated travel time in seconds |
legs | An array of route legs. Check RouteLeg object description for more information. |
toll | True if the route has tolls |
ferry | True if the route uses a ferry |
RouteLeg object
A RouteLeg object consists of information about a route between two waypoints:
Name | Required details | Description |
---|---|---|
distance | Distance of the route leg or between two waypoints. | |
time | Estimated travel time in seconds | |
steps | An array of steps. Check LegStep object description for more information. | |
elevation | elevation |
An array of heights in meters corresponding to the route leg geometry points. |
elevation_range | elevation |
An array of [distance , height ] values corresponding to the route leg geometry points. Both distance and heights are in meters |
country_code | route_details |
List of country codes crosses by the route leg |
LegStep object
A route step contains details about a road segment, including the general-purpose road type, lane guidance for part of the direction, and turn instructions. Some information about the road segment is added by default, but additional information is provided only when the user requests more specific details from the route within the details
parameter.
Name | Required details | Description |
---|---|---|
distance | Distance of the route segment | |
time | Estimated travel time in seconds | |
from_index | The index value at which the geometry starts in the leg geometry object. | |
to_index | The index value at which the geometry ends in the leg geometry object. | |
toll | True if the step has toll | |
ferry | True if includes a ferry | |
tunnel | route_details |
True if is a tunnel |
bridge | route_details |
True if is a bridge |
roundabout | route_details |
True if is a roundabout |
speed | route_details |
Estimated speed |
speed_limit | route_details |
Speed limit |
truck_limit | route_details |
Speed limit for trucks |
surface | route_details |
Road surface. Possible values: paved_smooth , paved , paved_rough , compacted , dirt , gravel , path , impassable |
lane_count | route_details |
Number of lanes |
road_class | route_details |
Road class. Possible values: motorway , trunk , primary , secondary , tertiary , unclassified , residential , service_other |
speed_limit | route_details |
Speed limit |
name | route_details |
Road name |
rightside | route_details |
True for driving on the right side |
traversability | route_details |
Traversability. Possible values: forward , backward , both |
elevation | route_details or evelation |
Average elevation along the step |
max_elevation | evelation |
Maximal elevation along the step |
min_elevation | evelation |
Minimal elevation along the step |
elevation_gain | evelation |
The elevation difference between the first points of the step and the last point |
instruction | Contains turn-by-turn inscructions. If you request a route_details, some road segments may not have transition instructions because no turn is needed to go from one road segment to another. Check StepInstruction object for more information |
StepInstruction object
An instruction object contains turn-by-turn navigation directions in human-readable and machine-readable form. The human-readable instructions can be localized with a lang
input parameter.
Name | Required details | Description |
---|---|---|
text | Navigation instruction | |
type | instruction_details |
Type of maneuver. Possible values: "None", "StartAt", "StartAtRight", "StartAtLeft", "DestinationReached", "DestinationReachedRight", "DestinationReachedLeft", "Straight", "Straight", "SlightRight", "Right", "SharpRight", "TurnAroundRight", "TurnAroundLeft", "SharpLeft", "Left", "SlightLeft", "Straight", "Right", "Left", "ExitRight", "ExitLeft", "Straight", "StayRight", "StayLeft", "Merge", "Roundabout", "Roundabout", "FerryEnter", "FerryExit", "Transit", "TransitTransfer", "TransitRemainOn", "TransitConnectionStart", "TransitConnectionTransfer", "TransitConnectionDestination", "PostTransitConnectionDestination", "MergeRight", "MergeLeft" |
transition_instruction | instruction_details |
Transition instruction |
pre_transition_instruction | instruction_details |
Instruction before transition |
post_transition_instruction | instruction_details |
Instruction after transition |
streets | instruction_details |
List of street names that are considered for the maneuver |
exitNumber | instruction_details |
List of exit numbers that are considered for the maneuver |
exitRoadName | instruction_details |
List of exit road names that are considered for the maneuver |
exitTowards | instruction_details |
List of exit directions that are considered for the maneuver |
contains_next_instruction | instruction_details |
True when the transition instruction contains a part of the next instruction. For example, "Take the exit toward Beatties Ford Street, J.C. Smith University. Then Turn right onto Beatties Ford Road." |
roundabout_exit | instruction_details |
Roundabout exit's number |
Error response and status codes
An error may occur when an API request is malformed, or some problem arises during the generation of a route:
Name | Description |
---|---|
statusCode | HTTP response status code. There are two general categories of server errors: 5xx errors usually represent problems with route calculation or are the result of a bug and 4xx errors are used to mark requests that cannot be carried out, generally due to bad input in the request or problems with the underlying data. Important! Please contact us if you get 5xx error as a result. |
error | Human-readable string for the status code |
message | Error message |
Code samples
The Routing API is just an HTTP request away. Requests are platform-independent and can be made from most programming languages. For our code samples, we use JavaScript. You can reimplement them in similar ways with the language of your choice.
Call Routing API
The call to the Routing API is a simple HTTP Get request. For example:
const myAPIKey = "YOUR_API_KEY";
const fromWaypoint = [38.937165,-77.045590]; // latutude, longitude
const toWaypoint = [38.881152,-76.990693]; // latitude, longitude
const url = `https://api.geoapify.com/v1/routing?waypoints=${fromWaypoint.join(',')}|${toWaypoint.join(',')}&mode=drive&details=instruction_details&apiKey=${myAPIKey}`;
fetch(url).then(res => res.json()).then(result => {
console.log(result);
}, error => console.log(err));
Show the result route on a Leaflet map
When you want to display a route on a map, GeoJSON is the easiest format to use. That format is natively supported by most popular map libraries, including Leaflet.
It’s simple. Here’s how to insert a route into the map:
L.geoJSON(routeResult, {
style: (feature) => {
return {
color: "rgba(20, 137, 255, 0.7)",
weight: 5
};
}
}).bindPopup((layer) => {
return `${layer.feature.properties.distance} ${layer.feature.properties.distance_units}, ${layer.feature.properties.time}`
}).addTo(map);
Check out the live demo on JSFiddle >>
Show turn-by-turn instructions on a Leaflet map
Each step in a route has from and to positions. You can pick up their coordinates from the route geometry by using the leg index in the legs array and from_index and to_index of the step. When creating a turn-by-turn navigator, you need to show a transition instruction at the beginning of each step.
Here is how to visualize the beginning of each step with a turn-by-turn instruction on a map:
const turnByTurns = []; // collect all transitions
routeResult.features.forEach(feature => feature.properties.legs.forEach((leg, legIndex) => leg.steps.forEach(step => {
const pointFeature = {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": feature.geometry.coordinates[legIndex][step.from_index]
},
"properties": {
"instruction": step.instruction.text
}
}
turnByTurns.push(pointFeature);
})));
L.geoJSON({
type: "FeatureCollection",
features: turnByTurns
}, {
pointToLayer: function(feature, latlng) {
return L.circleMarker(latlng, turnByTurnMarkerStyle);
}
}).bindPopup((layer) => {
return `${layer.feature.properties.instruction}`
}).addTo(map);
Check out the live demo on JSFiddle >>
Show the result route on a MapLibre GL (Mapbox GL) map
You can use GeoJSON when you want to display a route on the map. GeoJSON is the most popular file format for representing geographical features.
map.addSource('route', {
type: 'geojson',
data: routeResult
});
map.addLayer({
'id': 'route-layer',
'type': 'line',
'source': 'route',
'layout': {
'line-cap': "round",
'line-join': "round"
},
'paint': {
'line-color': "#6084eb",
'line-width': 8
},
'filter': ['==', '$type', 'LineString']
});
Check out the live demo on JSFiddle >>
Get route steps geometry
You may need to display route steps, for example, to show different route segment details. You can do it in this way:
const steps = [];
routeResult.features[0].properties.legs.forEach((leg, legIndex) => {
const legGeometry = routeData.features[0].geometry.coordinates[legIndex];
leg.steps.forEach((step, index) => {
if (step.from_index === step.to_index) {
// destination point
return;
}
const stepGeometry = legGeometry.slice(step.from_index, step.to_index + 1);
steps.push({
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": stepGeometry
},
properties: step
});
});
});
Check out the live demo on JSFiddle >>
Pricing
We charge in units called "credits", for each Geoapify API call. Accumulated credits per day are called Daily usage.
Geoapify offers a variety of Pricing Plans to meet your business needs. Pricing plans start with a Free plan, including 3000 credits/day.
Here is a pricing calculation rules for the Routing API:
Rule | Cost in credits | Example |
---|---|---|
Number of waypoints | A route between every waypoint pair costs 1 credit | A route between 3 waypoints costs 2 credits |
elevation details |
elevation details add additional 1 credit for every waypoints pair |
A route between 3 waypoints with elevation details costs 2 credits + 2 credits = 4 credits |
route_details details |
route_details details add additional 1 credit for every waypoints pair |
A route between 3 waypoints with route details costs 2 credits + 2 credits = 4 credits |
500km+ routes | For routes over 500km in the distance, it costs one credit per 500km | A route between 2 waypoints, that is 1378km, costs 3 credits |
elevation for 500km+ routes |
For routes over 500km in the distance, the elevation details cost additional one credit per 500km |
A route between 2 waypoints, that is 1378km, with elevation details, costs 3 credits + 3 credits = 6 credits |
route_details for 500km+ routes |
For routes over 500km in the distance, the route_details details cost additional one credit per 500km |
A route between 2 waypoints, that is 1378km, with elevation and route_details , costs 3 credits + 3 credits + 3 credits = 9 credits |
Pricing calculation examples
- A route between Los Angeles, CA and Prunedale, CA, which is 498991m (< 500km), costs 1 credit.
- A route with an
elevation
between Los Angeles, CA and Prunedale, CA, which is 498991m, costs 2 credit. - A route with an
elevation
androute_details
between Los Angeles, CA and Prunedale, CA, which is 498991m (< 500km), costs 3 credit. - A route between Los Angeles, CA and Marin County, CA, which is 630340m (> 500km), costs 2 credit.
- A route with an
elevation
androute_details
between Los Angeles, CA and Marin County, CA, which is 630340m (> 500km), costs 6 credit. - A route between Los Angeles, CA and Lewisville, TX, which is 2268071m, costs 4 credit.