Documentation

Heat Risk Data API

One request replaces what is otherwise six months to a year of specialist geospatial labor and reports how much to trust each number it returns.

What it is

The Heat-Risk Data API takes a set of geographic polygons and returns per-polygon heat-risk, air-quality, and vulnerability metrics, drawn from roughly fourteen distinct external data products: satellite thermal imagery, global population rasters, a European climate reanalysis service, ground-station and satellite air-quality networks, canopy-height models, and settlement classification, among others. None of it is visible to the caller. A request names the polygons to evaluate; the response returns the metrics for each.

A new project is queryable in approximately 20 to 35 minutes end to end, from initial polygon submission to a first complete set of metrics.

What comes back, per polygon, falls into three tiers. First, each raw source aggregated to the polygon: air temperature and Heat Index (max/min/mean, split into full-day, daytime, and nighttime windows), population and age structure, air quality (ground-station and satellite-model, reconciled), and the vulnerability inputs (settlement classification, tree canopy, land cover, night-time lights, relative wealth, subnational HDI, nearby health facilities). Second, processed metrics computed from those aggregates: the UTCI and WBGT thermal-comfort indices and forward-looking forecast metrics. Third, derived composites and comparisons: a warm-season land-surface-temperature composite, daily anomaly tiers grading how unusual a day is against a ten-year reference climatology, and vulnerability composites.

Responses from the main evaluation endpoint also include polygon_coverage: for twelve of the API's roughly fourteen sources, a signal reporting how well the underlying data actually resolves that specific polygon. Raster sources get a valid-area fraction, centroid-sampled weather sources get a sampling-representativeness ratio, sparse sources get a point or facility count, and the one categorical join gets a matched-region flag. Where it applies, it states how much to trust each number, for that specific polygon.

Polygons in, fourteen sources out GeoJSON polygons, an area of interest POST /v1/evaluate Heat-Risk Data API WEATHER & REANALYSIS ERA5 / ERA5-Land reanalysis (Copernicus CDS) paced, mutex-guarded CDS requests Open-Meteo ERA5 archive live REST; automatic failover for CDS and recent-day coverage LAND-SURFACE & POPULATION RASTERS LandScan population (ORNL) S3 raster Meta / WRI canopy height v2, with v1 fallback streamed /vsicurl/ range reads, quadkey COGs ESA WorldCover land cover streamed /vsicurl/ from ESA's public bucket, no local copy GHSL-SMOD settlement classification (EC JRC) S3 raster via /vsis3/ WorldPop age and sex structure mirrored COGs on S3, 20 bands per project VIIRS night-time lights (NASA) S3 raster via /vsis3/ Landsat 8/9 Collection 2 thermal (USGS / NASA) STAC search plus requester-pays COG streaming FORECAST Open-Meteo forecast live REST VECTOR & STATISTICAL Meta Relative Wealth Index CSV point-in-polygon OpenStreetMap health facilities (healthsites.io) prepared GeoJSON Global Data Lab subnational HDI spatial join AIR QUALITY CAMS air quality (via Open-Meteo) + OpenAQ stations live REST plus paced, budgeted station fetches, QC-reconciled one JSON response, per polygon 1  aggregated source values 2  processed indices (WBGT, UTCI) 3  derived composites + anomaly tiers + polygon_coverage
One request against POST /v1/evaluate queries fourteen external data products behind a single interface; the response carries heat, air-quality, and vulnerability metrics with polygon_coverage attached. Each source is shown with its access pattern. Upstream attribution and licensing requirements are handled once, centrally, and invisible to the caller.

Making a request

A request is a single POST with a JSON body: an authenticated caller, the action, and a payload naming the project and, for a new project, the polygons to evaluate.

POST https://5trhrgas69.execute-api.us-east-1.amazonaws.com/v1/evaluate
Content-Type: application/json

{
  "username": "<username>",
  "key":      "<api-key>",
  "action":   "evaluate-heat-risk",
  "payload":  {
    "project_id": "mexico-city-2024",
    "json_obj":   { "type": "FeatureCollection", "features": [ ... ] }
  }
}

The full action, request, and response reference, every action, payload field, error code, and a worked end-to-end walkthrough, is provided to accepted users alongside their credentials.

What using it replaces

The realistic alternative to this API is six months to a year of specialist geospatial labor: learning a dozen data products' access patterns, writing extraction code, and (usually skipped) building a coverage estimate. The companion post tells that story; this page is the reference.

Data validation and coverage

Each response carries the signals needed to judge how far to trust its own numbers. Coverage and validation are returned as normal fields, for twelve sources at once. The engineering stories behind these guarantees are in the companion write-up.

  • polygon_coverage on every evaluate response. Eight raster and weather sources report the fraction of a polygon's area backed by valid pixel data. For centroid-sampled ERA5 and CAMS, a resolution_adequate flag marks when the source grid is coarser than the polygon, so a small polygon still receives its point estimate with an explicit reliability flag. The four structurally sparse sources each report the signal that fits them: a point or facility count for RWI, Healthsites, and OpenAQ, and a matched-region overlap fraction for GDL subnational HDI.
  • Apportioned population is labeled. Where a polygon is smaller than a population pixel, the value is area-scaled and marked area_apportioned: true, so a partial-pixel estimate is distinguishable from a full measurement in the response.
  • Air quality is reconciled per station, per day. A ground-station reading is checked against its same-day network neighbors, falling back to the CAMS model estimate where too few neighbors exist. A station is downgraded to invalid only after three consecutive flagged days, separating a persistent sensor fault from a transient pollution event.
  • The anomaly reference period compares peaks to peaks. A day's maximum is scored against a distribution of one daily maximum per historical day, over a ±7-day window across ten years (~150 samples per day-of-year). The construction was cross-checked against an independent from-scratch implementation, agreeing on all 2,562 compared values before deployment.
  • The comparison season is derived per project. Each project's warm season comes from its own multi-year temperature climatology, wrapping the calendar-year boundary where needed; a fixed Northern-Hemisphere summer would place Lagos's real December-to-February season outside the comparison window.

A trimmed real response for one polygon, one day, showing the shape (48 reference-climatology columns per row omitted for length):

{
  "metrics": [{
    "name": "Colonia Roma", "date": "2024-07-01",
    "population": 45230,
    "day_t2m_max": 31.2, "day_hi_max": 98.4,
    "...": "48 ref_* reference-climatology columns, plus UTCI/WBGT and daytime/nighttime splits"
  }],
  "polygon_coverage": {
    "Colonia Roma": {
      "lst": {"valid_px_frac": 0.62, "below_threshold": false, "scene_date": "2025-08-14"},
      "population": {"valid_px_frac": 1.0, "below_threshold": false, "area_apportioned": false},
      "era5": {"grid_cells_spanned": 0.0007, "resolution_adequate": false,
               "polygon_area_km2": 0.6, "grid_cell_area_km2": 820.85},
      "healthsites": {"facility_count": 2, "nearest_km": 0.8},
      "rwi": {"n_points": 8, "has_data": true},
      "gdl": {"matched": true, "region_name": "MEXcty Ciudad de México",
              "overlap_frac": 0.93, "used_centroid_fallback": false},
      "cams": {"grid_cells_spanned": 0.0028, "resolution_adequate": false,
               "polygon_area_km2": 0.6, "cams_grid_cell_area_km2": 214.5},
      "...": "plus viirs, worldcover, ghsl_smod, canopy, and openaq (twelve sources in all)"
    }
  }
}
A median colonia inside one ERA5 grid cell, to scale one ERA5 grid cell 0.25° × 0.25°, about 28 km on a side a median Mexico City colonia about 785 m across, roughly 1/35 the width of the grid cell resolution_adequate: false ≈ 28 km
A median Mexico City colonia, 785 m across at its narrow side, drawn to scale inside a single 0.25° ERA5 grid cell of roughly 28 km per side. One reanalysis value covers the entire cell, so a centroid sample cannot resolve variation at the colonia's scale; for weather metrics on polygons this small, the API still returns the point estimate, but flags it with resolution_adequate: false rather than presenting it as reliable at that scale.

Neighborhood-resolution correction

The base weather grid is ERA5-Land, roughly 9 km per cell. A city neighborhood is far smaller than one cell, so the centroid sample above cannot resolve variation at the block scale, the same resolution_adequate: false case the figure just showed.

A statistical model corrects the grid air temperature for each polygon, using covariates the API already computes for every polygon: elevation, tree canopy height, impervious and built fraction, warm-season land-surface-temperature anomaly, population density, wind, and climate zone. The corrected temperature is then run back through the same heat-index, UTCI, and WBGT functions the base pipeline uses. The model corrects temperature only; it does not model the composite indices directly.

A response can carry one of four kinds of value for a polygon-day, in order of precedence: the raw grid estimate; the model-corrected estimate; a corrected estimate additionally adjusted against nearby real weather stations; or, where a station sits inside the polygon itself, that station's own observed reading, which overrides the model outright. A later value in this order can replace an earlier one, never the reverse, so a real observation is never quietly downgraded back to a modeled estimate.

Four-tier precedence order, strictly enforced TIER 1 · LAST RESORT era5_land_grid raw reanalysis grid, ~9–28 km per cell served whenever no gate has passed yet TIER 2 era5_land_downscaled model-corrected, gated per zone/target tmax 19/19 zones, tmin 15/19 zones TIER 2.5 era5_land_station _blended model + distance-weighted blend vs. nearby stations one public project today TIER 3 · ALWAYS WINS metar_station a real station sits inside the polygon overrides every modeled value A later tier can replace an earlier one for a polygon-day. Never the reverse.
The four data_source values a polygon-day can carry, strictly ordered. Real per-zone pass rates and the one project with live Tier 2.5 data are covered in the paragraphs above; full validation detail is at the model performance page.

The correction is validated per climate zone, separately for daytime and nighttime. Daytime-maximum correction passes cross-validation in all 19 zones tested. Nighttime-minimum correction passes in 15 of 19, failing in four zones spanning tropical, humid-subtropical, and hot-desert climates (Am, As, Cwa, BWh), where the raw grid value is served instead. Where a metric does not pass for a zone, the response returns the uncorrected grid value and says so.

The correction is not limited to days that have already happened. A separate near-term band (covering the most recent few days, before the historical archive catches up) and the seven-day forecast horizon are each validated on their own terms, per climate zone, and current and forecast values carry a correction under the same discipline. Its structural eligibility is reported per polygon in polygon_coverage as a downscaling entry. Some zone/band passes reflect genuine per-polygon differentiation; others clear the gate only through a flat per-zone bias adjustment, and that share grows with forecast lead time. Both count as a validated pass here; which kind applies to a given zone, band, and target is disclosed on the model performance page.

Only air temperature is corrected. Humidity, wind, and solar radiation are not, so WBGT and UTCI improve only through their temperature term and still carry the grid-scale wind and solar values. The corrected resolution varies with covariate availability: roughly 100–300 m where the fine covariates are present, degrading toward about 1 km where only coarse covariates exist, a floor rather than a fixed number.

The correction is enabled across every active project. A polygon-day carries a corrected value once its covariate context is complete and its zone's gate passes for that target. An absent or grid-tier value in the meantime is a normal, temporary state that resolves automatically as each project's daily update runs. Per-zone validation results, the global station coverage behind the station-adjusted tier, and the full methodology are at the model performance page.

Pipeline guarantees

Behavioral guarantees of the daily pipeline. The engineering stories behind them are in the companion write-up.

  • Copernicus CDS pacing. One concurrent CDS request per account is enforced by an account-wide lock applied at every call site, so no code path can exceed the upstream limit.
  • Automatic weather-provider failover. When the paced primary source is not immediately available, requests fail over to an independent provider serving the same ERA5 reanalysis, with no gap in the daily schedule. Over one reporting period, 213 of 376 daily-update invocations took this failover path and delivered on time.
  • Batched upstream requests. Daily updates batch many grid cells into each Open-Meteo request, keeping large or geographically dispersed projects inside the 900-second execution ceiling. Thermal-comfort values left incomplete by a time-constrained run are backfilled automatically on a later run.
  • Resumable, time-budgeted extraction. Raster extraction persists progress tile by tile and resumes on the next invocation, so a large project builds coverage steadily across runs.

Sustainability & architecture

The system runs entirely on serverless infrastructure, Lambda functions, an Aurora Serverless v2 database, and S3, with no dedicated servers to patch and no fixed capacity to plan around. Compute scales to zero between requests.

The cost profile follows the same shape as the architecture: the dominant operating charges are flat, per-hour infrastructure costs (the network gateway that gives the functions internet access to external data services, and the database's idle floor) while the compute that actually answers requests is a negligible fraction of the total. Nothing in the cost structure scales meaningfully with request volume.

The system is also explicitly bounded against the one way serverless costs typically escalate unexpectedly: every function has a maximum runtime, a stage-wide throttle (20 requests/second) caps total traffic regardless of endpoint, and new-project size is capped at creation (1,500 polygon features, 50 square degrees of bounding box, calibrated against real live projects), so a traffic spike or an unusually large polygon submission degrades into a clear rate-limit response rather than an open-ended bill.

The confirmed direction: non-commercial use (academic research, journalism, humanitarian response, public health practice) stays free, with attribution. The open item is commercial terms; research access is settled. See Access, limits & terms below.

Access, limits & terms

Rate limits: 300 requests/hour per authenticated user on the primary evaluation endpoint, with administrative accounts exempted; a stage-wide throttle of 20 requests/second applies across all traffic, regardless of endpoint. Authentication is via an API key, issued once at account creation and not stored or logged in plaintext afterward.

This page covers what the API does and how it's built. The full technical reference (every action, request/response shapes, error codes, and a worked end-to-end walkthrough) is provided directly to every accepted user alongside their credentials.

Account creation itself is invite-based (2026-07-12): an administrator mints a single-use invite code that expires after seven days; whoever holds it redeems it in one call and receives their API key directly, so the plaintext key is never relayed over email or seen by anyone but the account holder. Each invite carries the organization and role the new account will hold, so redeeming it places the holder into the right organization with the right permissions in that single call. A leaked code can be revoked immediately. This is closed-group by construction: a code exists only because an administrator minted one. Access still starts with an email to datascience_crisisready@harvard.edu. Pre-merge review of the mechanism caught and fixed a redemption race that could burn a code without creating an account, and re-keyed a rate limit that one bad actor could have exhausted for every code holder at once.

Organizations and roles

Every account belongs to an organization, which is the boundary for what it can reach. A role inside the organization sets what an account can do: an organization administrator manages that organization's users and can run data work on any project in the organization; a member owns and runs its own projects; a read-only account cannot change anything. A project is private by default and visible to its owner; marking a project public grants read-only access to it from any organization, which is how the public demonstration projects are shared, while a private project is never readable from outside its organization. Broader read access across an organization's members is supported but switched off by default while the service is in early access. Ownership and edit rights are separate, so an account demoted to read-only keeps the projects it owns but can no longer change them.

The access model: organization, users, roles, keys, projects ORGANIZATION the top container Users, each with a role Administrator manages people and projects key rotatable Member runs their own projects key rotatable Read-only can look, not change key rotatable Projects the organization owns project an area of interest, many polygons project an area of interest, many polygons project an area of interest, many polygons Each account authenticates with an API key; rotating it kills the old one the moment the replacement is issued. new colleague single-use invite, org + role preset joins
How access is structured. Every account belongs to an organization and carries a role; a new colleague joins through a single-use invite that already encodes their organization and role; and an API key can be rotated the moment it is suspected leaked, with no overlap window.

Self-serve data onboarding

A project starts with the core heat metrics and can be extended with further data layers without going through an administrator. One read action reports which layers a project already holds and flags whether a missing layer reflects a real data gap or a pipeline problem, so a user can tell whether an absence is on their end or ours. A second action enables any supported layer through one entry point, whether that is land surface temperature, air quality, the WMO climate reference period, population, or one of the vulnerability layers, without the user needing to know which internal pipeline produces which layer. These onboarding requests run through a shared queue with per-source limits, so a burst of new projects or layers cannot overrun the upstream data services, the same pacing discipline that keeps the daily updates inside their rate limits.

Key management and usage

An account holder can rotate their own key at any time. The previous key stops working the instant the replacement is issued, with no overlap window, so a suspected leak can be closed at once; a key can also be issued with an expiry date for time-limited access. An account can read its own current usage, meaning its consumption against the hourly rate limit and the number of projects it holds, which is the basis for the per-account cost accounting the service will add as it moves toward general availability.

Terms of use (draft; see pending note below)

Once finalized, access to this API will be granted upon issuance of an API key and subject to terms along these lines:

Permitted use. The API and the data it returns are free to use for non-commercial purposes, including academic research, journalism, humanitarian response, and public health practice. Any publication, report, or product that uses the API's output must include attribution to CrisisReady.

Commercial use. Use of the API or its output in a commercial product or service requires a separate written agreement. Contact datascience_crisisready@harvard.edu.

Upstream attribution. Several underlying data sources carry their own attribution requirements independent of these terms. Most notably, whenever this API's output is published or redistributed, the following Copernicus/ERA5 statement is required: "T2m, heat index, and the UTCI/WBGT thermal-comfort inputs derived from it are generated using Copernicus Climate Change Service (C3S) information via the ERA5 reanalysis (2026). Neither the European Commission nor ECMWF is responsible for any use that may be made of the Copernicus information or data it contains." Complying with these requirements is a condition of use. Full per-source attribution and licensing notes for the rest of the fourteen external data products are available on request to datascience_crisisready@harvard.edu.

No warranty. The API and its output are provided "as is," without warranty of accuracy, completeness, or availability. CrisisReady is not liable for decisions made based on this data.

Changes. The API is in early access (see Versioning & support, below); these terms and the service's rate limits and pricing may change, with advance notice to existing users before changes take effect against their existing usage.

Pending: exact license wording (direction confirmed: free for non-commercial/research/humanitarian use with attribution, commercial by direct conversation) is drafted but awaiting real legal review before this is final.

Citation

A methods paper describing this system's approach is in preparation, and the underlying work will be registered with Harvard Dataverse for a formal, citable DOI.

Citation forthcoming. DOI registration is not yet complete.

Versioning & support

The API is currently at v1.36.0; the URL path carries the major version (/v1/evaluate). The API is in early access (see Access, limits & terms above for what may still change). The intent, not yet a fully ratified policy, is that testers using the API before general availability would get at least 30 days' notice before any change takes effect against their existing usage, and that a breaking change would ship under a new version path rather than alter /v1/'s existing behavior. A fuller, formally adopted deprecation policy is deferred until there's an actual /v2/ to write one against.

For questions about coverage, licensing for a specific use case, or integration support, contact datascience_crisisready@harvard.edu.