APIs

Elevation API: points

Point lookups, batch lookups, and path sampling — parameters, response shapes, and source-selection behavior.

Elevations computed from the best available source at each location, returned in meters. All endpoints require an API key.

Endpoint Methods Input
/v1/elevation/point GET lat, lon
/v1/elevation/points GET, POST latlons — pipe-separated lat,lon|lat,lon|…
/v1/elevation/sample GET, POST path (same syntax, ≥ 2 vertices) + samples=N

POST variants accept a JSON body with the same field names as the query parameters (the body wins on conflict). In a body, latlons/path may be a pipe-separated string, a list of "lat,lon" strings, or a list of [lat, lon] pairs.

sample computes N evenly spaced points along the geodesic polyline (endpoints included), then behaves exactly like points — useful for elevation profiles along a route.

Examples

Single point:

curl "https://api.darly.io/v1/elevation/point?lat=45.51&lon=-73.56" \
  -H "X-API-Key: $DARLY_API_KEY"

Batch (each point in a batch counts as one lookup against your limits):

curl -X POST "https://api.darly.io/v1/elevation/points" \
  -H "X-API-Key: $DARLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"latlons": "45.51,-73.56|49.28,-123.12|19.43,-99.13"}'

Elevation profile — 50 samples along a leg of Mount Rainier:

curl -G "https://api.darly.io/v1/elevation/sample" \
  --data-urlencode "path=46.85,-121.76|46.79,-121.74" \
  --data-urlencode "samples=50" \
  -H "X-API-Key: $DARLY_API_KEY"

Shared options

All point endpoints accept:

Param Values Default Behavior
surface dtm, dsm dtm Terrain (bare earth) or surface (includes buildings/canopy). Only collections carrying the requested asset are considered.
vertical_datum egm2008, wgs84_ellipsoid egm2008 egm2008 = orthometric height above the EGM2008 geoid (what most people mean by "elevation above sea level"). wgs84_ellipsoid = height above the WGS84 ellipsoid (what raw GPS reports). Converted from each source's native datum via geoid grids.
interpolation bilinear, nearest bilinear Ignored when radius > 0. Bilinear degrades to nearest where a full 2×2 neighborhood is unavailable (raster edges, nodata neighbors).
radius meters, 0–100 0 0 samples at the point. Otherwise: mean of valid cells whose center falls within the circle (nodata excluded). A radius smaller than the pixel degrades to the containing cell.
collections ordered STAC collection IDs omitted Comma-separated (JSON array on POST). IDs are the STAC collection IDs from the catalog — list them via GET /collections. Only these collections are considered, and order is priority: the first collection answers wherever it has valid data; each later one is only consulted where every earlier one came up empty (nodata or no coverage). Useful where overlapping collections exist and you know which you want. Omitted: all collections your plan allows, ranked finest resolution first — lidar naturally beats the 30 m globals. Unknown and not-allowed IDs return the same error; so does an ID without the requested surface.

How the source is chosen

For each point:

  1. Find candidate items intersecting the point (filtered by your allowed collections and the requested surface).
  2. Rank by collection resolution (finest first), then item date (newest first) within a collection. An explicit collections list replaces the resolution ranking with your order — first in the list is tried first (item date still breaks ties within a collection).
  3. Read the best candidate. Nodata falls through to the next candidate (voids, coastal edges, tile overlap) — and to the global 30 m datasets last.
  4. Nothing valid anywhere → elevation: null, collection: null; the request still succeeds.

There is no fake bathymetry: open ocean is null, not 0.

Response shape

point returns result (single object); points/sample return results (array, same order as the input):

Response
{
  "status": "OK",
  "result": {
    "lat": 45.51,
    "lon": -73.56,
    "elevation": 36.42,
    "collection": "can-nrcan-hrdem-1m",
    "vertical_datum": "egm2008",
    "surface": "dtm",
    "resolution": 1.0
  }
}

resolution is the source dataset's ground sampling distance in meters — use it to judge how much to trust the value.

Caps and errors

  • Up to 512 points per request on paid plans, 100 on Free (latlons entries or samples), up to 25 path vertices, radius up to 100 m.
  • Validation failures, including unknown query/body fields, return 400 {"status": "INVALID_REQUEST", "error": "…"}.
  • Missing key → 401; per-minute and monthly limit errors → 429. See rate limits & quotas for bodies and headers.