API Guide
EDOPS — the Environmental Dimensions of Place Service — generates structured
environmental signatures for a single coordinate (scope=basin), a radius around one
(scope=buffer), or an arbitrary polygon (scope=area). Signatures are derived from
global datasets aggregated at the hydrological sub-basin level in
BasinATLAS, with optional historical
enrichment from LMR v2.1 (paleoclimate), eVolv2k v4 (volcanic events), and HYDE 3.4
(land use).
Base URL: https://edops.computingplace.org/api
Interactive schema: edops.computingplace.org/api/schema
Full worked example payloads: edops_schema_basin.json · edops_schema_area.json
Research prototype. The API is publicly accessible but not under a stability guarantee — parameters and response fields may change between versions.
This page documents the endpoints below, and only those — every other route this app serves exists to support the Sandbox/Explorer/Workbench pages directly and isn't public API surface (hidden from the interactive schema accordingly).
Local vs. upstream
Many Band A–D fields appear as pairs: a local value (the sub-basin only) and an
upstream value (its entire contributing watershed, to the headwaters). Upstream keys
carry an _upstream suffix, e.g. aridity / aridity_upstream.
Aggregation depends on the variable: intensive quantities — aridity, precipitation, temperature, soils, slope — are area-weighted averages over the catchment; extensive quantities like river area and reservoir volume are sums. See each variable's Codebook entry for its rule. A few variables, like discharge, have no upstream counterpart at all — their local value is already the integrated result of everything above.
The divergence between local and upstream is usually the meaningful reading, not the upstream value alone: a desert city fed by a distant mountain river occupies a qualitatively different position than one where the two converge. Because the upstream figure spans the whole catchment, it can blend very different terrain into one number — read it against its local counterpart. The API returns both raw values; it does not compute or return the divergence itself.
Full variable-by-variable reference: see the Codebook.
Endpoints
GET /api/signature
Return an environmental signature.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
lat |
float (-90 to 90) | no | — | Latitude, decimal degrees, in [-90, 90]. Required for scope=basin/buffer. |
lon |
float (-180 to 180) | no | — | Longitude, decimal degrees, in [-180, 180]. Required for scope=basin/buffer. |
bands |
str | no | ABCDE |
Which signature bands to include, e.g. "ABCDE" or "ABCDET". |
level |
int | no | 6 |
Basin hierarchy level: 8 or 6. |
from_year |
int | no | — | Start year CE for Band T temporal enrichment (0–1998). |
to_year |
int | no | — | End year CE for Band T temporal enrichment (0–1998). |
flat |
bool | no | false |
If true, return flat field values instead of nested signature_bands; Band T temporal data appears at key "temporal" rather than in signature_bands. |
place_links |
str | no | — | Comma-separated gazetteer identifiers (e.g. "wd:Q220,gn:3169070") to echo into meta.query.place_links. |
scope |
str | yes | — | 'basin': raw values for the one basin containing this point -- the shape documented below. 'buffer': aggregate distribution over the basins within radius_km of this point -- a different shape (variables/shortfall/caveats/meta). 'area': same shape as buffer, aggregated over the basins within an arbitrary polygon instead of a radius -- see geom_wkt. |
radius_km |
float | no | — | Buffer radius in km. Required for scope=buffer. |
geom_wkt |
str | no | — | WKT geometry (SRID 4326), POLYGON or MULTIPOLYGON only. Required for scope=area. |
detail |
bool | no | false |
scope=buffer/area only: include per-variable histogram/detail objects. |
Response
scope=basin: basin identity/geometry fields (id, hybas_id, geom_geojson, ...) plus
"signature_bands": {"<band letter>": {"label": str, "items": [{"key", "label", "value"}, ...]}}
for each requested band. Band T requires from_year and to_year (422 without them); when
requested it nests under signature_bands["T"] instead, with its own "_status" ("ok" |
"error"). flat=True: the same identity/geometry
fields plus every variable as a top-level key (no signature_bands nesting); Band T appears at
top-level key "temporal" instead.
scope=buffer / area: an entirely different shape -- a flat "variables" list (one object
per requested variable, a distribution summary aggregated across the scope's member
basins, not an average) plus "shortfall" and "caveats". See edops_schema_area.json for
a full worked example. flat, place_links are basin-only; ignored for buffer/area. Band T
on these two scopes requires from_year == to_year (a single year, not a range) -- unlike
scope=basin, Band T here explodes into one row per HYDE-epoch/LMR-year per member basin,
so a real multi-year range is a genuine large-payload risk at this scope.
All three scopes carry a top-level "meta": {"signature_version", "generated", "query"
(the request echoed back), "scope", "data_sources"}. meta["scope"] is
{"type": "containing_basin", "basin_level"} for basin; {"type", "n_units", "unit_type",
"member_ids"} for buffer; {"type", "n_units", "unit_type", "marginal_exposure"} for area.
Full variable inventory (what each band/key means): see the Codebook (/docs/codebook/).
GET /api/health
Confirm the service is running.
Response
{"status": "ok"}
Example requests
Bands A and B only — Athens
curl "https://edops.computingplace.org/api/signature?scope=basin&lat=37.97&lon=23.73&bands=AB"
Full baseline signature — Samarkand
curl "https://edops.computingplace.org/api/signature?scope=basin&lat=39.65&lon=66.98&bands=ABCDE"
With historical climate — Rome, early imperial period
curl "https://edops.computingplace.org/api/signature?scope=basin&lat=41.9&lon=12.5&bands=ABCT&from_year=1&to_year=400"
Flat mode — all fields as top-level keys
curl "https://edops.computingplace.org/api/signature?scope=basin&lat=16.8167&lon=-2.9833&bands=ABCDE&flat=true"
Buffer scope — aggregate signature within a radius
curl "https://edops.computingplace.org/api/signature?scope=buffer&lat=16.8167&lon=-2.9833&radius_km=50&bands=ABCDE"
Area scope — aggregate signature over an arbitrary polygon
curl "https://edops.computingplace.org/api/signature?scope=area&geom_wkt=POLYGON((7%2044,14%2044,14%2047,7%2047,7%2044))&bands=ABCDE"
Notes for application developers
- CORS: Cross-origin requests are allowed — call the API directly from browser JavaScript.
- No basin found: If the coordinate falls outside all known sub-basins (open ocean, ice sheet), the API returns HTTP 404.
- Response modes: By default, environmental variables are grouped under
signature_bands. Pass&flat=trueon/signatureto receive all variable values as flat top-level keys instead. - Band T availability:
_statusreflects whether the Band T mechanism ran, not whether every source had data — LMR, eVolv2k, and HYDE each have independent coverage windows, and a single query can mix available and unavailable sources. Check the per-source fields (lmr_status, the*_notefields) rather than_statusalone. See edops_schema_basin.json for a full worked example (Band T on scope=area is a different, row-exploded shape — see edops_schema_area.json instead). leveldefaults to6(BasinATLAS Level 06) for every scope. Passlevel=8explicitly for finer sub-basin resolution —scope=basinalways returns a single basin's data regardless of level, so this only affects which basin/how many member basins are resolved, not the payload's shape.- Rate limits: None enforced currently.
EDOPS is part of the Computing Place research initiative. Contact: karl.geog@gmail.com