Skip to content

API Guide

EDOPS — the Environmental Dimensions of Place Service — generates structured environmental signatures for a coordinate, a buffer/basin-ring scope, or a historical polity's territory. 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
A full worked example payload: edops_schema.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 environmental signature for a coordinate.

Parameter Type Required Default Description
lat float (-90 to 90) yes Latitude, decimal degrees, in [-90, 90].
lon float (-180 to 180) yes Longitude, decimal degrees, in [-180, 180].
bands str no ABCDE Which profile groups to include, e.g. "ABCDE" or "ABCDET".
level int no 8 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 profile_groups; Band T temporal data appears at key "temporal" rather than in profile_groups.

Response

Default (flat=False): basin identity/geometry fields (id, hybas_id, geom_geojson, ...) plus
"profile_groups": {"<band letter>": {"label": str, "items": [{"key", "label", "value"}, ...]}}
for each requested band. Band T (if requested) nests under profile_groups["T"] instead, with
its own "_status" ("ok" | "not_requested" | "error").

flat=True: the same identity/geometry fields plus every variable as a top-level key (no
profile_groups nesting); Band T appears at top-level key "temporal" instead.

Full variable inventory (what each band/key means): see the Codebook (/docs/codebook/).

GET /api/area

Return an areal environmental signature for a named Cliopatria polity.

Parameter Type Required Default Description
polity str yes Cliopatria polity name, exact match (e.g. "Northern Song").
year int yes Resolver year CE — selects the polity boundary active at this year.
level int no 6 Basin hierarchy level: 6 or 8.
bands str no ABCDET Band letters to compute, e.g. "ABCDET". Add T to include Band T (requires from_year and to_year).
from_year int no Band T span start, year CE. Required when T is in bands.
to_year int no Band T span end, year CE. Required when T is in bands.
detail bool no false If true, include per-variable histogram objects in the response.

Response

Same profile_groups envelope as GET /api/signature, but each value is a distribution across
the polity's member basins, not an average (see engine.py). Adds:
  "resolver": {"type": "polity", "polity", "polity_id", "fromyear", "toyear", "year"}
  "member_ids": [hybas_id, ...]
  "band_t_span": {"from_year", "to_year"}   -- present only when Band T requested
detail=true adds a per-variable "distribution" histogram object.

Full variable inventory: see the Codebook (/docs/codebook/).

GET /api/areas

Areal signature dispatcher — resolves to a set of member basins by scope, then aggregates their signature as a distribution (not an average). scope is confusingly named "area" alongside GET /api/area, but the four scope kinds are not all areas in the geometric sense: single_basin and polity are bounded regions, buffer is an arbitrary radius, and basin_ring is a topological set of basins, not a shape.

Parameter Type Required Default Description
scope str yes Spatial scope of the query: 'buffer', 'single_basin', 'polity', or 'basin_ring'. Determines which of lat/lon/radius_km/polity/year are required (see each param's own description) and the shape of the scope block in the response.
lat float (-90 to 90) no WGS-84 latitude, decimal degrees. Required for scope=buffer, single_basin, basin_ring.
lon float (-180 to 180) no WGS-84 longitude, decimal degrees. Required for scope=buffer, single_basin, basin_ring.
radius_km float no Buffer radius in km. Required for scope=buffer.
polity str no Cliopatria polity name, exact match (e.g. "Northern Song"). Required for scope=polity.
year int no Resolver year CE — selects the polity boundary active at this year. Required for scope=polity.
level int no 6 Basin hierarchy level: 6 or 8.
bands str no ABCDE Band letters to compute, e.g. "ABCDE" or "ABCDET". Add T to include Band T (requires from_year and to_year).
from_year int no Band T span start, year CE. Required when T is in bands.
to_year int no Band T span end, year CE. Required when T is in bands.
detail bool no false If true, include per-variable histogram objects in the response.

Response

Same areal-signature envelope as GET /api/area (profile_groups as distributions across member
basins, not averages), plus a `scope` block whose shape depends on `scope`. detail=true adds
per-variable histogram objects. Full variable inventory: 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?lat=37.97&lon=23.73&bands=AB"

Full baseline signature — Samarkand

curl "https://edops.computingplace.org/api/signature?lat=39.65&lon=66.98&bands=ABCDE"

With historical climate — Rome, early imperial period

curl "https://edops.computingplace.org/api/signature?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?lat=16.8167&lon=-2.9833&bands=ABCDE&flat=true"

Areal signature for a polity — Northern Song at 1080 CE

curl "https://edops.computingplace.org/api/area?polity=Northern%20Song&year=1080&bands=ABCDE"

Buffer scope via the scope dispatcher

curl "https://edops.computingplace.org/api/areas?scope=buffer&lat=16.8167&lon=-2.9833&radius_km=100&bands=ABCDE"

Notes for application developers

  • /area vs /areas: not a clean singular/plural pair. /area is polity-only. /areas dispatches on scope, and its four resolver types aren't all "areas" in the geometric sense — single_basin and polity are bounded regions, buffer is an arbitrary radius, and basin_ring is a topological set of neighboring basins, not a shape at all. "Area" in EDOPS currently covers several distinct things; not yet normalized to one term.
  • 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 profile_groups. Pass &flat=true on /signature to receive all variable values as flat top-level keys instead.
  • Band T availability: _status reflects 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 *_note fields) rather than _status alone. See edops_schema.json for a full worked example.
  • level default varies by endpoint, deliberately left as-is/signature defaults to 8; /area and /areas default to 6. /signature always returns a single basin's data regardless of level, so this only affects resolution, not payload shape or size. Pass it explicitly if your use case depends on which sub-basin resolution you get.
  • Rate limits: None enforced currently.

EDOPS is part of the Computing Place research initiative. Contact: karl.geog@gmail.com