Elevation API

Query terrain elevation (metres above sea level) for any coordinate or a batch of coordinates. Powered by the hillshading DEM source.

Billing1 unit per request (single or batch, regardless of point count)
PlanPaid plans only (Starter, Pro, Enterprise). Free-plan keys get 403.
CoverageMatches the hillshading source — Europe, Oceania, and expanding

Single coordinate

/elevation/{lat}/{lng}?apiKey=<key>
ParameterTypeDescription
latfloatLatitude (WGS 84)
lngfloatLongitude (WGS 84)

Example

/elevation/50.732669/14.984353?apiKey=<key>

Response

{
  "long": 14.984353,
  "lat": 50.732669,
  "elevation": 1008,
  "z": 12,
  "x": 2218,
  "y": 1376,
  "pixelX": 250,
  "pixelY": 34
}
FieldDescription
elevationAltitude in metres above sea level
z, x, yDEM tile coordinates that were sampled
pixelX, pixelYPixel position within the sampled tile

Returns 204 No Content (empty body) if the DEM has no data at that point.

Note: 204 No Content means the DEM has no data at that point (outside coverage), not an error.


Batch

Query multiple coordinates in a single request.

POST /elevation?apiKey=<key>
Content-Type: application/json

Request body:

{
  "points": [
    { "lat": 50.732669, "lon": 14.984353, "z": 12 },
    { "lat": 50.0755, "lon": 14.4378, "z": 12 },
    { "lat": 49.1951, "lon": 16.6068, "z": 12 }
  ]
}
FieldTypeDescription
latfloatLatitude (WGS 84)
lonfloatLongitude (WGS 84)
zintRequired. DEM tile zoom to sample at — see What z does. Send 12.

All three fields are required on every point, and the longitude field is lon, not lng. The Content-Type: application/json header is required too.

Response — a bare array of elevation values in input order (null where no data is available):

[1008, 247.20000000000073, 216.8000000000011]

Values are floats and are not rounded — round client-side if you want whole metres.

Rejected request bodies all return 400 with a plain-text message:

BodyMessage
[[50.0755, 14.4378]]Missing or empty points array
{"points": []}Missing or empty points array
a point using lng instead of lonInvalid point at index 0: lon must be a finite number
a point with no zInvalid point at index 0: z must be a finite number

A rejected request still costs 1 unit, so validate the body client-side.


What z does

z is the DEM tile zoom level used for the lookup, not a property of your coordinate. The server turns each point into a DEM tile plus one pixel inside it and reads the elevation from that pixel, so a higher z means a smaller patch of ground per pixel and a more precise answer.

z is clamped to the DEM’s zoom range (5–12), so values outside it are not an error — they behave as 5 or 12. One pixel covers roughly:

zGround resolution at 50° N
5~1,570 m
8~200 m
10~50 m
12~12 m

The difference is real. Sampling Sněžka’s summit (1,603 m) at z=5 returns 1,299 m, at z=8 1,559 m, at z=10 1,597 m and at z=12 1,601 m. Values above 12 return exactly the same answer as 12.

Send z: 12. The only reason to go lower is throughput on a very dense track — points are grouped by tile, so a lower z fetches fewer tiles — and the accuracy cost above is usually not worth it.


Notes

  • Coverage matches the hillshading source — not worldwide. Returns 204 (single) or null in the array (batch) for uncovered regions.
  • Resolution depends on the z parameter — z=12 gives the best available resolution (~12 m at Czech latitudes)
  • Coordinate order is always latitude, longitude in the URL; in the batch body the fields are named lat and lon
  • Batch bodies are capped at 1 MB. A larger body returns 413 and is not billed