GET /v1/elevation
Overview
Look up terrain elevation for one or more points. With range=true the response also pairs each point with its cumulative distance along the path: a ready-to-plot elevation profile for a bike ride or a hike. Other uses: grade-aware logistics (EV range, truck routes) and enriching GPS traces with altitude.
Cost: 2 credits per request (whatever the number of points). Availability: from the Startup plan.
Request
GET https://api.geocodeme.net/v1/elevation
Required header: X-Api-Key: gm_YOUR_API_KEY
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
points | string | Yes | n/a | Points as lon,lat separated by | (1 to 500 entries), e.g. 6.8652,45.8326|6.8700,45.8300 |
range | boolean | No | false | When true, also return the cumulative-distance elevation profile (range_profile) |
Remember to URL-encode the | separator as %7C if your HTTP client does not do it for you.
Code Examples
- cURL
- Python
- JavaScript
curl -H "X-Api-Key: gm_YOUR_API_KEY" \
"https://api.geocodeme.net/v1/elevation?points=6.8652,45.8326%7C6.8700,45.8300&range=true"
import os
import requests
api_key = os.environ["GEOCODEME_API_KEY"]
response = requests.get(
"https://api.geocodeme.net/v1/elevation",
params={"points": "6.8652,45.8326|6.8700,45.8300", "range": "true"},
headers={"X-Api-Key": api_key},
)
response.raise_for_status()
data = response.json()
for distance_m, height_m in data["range_profile"]:
print(f"{distance_m:>7.0f} m -> {height_m} m a.s.l.")
const apiKey = process.env.GEOCODEME_API_KEY;
const params = new URLSearchParams({
points: "6.8652,45.8326|6.8700,45.8300",
range: "true",
});
const response = await fetch(
`https://api.geocodeme.net/v1/elevation?${params}`,
{ headers: { "X-Api-Key": apiKey } }
);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
for (const [distanceM, heightM] of data.range_profile) {
console.log(`${distanceM} m -> ${heightM} m a.s.l.`);
}
Response
All responses include rate limiting headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Monthly-Remaining, etc.).
With range=true:
{
"elevations": [1035.0, 1002.0],
"range_profile": [
[0.0, 1035.0],
[472.0, 1002.0]
],
"attribution": "Route data (c) OpenStreetMap contributors; elevation (c) Tilezen/AWS",
"meta": {
"took_ms": 12,
"cache_hit": false
}
}
Without range, the response only contains elevations (the range_profile field is omitted, not null).
Schema
| Field | Type | Description |
|---|---|---|
elevations | array | elevations[i] = height in meters of the i-th input point, or null when the point is outside known terrain |
range_profile | array | [cumulative_distance_m, height_m] pairs along the path, present only when range=true |
attribution | string | Always "Route data (c) OpenStreetMap contributors; elevation (c) Tilezen/AWS" |
meta.took_ms | integer | Server processing time in milliseconds |
meta.cache_hit | boolean | Whether the response was served from cache |
null elevationsA null entry means the point falls outside the terrain model's coverage (for example, in open sea). The request itself still succeeds; check individual entries rather than the HTTP status.
Error Responses
Too many (or zero) points
{
"error": {
"code": "INVALID_PARAMETER",
"message": "'points' must contain between 1 and 500 'lon,lat' entries",
"field": "points"
}
}
Endpoint not included in your plan (Free)
{
"error": {
"code": "PLAN_UPGRADE_REQUIRED",
"message": "The 'elevation' feature is not included in your plan. Upgrade to unlock it.",
"upgrade_url": "https://geocodeme.net/dashboard/billing"
}
}
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.