GET /v1/route
Overview
Compute the best route between two points on the road network, with distance, duration, geometry, and optional turn-by-turn instructions in English or French.
Cost: 2 credits per request. Availability: all plans. The car profile is included everywhere; bike and foot require the Startup plan or above, truck and moto require Growth or above.
Request
GET https://api.geocodeme.net/v1/route
Required header: X-Api-Key: gm_YOUR_API_KEY
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
from | string | Yes | n/a | Origin as lon,lat (e.g. 2.3522,48.8566) |
to | string | Yes | n/a | Destination as lon,lat (e.g. 4.8357,45.7640) |
profile | string | No | car | Vehicle profile: car, bike, foot, truck, or moto (plan-gated, see above) |
geometries | string | No | geojson | Geometry format: geojson, polyline, or polyline6 |
steps | boolean | No | false | Include turn-by-turn instructions |
language | string | No | en | Instruction language (en or fr), only relevant with steps=true |
use_tolls | boolean | No | n/a | Prefer (true) or avoid (false) toll roads. Motorized profiles only |
truck_height | float | No | n/a | Vehicle height in meters (0 to 10). Requires profile=truck |
truck_width | float | No | n/a | Vehicle width in meters (0 to 5). Requires profile=truck |
truck_weight | float | No | n/a | Vehicle weight in metric tons (0 to 100). Requires profile=truck |
truck_height/truck_width/truck_weightare only valid withprofile=truck; with any other profile the API returns a400 INVALID_PARAMETER.use_tollsonly applies to motorized profiles; combining it withbikeorfootreturns a400 INVALID_PARAMETER.
Requests rejected by these validations are not charged any credits.
Code Examples
- cURL
- Python
- JavaScript
curl -H "X-Api-Key: gm_YOUR_API_KEY" \
"https://api.geocodeme.net/v1/route?from=2.3522,48.8566&to=2.2945,48.8584&profile=car&steps=true"
import os
import requests
api_key = os.environ["GEOCODEME_API_KEY"]
response = requests.get(
"https://api.geocodeme.net/v1/route",
params={
"from": "2.3522,48.8566",
"to": "2.2945,48.8584",
"profile": "car",
"steps": "true",
},
headers={"X-Api-Key": api_key},
)
response.raise_for_status()
data = response.json()
print(f"Distance: {data['distance_meters'] / 1000:.1f} km")
print(f"Duration: {data['duration_seconds'] / 60:.0f} min")
for step in data.get("steps", []):
print(f"- {step['instruction']}")
const apiKey = process.env.GEOCODEME_API_KEY;
const params = new URLSearchParams({
from: "2.3522,48.8566",
to: "2.2945,48.8584",
profile: "car",
steps: "true",
});
const response = await fetch(
`https://api.geocodeme.net/v1/route?${params}`,
{ headers: { "X-Api-Key": apiKey } }
);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
console.log(`Distance: ${(data.distance_meters / 1000).toFixed(1)} km`);
console.log(`Duration: ${Math.round(data.duration_seconds / 60)} min`);
Response
All responses include rate limiting headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Monthly-Remaining, etc.).
With geometries=geojson (default) and steps=true (geometry shortened for readability):
{
"coordinates": [
[2.3522, 48.8566],
[2.3488, 48.8589],
[2.3305, 48.8630],
[2.3079, 48.8621],
[2.2945, 48.8584]
],
"distance_meters": 6284.0,
"duration_seconds": 941.0,
"steps": [
{
"instruction": "Drive west on Rue de Rivoli.",
"distance_meters": 1520.0,
"duration_seconds": 210.0,
"type": 1,
"street_names": ["Rue de Rivoli"]
},
{
"instruction": "Turn right onto Quai des Tuileries.",
"distance_meters": 980.0,
"duration_seconds": 145.0,
"type": 10,
"street_names": ["Quai des Tuileries"]
},
{
"instruction": "You have arrived at your destination.",
"distance_meters": 0.0,
"duration_seconds": 0.0,
"type": 4,
"street_names": []
}
],
"attribution": "Route data (c) OpenStreetMap contributors",
"meta": {
"took_ms": 38,
"cache_hit": false
}
}
With geometries=polyline (or polyline6), the geometry is returned as geometry_polyline (an encoded string) and coordinates is omitted.
This endpoint omits fields that do not apply to your request instead of returning them as null: coordinates and geometry_polyline are mutually exclusive, and steps is only present when steps=true.
Schema
| Field | Type | Description |
|---|---|---|
coordinates | array | Route geometry as [[longitude, latitude], ...], present when geometries=geojson |
geometry_polyline | string | Encoded polyline string, present when geometries=polyline or polyline6 |
distance_meters | float | Total route distance in meters |
duration_seconds | float | Estimated travel time in seconds |
steps | array | Turn-by-turn maneuvers, present only when steps=true |
steps[].instruction | string | Human-readable instruction, in the requested language |
steps[].distance_meters | float | Length of this maneuver in meters |
steps[].duration_seconds | float | Duration of this maneuver in seconds |
steps[].type | integer | Maneuver type code (routing engine convention: start, turn, arrival, ...) |
steps[].street_names | array | Street names involved in the maneuver |
attribution | string | Always "Route data (c) OpenStreetMap contributors" |
meta.took_ms | integer | Server processing time in milliseconds |
meta.cache_hit | boolean | Whether the response was served from cache |
Error Responses
Profile not included in your plan
{
"error": {
"code": "PLAN_UPGRADE_REQUIRED",
"message": "The 'truck' profile is not included in your plan. Upgrade to unlock it.",
"field": "profile",
"upgrade_url": "https://geocodeme.net/dashboard/billing"
}
}
Malformed coordinate
{
"error": {
"code": "INVALID_PARAMETER",
"message": "'from' must be 'lon,lat' (e.g. 2.3522,48.8566)",
"field": "from"
}
}
Truck dimensions without the truck profile
{
"error": {
"code": "INVALID_PARAMETER",
"message": "truck_height/truck_width/truck_weight require profile=truck",
"field": "profile"
}
}
All endpoints are also subject to INVALID_API_KEY (401) and RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED (429) errors. See Error Codes for the full reference.