{"basePath":"/","consumes":["application/json"],"definitions":{"BarResponse":{"properties":{"basin":{"example":"limpopo","type":"string"},"trace":{"$ref":"#/definitions/BarTrace"}},"type":"object"},"BarTrace":{"properties":{"name":{"type":"string"},"type":{"example":"bar","type":"string"},"x":{"items":{"type":"object"},"type":"array"},"y":{"items":{"type":"number"},"type":"array"}},"type":"object"},"BarTraceKM3":{"properties":{"name":{"example":"Rainfall","type":"string"},"type":{"example":"bar","type":"string"},"x":{"example":[2018,2019,2020],"items":{"type":"integer"},"type":"array"},"y":{"example":[541.2,612.8,488.0],"items":{"type":"number"},"type":"array"}},"type":"object"},"BasinDetail":{"allOf":[{"$ref":"#/definitions/BasinSummary"},{"properties":{"metrics":{"description":"`metric_code` values that have at least one observation in this basin.","example":["RAIN_MM","TOTAL_ET_MM","WATER_YIELD_MM"],"items":{"type":"string"},"type":"array"}},"type":"object"}]},"BasinInsights":{"properties":{"basin":{"example":"limpopo","type":"string"},"basin_area_km2":{"example":414055,"type":"integer"},"environmental_stress_pct":{"description":"Long-term mean of EWS = 100 \u00d7 utilized_flow / (exploitable \u2212 reserved).","example":80.0,"type":"number"},"future_use_bmc":{"description":"Long-term mean utilizable outflow (1 BMC = 1 km\u00b3/yr).","example":2.55,"type":"number"},"per_capita_litres_per_day":{"description":"Convenience conversion: m\u00b3/yr \u00d7 1000 \u00f7 365.","example":1719.5,"type":"number"},"per_capita_m3_per_year":{"description":"Long-term mean exploitable_water / population.","example":627.6,"type":"number"},"population":{"description":"Most recent year on file.","example":14739624,"type":"integer"},"population_year":{"example":2025,"type":"integer"},"window":{"description":"`{start_year, end_year}` over which the means are computed.","type":"object"}},"type":"object"},"BasinList":{"properties":{"basins":{"items":{"$ref":"#/definitions/BasinSummary"},"type":"array"},"count":{"description":"Number of basins in `basins`.","example":1,"type":"integer"}},"type":"object"},"BasinSummary":{"properties":{"basin_code":{"description":"Stable, lower-case identifier used throughout the API.","example":"limpopo","type":"string"},"basin_name":{"description":"Human-readable name.","example":"Limpopo River Basin","type":"string"},"metric_count":{"description":"Distinct metric codes observed for this basin.","example":16,"type":"integer"},"regions":{"description":"Count of HydroBASINS sub-basins loaded for this basin.","example":3161,"type":"integer"},"year_max":{"description":"Latest calendar year with at least one observation.","example":2024,"type":"integer"},"year_min":{"description":"Earliest calendar year with at least one observation.","example":2003,"type":"integer"}},"type":"object"},"ChangeAnomalyResponse":{"properties":{"basin":{"example":"limpopo","type":"string"},"metric":{"example":"rainfall","type":"string"},"z":{"allOf":[{"$ref":"#/definitions/XYSeries"}],"description":"`unit: \"z\"` \u2014 standardised anomaly."}},"type":"object"},"ChangePackResponse":{"properties":{"anomaly":{"description":"Object keyed by metric \u2192 {x, y, unit:'z'}.","type":"object"},"basin":{"example":"limpopo","type":"string"},"series":{"description":"Object keyed by metric \u2192 {x, y, unit}.","type":"object"}},"type":"object"},"ChangeSeriesResponse":{"properties":{"basin":{"example":"limpopo","type":"string"},"metric":{"example":"rainfall","type":"string"},"series":{"$ref":"#/definitions/XYSeries"}},"type":"object"},"ETFractionsResponse":{"properties":{"agriculture":{"items":{"type":"object"},"type":"array"},"basin":{"example":"limpopo","type":"string"},"has_agriculture":{"example":true,"type":"boolean"},"has_irrigated":{"example":true,"type":"boolean"},"irrigated":{"items":{"type":"object"},"type":"array"},"managed":{"description":"Annual managed-ET fraction (%).","items":{"type":"object"},"type":"array"}},"type":"object"},"GeoJoinDiagnostic":{"properties":{"basin":{"example":"limpopo","type":"string"},"db_keys_missing_in_geo":{"description":"Keys present in DB but missing from GeoJSON.","example":[],"items":{"type":"string"},"type":"array"},"db_rows_month1":{"example":3155,"type":"integer"},"geo_features":{"example":3161,"type":"integer"},"geo_keys_missing_in_db":{"description":"Keys present in GeoJSON but missing from DB.","example":["1101521290"],"items":{"type":"string"},"type":"array"},"join_key":{"example":"region_code","type":"string"}},"type":"object"},"Geometry":{"properties":{"coordinates":{"description":"GeoJSON coordinates array","type":"object"},"type":{"example":"MultiPolygon","type":"string"}},"type":"object"},"HeatmapTrace":{"properties":{"name":{"example":"m3_per_capita","type":"string"},"type":{"example":"heatmap","type":"string"},"x":{"example":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"items":{"type":"string"},"type":"array"},"y":{"example":[2003,2004,2005],"items":{"type":"integer"},"type":"array"},"z":{"items":{"items":{"type":"number"},"type":"array"},"type":"array"}},"type":"object"},"LandUseBreakdown":{"properties":{"basin":{"example":"limpopo","type":"string"},"fields":{"description":"`{value_field, units}` \u2014 which value the Plotly bundle charts.","type":"object"},"plotly":{"description":"Plotly bundles (`pie`, `bar`, or both) ready for `Plotly.newPlot`.","type":"object"},"rows":{"items":{"$ref":"#/definitions/LandUseRow"},"type":"array"}},"type":"object"},"LandUsePart":{"properties":{"luw_category":{"example":"Utilized Landuse","type":"string"},"pct":{"example":76.95,"type":"number"},"pixel_count":{"example":310320,"type":"integer"}},"type":"object"},"LandUseRow":{"properties":{"area_km2":{"example":62705.55,"type":"number"},"class_key":{"example":"protected_landuse","type":"string"},"class_label":{"example":"Protected Landuse","type":"string"},"percent_of_basin":{"example":15.55,"type":"number"}},"type":"object"},"LandUseSummary":{"properties":{"basin":{"example":"limpopo","type":"string"},"mode":{"example":"average","type":"string"},"parts":{"items":{"$ref":"#/definitions/LandUsePart"},"type":"array"},"year":{"example":2024,"type":"integer"}},"type":"object"},"Metric":{"properties":{"family":{"description":"Which group of endpoints accept this key.","example":"monthly","type":"string"},"key":{"description":"URL key used in path parameters (kebab-case).","example":"blue-et","type":"string"},"label":{"description":"Human-readable display label.","example":"Blue (incremental) ET","type":"string"},"metric_code":{"description":"Stable identifier as stored in `dim_metric.metric_code`.","example":"BLUE_ET_MM","type":"string"},"notes":{"description":"Optional one-line description.","type":"string"},"unit":{"description":"Physical unit of the values.","example":"mm","type":"string"}},"type":"object"},"MetricList":{"properties":{"count":{"example":5,"type":"integer"},"metrics":{"items":{"$ref":"#/definitions/Metric"},"type":"array"}},"type":"object"},"MonthlyValues":{"properties":{"agg":{"example":"climatology","type":"string"},"basin":{"example":"limpopo","type":"string"},"metric":{"example":"water-yield","type":"string"},"month":{"description":"1..12","example":1,"type":"integer"},"stats":{"example":{"count":312,"max":132.0,"mean":15.3,"min":-77.7},"type":"object"},"unit":{"example":"mm","type":"string"},"values":{"example":{"1100012590":48.73},"type":"object"}},"type":"object"},"PerCapitaResponse":{"properties":{"basin":{"example":"limpopo","type":"string"},"heatmap":{"$ref":"#/definitions/HeatmapTrace"},"mode":{"example":"heatmap","type":"string"},"trace":{"$ref":"#/definitions/BarTrace"},"year":{"example":2021,"type":"integer"}},"type":"object"},"RegionFeature":{"properties":{"geometry":{"$ref":"#/definitions/Geometry"},"properties":{"$ref":"#/definitions/RegionProperties"},"type":{"example":"Feature","type":"string"}},"type":"object"},"RegionProperties":{"properties":{"HYBAS_ID":{"example":1100012590,"type":"integer"},"basin_code":{"example":"limpopo","type":"string"},"hybas_id":{"example":1100012590,"type":"integer"},"region_code":{"example":"1100012590","type":"string"}},"type":"object"},"RegionsFeatureCollection":{"properties":{"features":{"items":{"$ref":"#/definitions/RegionFeature"},"type":"array"},"type":{"example":"FeatureCollection","type":"string"}},"type":"object"},"SunburstTrace":{"properties":{"branchvalues":{"example":"total","type":"string"},"insidetextorientation":{"example":"horizontal","type":"string"},"labels":{"items":{"type":"string"},"type":"array"},"parents":{"items":{"type":"string"},"type":"array"},"text":{"items":{"type":"string"},"type":"array"},"textinfo":{"example":"label+text+percent parent","type":"string"},"type":{"example":"sunburst","type":"string"},"values":{"items":{"type":"number"},"type":"array"}},"type":"object"},"TimeWindow":{"properties":{"end_year":{"example":2024,"type":"integer"},"start_year":{"example":2003,"type":"integer"}},"type":"object"},"WaterBalanceAnnual":{"properties":{"basin":{"example":"limpopo","type":"string"},"outflow":{"$ref":"#/definitions/BarTraceKM3"},"rainfall":{"$ref":"#/definitions/BarTraceKM3"},"total_et":{"$ref":"#/definitions/BarTraceKM3"},"window":{"$ref":"#/definitions/TimeWindow"}},"type":"object"},"WaterBalanceSunburst":{"properties":{"aggregation":{"example":"mean","type":"string"},"basin":{"example":"limpopo","type":"string"},"metrics":{"description":"Headline numbers: rainfall_km3, total_et_km3, exploitable_km3, utilizable_km3","type":"object"},"title":{"example":"Limpopo Basin 2003\u20132024","type":"string"},"trace":{"$ref":"#/definitions/SunburstTrace"},"window":{"$ref":"#/definitions/TimeWindow"}},"type":"object"},"WaterCopilotMonthlyResponse":{"properties":{"basin":{"type":"string"},"metric":{"type":"string"},"month":{"type":"integer"},"provenance":{"type":"object"},"stats":{"type":"object"},"subtitle":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"},"values":{"type":"object"}},"type":"object"},"WaterCopilotOverviewResponse":{"properties":{"basin":{"example":"limpopo","type":"string"},"chart_url":{"example":"/v1/temp-files/copilot-limpopo-overview-\u2026png","type":"string"},"markdown":{"type":"string"},"provenance":{"type":"object"},"stats":{"type":"object"},"subtitle":{"example":"mean annual, km\u00b3","type":"string"},"summary":{"type":"string"},"title":{"example":"Limpopo Basin overview, 2003-2024","type":"string"}},"type":"object"},"WaterCopilotWAResponse":{"properties":{"basin":{"type":"string"},"chart_url":{"type":"string"},"markdown":{"type":"string"},"provenance":{"type":"object"},"stats":{"type":"object"},"subtitle":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"WaterCopilotWBResponse":{"properties":{"basin":{"type":"string"},"chart_url":{"type":"string"},"markdown":{"type":"string"},"provenance":{"type":"object"},"stats":{"type":"object"},"subtitle":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"WaterYieldFeatureCollection":{"properties":{"basin":{"example":"limpopo","type":"string"},"features":{"type":"object"},"stats":{"$ref":"#/definitions/WaterYieldStats"},"type":{"example":"FeatureCollection","type":"string"},"unit":{"example":"mm/year","type":"string"},"year":{"example":"2018","type":"string"}},"type":"object"},"WaterYieldStats":{"properties":{"count":{"example":3155,"type":"integer"},"max":{"type":"number"},"mean":{"type":"number"},"median":{"type":"number"},"min":{"type":"number"},"p10":{"type":"number"},"p90":{"type":"number"},"unit":{"example":"mm/year","type":"string"},"year":{"example":"2021","type":"string"}},"type":"object"},"WaterYieldValues":{"properties":{"basin":{"example":"limpopo","type":"string"},"stats":{"$ref":"#/definitions/WaterYieldStats"},"unit":{"example":"mm/year","type":"string"},"values":{"example":{"1100012590":48.73},"type":"object"},"year":{"example":"2021","type":"string"}},"type":"object"},"WaterYieldYears":{"properties":{"basin":{"example":"limpopo","type":"string"},"supports":{"example":["year","average"],"items":{"type":"string"},"type":"array"},"years":{"example":[2003,2004,2005],"items":{"type":"integer"},"type":"array"}},"type":"object"},"XYSeries":{"properties":{"unit":{"example":"km\u00b3/yr","type":"string"},"x":{"example":[2018,2019,2020],"items":{"type":"integer"},"type":"array"},"y":{"example":[12.3,15.8,10.1],"items":{"type":"number"},"type":"array"}},"type":"object"}},"info":{"description":"Basin-scale water accounting, served as a REST API.\n\nBuilt on the **IWMI Water Accounting Plus (WA+)** framework \u2014 a basin-scale water-resources accounting methodology that combines satellite remote sensing (evapotranspiration, rainfall, land cover) with hydrological modelling and field data to produce a closed-form water balance for an entire basin.\n\n### Two API surfaces\n\n* **`/v1/basins/{basin}/\u2026`** \u2014 dashboard-shaped endpoints used by IWMI Digital Twin and basin portals. Returns the precise JSON shape the dashboards expect (Plotly-ready traces, GeoJSON, key-metric blocks).\n* **`/v1/watercopilot/basins/{basin}/\u2026`** \u2014 endpoints designed for LLM agents and chatbots. Returns server-rendered chart images plus compact JSON, so a model can answer water-accounting questions without paging in large numeric arrays into conversation context.\n\n### Basin model\n\nEvery endpoint that operates on a single basin nests under `/v1/basins/{basin}/\u2026`. Call `GET /v1/basins` to discover which basins are loaded. Unknown basins return **`404 Not Found`** with an RFC 7807 problem-details body listing the valid codes.\n\n### Units, sign convention, time\n\n* Depths are millimetres (mm); volumes are cubic kilometres (km\u00b3); fractions and percentages of the basin area in percent (%).\n* Years are calendar years (CE); months are 1\u201312; dates use ISO-8601 where applicable.\n* All values are basin-aggregated unless the endpoint name or response field indicates a sub-basin (HydroBASINS region).\n\n### Errors \u2014 RFC 7807\n\nEvery non-2xx response is an `application/problem+json` body:\n\n```json\n{\n  \"type\":     \"https://api.wateraccounting.iwmi.org/problems/basin-not-found\",\n  \"title\":    \"Basin not found\",\n  \"status\":   404,\n  \"detail\":   \"Unknown basin code 'nile'.\",\n  \"instance\": \"/v1/basins/nile\",\n  \"valid_basins\": [\"limpopo\"]\n}\n```\n\nThe `type` URL is the stable contract \u2014 clients should switch on the slug after `/problems/`.\n\n### Caching\n\nRead endpoints set `Cache-Control: public, max-age=3600, stale-while-revalidate=86400` and a strong `ETag`. Clients that send `If-None-Match` will receive `304 Not Modified` for unchanged content.\n\n### HTTP status codes\n\n* **`200 OK`** \u2014 request succeeded, body contains data\n* **`204 No Content`** \u2014 valid request, but the data set is empty\n* **`304 Not Modified`** \u2014 client's `If-None-Match` matched current ETag\n* **`400 Bad Request`** \u2014 malformed parameter\n* **`404 Not Found`** \u2014 unknown resource (basin / year / metric)\n* **`422 Unprocessable Entity`** \u2014 semantically invalid combination (e.g. `start_year > end_year`)\n* **`500 Internal Server Error`** \u2014 unexpected server-side failure\n","license":{"name":"MIT","url":"https://opensource.org/licenses/MIT"},"title":"IWMI Water-Accounting Platform API","version":"3.0.0","x-logo":{"altText":"IWMI","backgroundColor":"#ffffff","href":"/","url":"/static/img/iwmi-logo.svg"}},"paths":{"/v1/basins":{"get":{"description":"List every basin loaded into the warehouse.\n\nUse this as the first call when scripting against the API for an\nunfamiliar basin \u2014 every other ``/v1/basins/{basin}/\u2026`` endpoint\nvalidates against this list and 404s on unknown codes.\n\nReturns ``count: 0`` and an empty list on a fresh deployment before\n``make populate`` has run.","operationId":"listBasins","responses":{"200":{"description":"Basin list","schema":{"$ref":"#/definitions/BasinList"}}},"summary":"List every basin loaded into the warehouse.","tags":["Basins"]}},"/v1/basins/{basin}":{"get":{"description":"Metadata + available metrics for one basin.\n\nUsed to verify a basin exists and to discover which `metric` values\ncan be passed to downstream endpoints (e.g. monthly climatology or\nchange analysis).\n\nReturns **404 Not Found** as an RFC 7807 problem-details body if the\n`basin` path parameter does not match any row in `dim_basin`.","operationId":"getBasin","parameters":[{"default":"limpopo","description":"Basin short code (case-insensitive). Example: `limpopo`.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"}],"responses":{"200":{"description":"Basin detail","schema":{"$ref":"#/definitions/BasinDetail"}},"404":{"description":"Unknown basin (RFC 7807 problem+json with `valid_basins`)."}},"summary":"Metadata + available metrics for one basin.","tags":["Basins"]}},"/v1/basins/{basin}/change/anomaly":{"get":{"description":"Standardised anomaly (z-score) of one indicator's annual series.\n\nFor each year:\n\n```\nz[year] = (value[year] \u2212 mean(values)) / stdev(values)\n```\n\nUnitless and centred on zero. Pair with `getBasinChangeSeries` to\nproduce the canonical *left = absolute / right = z-score* layout.","operationId":"getBasinChangeAnomaly","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"},{"default":"water-yield","description":"Same catalogue as `getBasinChangeSeries`.","enum":["rainfall","outflow","water-yield","utilizable-outflow","utilized-flow","total-et"],"example":"water-yield","in":"query","name":"metric","required":true,"type":"string"},{"default":2003,"description":"Inclusive window lower bound.","in":"query","name":"start_year","type":"integer"},{"default":2024,"description":"Inclusive window upper bound.","in":"query","name":"end_year","type":"integer"}],"responses":{"200":{"description":"Anomaly response","schema":{"$ref":"#/definitions/ChangeAnomalyResponse"}},"204":{"description":"No data in window."},"400":{"description":"Unsupported metric."},"404":{"description":"Unknown basin."},"422":{"description":"Invalid window."}},"summary":"Standardised anomaly (z-score) of one indicator's annual series.","tags":["Change Analysis"]}},"/v1/basins/{basin}/change/pack":{"get":{"description":"Five-indicator bundle: absolute series + z-scores in one call.\n\nIndicators (fixed): **rainfall, outflow, utilizable-outflow,\nutilized-flow, total-et**. Together they decompose the basin balance\ninto supply / consumption / residual.","operationId":"getBasinChangePack","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"},{"default":2003,"description":"Inclusive window lower bound.","in":"query","name":"start_year","type":"integer"},{"default":2024,"description":"Inclusive window upper bound.","in":"query","name":"end_year","type":"integer"}],"responses":{"200":{"description":"Pack response","schema":{"$ref":"#/definitions/ChangePackResponse"}},"204":{"description":"No data in window."},"404":{"description":"Unknown basin."},"422":{"description":"Invalid window."}},"summary":"Five-indicator bundle: absolute series + z-scores in one call.","tags":["Change Analysis"]}},"/v1/basins/{basin}/change/series":{"get":{"description":"Annual time-series of one indicator (km\u00b3/yr).\n\nThe *left-hand chart* in a typical change-analysis panel \u2014 the\ncompanion of `getBasinChangeAnomaly`, which returns the same series\nas z-scores.\n\n### Supported metric keys\n\n| `metric`              | Source expression                      |\n|-----------------------|----------------------------------------|\n| `rainfall`            | `precipitation_km3`                    |\n| `outflow`             | `outflow_km3`                          |\n| `water-yield`         | alias of `outflow`                     |\n| `utilizable-outflow`  | `utilizable_outflow_km3`               |\n| `utilized-flow`       | `utilized_flow_km3`                    |\n| `total-et`            | `blue_et_km3 + green_et_km3`           |","operationId":"getBasinChangeSeries","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"},{"default":"water-yield","description":"One of the supported keys (see description).","enum":["rainfall","outflow","water-yield","utilizable-outflow","utilized-flow","total-et"],"example":"water-yield","in":"query","name":"metric","required":true,"type":"string"},{"default":2003,"description":"Inclusive window lower bound.","in":"query","name":"start_year","type":"integer"},{"default":2024,"description":"Inclusive window upper bound.","in":"query","name":"end_year","type":"integer"}],"responses":{"200":{"description":"Series response","schema":{"$ref":"#/definitions/ChangeSeriesResponse"}},"204":{"description":"No data in window."},"400":{"description":"Unsupported metric."},"404":{"description":"Unknown basin."},"422":{"description":"Invalid window."}},"summary":"Annual time-series of one indicator (km\u00b3/yr).","tags":["Change Analysis"]}},"/v1/basins/{basin}/insights":{"get":{"description":"Headline at-a-glance figures for the basin overview.\n\nBundles five summary numbers into one call so the overview\nUI doesn't have to fan out across four endpoints:\n\n| Field                          | Source                                                    |\n|--------------------------------|-----------------------------------------------------------|\n| `basin_area_km2`               | `SUM(region_area_km2.area_km2)` (sentinel basin total)    |\n| `population`                   | latest `mart_basin_population_yearly.population`          |\n| `per_capita_m3_per_year`       | mean of exploitable_water_km3 \u00d7 10\u2079 \u00f7 population          |\n| `per_capita_litres_per_day`    | per_capita_m3_per_year \u00d7 1000 \u00f7 365                       |\n| `environmental_stress_pct`     | mean of 100 \u00d7 utilized / (exploitable \u2212 reserved)         |\n| `future_use_bmc`               | mean of utilizable_outflow_km3 (1 BMC = 1 km\u00b3)            |","operationId":"getBasinInsights","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"}],"responses":{"200":{"description":"At-a-glance figures","schema":{"$ref":"#/definitions/BasinInsights"}},"204":{"description":"No data on file for basin."},"404":{"description":"Unknown basin (RFC 7807)."}},"summary":"Headline at-a-glance figures for the basin overview.","tags":["Basins"]}},"/v1/basins/{basin}/land-use/breakdown":{"get":{"description":"Basin-level WA+ class breakdown with **Plotly-ready chart bundles**.\n\nSame underlying data as `getBasinLandUseSummary`, plus pre-built Plotly\n`pie` and `bar` bundles for direct embedding in dashboards.\n\nClass order is **fixed** \u2014 Protected \u2192 Utilized \u2192 Modified \u2192 Managed \u2014\nso the colour mapping stays stable across years and basins.","operationId":"getBasinLandUseBreakdown","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"},{"default":"percent","description":"Chart this value \u2014 `percent` (default) or `area`.","enum":["percent","area"],"in":"query","name":"value","type":"string"},{"default":"both","description":"Plotly bundle to return \u2014 `pie`, `bar`, or `both`.","enum":["pie","bar","both"],"in":"query","name":"chart","type":"string"},{"default":2,"description":"Decimal places for rounding (default 2).","in":"query","name":"decimals","type":"integer"}],"responses":{"200":{"description":"Land-use breakdown + Plotly bundles","schema":{"$ref":"#/definitions/LandUseBreakdown"}},"204":{"description":"Basin has no land-use rows loaded."},"404":{"description":"Unknown basin."}},"summary":"Basin-level WA+ class breakdown with **Plotly-ready chart bundles**.","tags":["Land Use"]}},"/v1/basins/{basin}/land-use/summary":{"get":{"description":"WA+ land-use class breakdown \u2014 single year or long-term average.\n\n### The four WA+ LU_WA classes\n\n| Class                | Where it sits in the water budget                          |\n|----------------------|------------------------------------------------------------|\n| Protected Landuse    | Pristine ecosystems \u2014 green ET only                        |\n| Utilized Landuse     | Lightly-used natural cover (rangelands) \u2014 green ET         |\n| Modified Landuse     | Rainfed agriculture, plantations \u2014 green ET, human-managed |\n| Managed Landuse      | Irrigated agriculture + urban \u2014 adds **blue ET**           |\n\nCompanion endpoint: `getBasinLandUseBreakdown` for the Plotly-ready\npie/bar bundles.","operationId":"getBasinLandUseSummary","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"},{"default":"average","description":"`average` (default) or `year`.","enum":["year","average"],"in":"query","name":"mode","type":"string"},{"default":2024,"description":"Required when `mode=year`.","in":"query","name":"year","type":"integer"}],"responses":{"200":{"description":"Donut parts","schema":{"$ref":"#/definitions/LandUseSummary"}},"400":{"description":"`mode=year` without `year` parameter."},"404":{"description":"Unknown basin."}},"summary":"WA+ land-use class breakdown \u2014 single year or long-term average.","tags":["Land Use"]}},"/v1/basins/{basin}/monthly/{metric}/{month}":{"get":{"description":"Sub-basin choropleth for one (or many) calendar months.\n\nReturns the climatological value of `metric` for a single month, by\nHydroBASINS sub-basin, in one of five output formats. *Climatology*\nmeans the same month averaged across all loaded years \u2014 the response\nisolates the seasonal cycle from inter-annual variability.\n\n### Formats (`?format=`)\n\n| format     | Body                                                                                       |\n|------------|--------------------------------------------------------------------------------------------|\n| `geojson`  | FeatureCollection; each feature has `properties.value` (mm).                               |\n| `image`    | PNG bytes (`Content-Type: image/png`). Tweak with `vmin`/`vmax`/`cmap`.                    |\n| `url`      | `{url, ...}` \u2014 PNG saved to disk, return short-lived URL via `/v1/temp-files/{fname}`.     |\n| `markdown` | `{url, markdown, ...}` \u2014 same plus a ready-to-paste `![title](url)` snippet.               |\n| `csv`      | CSV text (`region_code,month,value_mm`).                                                   |\n\n### Collage\n\nSet `collage=true` to render the same metric for several months\nside-by-side. The `{month}` path segment is **ignored** in collage\nmode \u2014 use the `?months=` query parameter (e.g. `1,4,7,10` or `all`)\nto pick which months. Collage works only with `format=image`, `url`,\nor `markdown`.\n\n### Companion endpoint\n\n`getBasinMonthlyValues` \u2014 values-only payload without geometry, for\nwhen the client already has the polygons cached.","operationId":"getBasinMonthlyChoropleth","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"},{"default":"water-yield","description":"Metric URL key. See `GET /v1/metrics`.","example":"water-yield","in":"path","name":"metric","required":true,"type":"string"},{"default":1,"description":"Calendar month 1\u201312 (ignored when `collage=true`).","example":1,"in":"path","name":"month","required":true,"type":"integer"},{"default":"geojson","description":"Response format \u2014 see description.","enum":["geojson","image","url","markdown","csv"],"in":"query","name":"format","type":"string"},{"default":false,"description":"`true` to render multiple months side-by-side.","in":"query","name":"collage","type":"string"},{"description":"Comma list `1,4,7,10` or `all` \u2014 only with `collage=true`.","in":"query","name":"months","type":"string"},{"description":"Colour-scale minimum (mm).","in":"query","name":"vmin","type":"number"},{"description":"Colour-scale maximum (mm).","in":"query","name":"vmax","type":"number"},{"default":"viridis","description":"Matplotlib colormap. Default `viridis`.","in":"query","name":"cmap","type":"string"},{"default":"db","description":"Polygon source. `db` (default) or `file`.","enum":["db","file"],"in":"query","name":"source","type":"string"}],"produces":["application/json","image/png","text/csv"],"responses":{"200":{"description":"Successful response in the chosen format."},"400":{"description":"Unsupported metric, bad month, or invalid collage format."},"404":{"description":"Unknown basin."}},"summary":"Sub-basin choropleth for one (or many) calendar months.","tags":["Monthly Climatology"]}},"/v1/basins/{basin}/monthly/{metric}/{month}/values":{"get":{"description":"Per-sub-basin monthly values (`{region_code: value_mm}`).\n\nSame data as the choropleth endpoint, but **just the values** \u2014 no\npolygons, no rendering. Pair with one polygon load from\n`getBasinRegions` and join client-side.\n\nThe underlying data is a **month-of-year climatology** (one value\nper sub-basin \u00b7 metric \u00b7 month), so this returns that climatological\nvalue for the requested month \u2014 there is no year dimension.","operationId":"getBasinMonthlyValues","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"},{"default":"water-yield","description":"Metric URL key. See `GET /v1/metrics`.","example":"water-yield","in":"path","name":"metric","required":true,"type":"string"},{"default":1,"description":"Calendar month 1\u201312.","example":1,"in":"path","name":"month","required":true,"type":"integer"}],"responses":{"200":{"description":"Values + stats","schema":{"$ref":"#/definitions/MonthlyValues"}},"204":{"description":"No data for query."},"400":{"description":"Unsupported metric or bad month."},"404":{"description":"Unknown basin."}},"summary":"Per-sub-basin monthly values (`{region_code: value_mm}`).","tags":["Monthly Climatology"]}},"/v1/basins/{basin}/regions":{"get":{"description":"Sub-basin polygons for one basin as a GeoJSON `FeatureCollection`.\n\nPure geometry \u2014 no metric values are embedded. Pair with one of the\n`\u2026/values` endpoints for the choropleth fill.\n\nThe polygons come from `vw_region_geom_area` (joined with the\n`vw_region_hybas` shim so each feature carries the HydroBASINS ID as\nwell as the API's `region_code`).","operationId":"getBasinRegions","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"}],"responses":{"200":{"description":"Sub-basin FeatureCollection","schema":{"$ref":"#/definitions/RegionsFeatureCollection"}},"204":{"description":"Basin has no region geometry loaded."},"404":{"description":"Unknown basin."}},"summary":"Sub-basin polygons for one basin as a GeoJSON `FeatureCollection`.","tags":["Regions"]}},"/v1/basins/{basin}/water-availability/closure":{"get":{"description":"Basin closure index, year by year, in %.\n\n```\nclosure = 100 \u00d7 (utilized_flow + reserved_flow) / exploitable_water\n```\n\n| %        | Class             |\n|----------|-------------------|\n| < 60     | Open              |\n| 60\u201375    | Closing           |\n| 75\u2013100   | Closed            |\n| > 100    | Over-allocated    |","operationId":"getBasinClosure","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"}],"responses":{"200":{"description":"Annual closure bar trace","schema":{"$ref":"#/definitions/BarResponse"}},"204":{"description":"No data for basin."},"404":{"description":"Unknown basin."}},"summary":"Basin closure index, year by year, in %.","tags":["Water Availability"]}},"/v1/basins/{basin}/water-availability/environmental-stress":{"get":{"description":"Environmental water-stress index, year by year, in %.\n\n```\nEWS = 100 \u00d7 utilized_flow / (exploitable_water \u2212 reserved_flow)\n```\n\nBands per SDG indicator 6.4.2 (UN/FAO classification):\n\n| %        | Stress class      |\n|----------|-------------------|\n| < 25     | No stress         |\n| 25\u201350    | Low               |\n| 50\u201375    | Medium            |\n| 75\u2013100   | High              |\n| > 100    | Critical          |","operationId":"getBasinEnvironmentalStress","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"}],"responses":{"200":{"description":"Annual EWS bar trace","schema":{"$ref":"#/definitions/BarResponse"}},"204":{"description":"No data for basin."},"404":{"description":"Unknown basin."}},"summary":"Environmental water-stress index, year by year, in %.","tags":["Water Availability"]}},"/v1/basins/{basin}/water-availability/et-fractions":{"get":{"description":"ET partitioning \u2014 managed / irrigated / agriculture fractions (%).\n\n* **managed**     \u2014 `100 \u00d7 blue_et_mm / total_et_mm`. Always returned.\n* **irrigated**   \u2014 share of ET from irrigated areas (optional;\n                    depends on `mart_basin_irrigated_et_yearly_mm`).\n* **agriculture** \u2014 share of ET from agriculture, rainfed + irrigated\n                    (optional; depends on `mart_basin_ag_et_yearly_mm`).\n\n`has_irrigated` / `has_agriculture` tell the client up-front which\noptional series are populated for this basin.","operationId":"getBasinETFractions","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"}],"responses":{"200":{"description":"ET fractions","schema":{"$ref":"#/definitions/ETFractionsResponse"}},"404":{"description":"Unknown basin."}},"summary":"ET partitioning \u2014 managed / irrigated / agriculture fractions (%).","tags":["Water Availability"]}},"/v1/basins/{basin}/water-availability/further-use":{"get":{"description":"Annual water available for further use (utilizable outflow), in km\u00b3/yr.\n\nThe headroom that future development would consume. A declining series\nis a leading indicator of basin closure; near-zero means the basin is\neffectively closed.","operationId":"getBasinFurtherUse","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"}],"responses":{"200":{"description":"Bar trace by year","schema":{"$ref":"#/definitions/BarResponse"}},"204":{"description":"No data for basin."},"404":{"description":"Unknown basin."}},"summary":"Annual water available for further use (utilizable outflow), in km\u00b3/yr.","tags":["Water Availability"]}},"/v1/basins/{basin}/water-availability/per-capita":{"get":{"description":"Renewable water resources per person, in **m\u00b3/capita\u00b7yr**.\n\nExploitable water (the basin's renewable resource) \u00f7 population.\nOne of the most-cited water-scarcity indicators (Falkenmark family):\n\n| m\u00b3/capita\u00b7yr | Class                |\n|--------------|----------------------|\n| > 1700       | No scarcity          |\n| 1000\u20131700    | Stress               |\n| 500\u20131000     | Chronic scarcity     |\n| < 500        | Absolute scarcity    |\n\nReturns one of three shapes depending on ``mode``:\n\n* ``heatmap`` *(default)* \u2014 year \u00d7 month matrix `z`\n* ``yearly``              \u2014 annual bar trace\n* ``monthly``             \u2014 12-month bar trace for one ``year``","operationId":"getBasinWaterAvailabilityPerCapita","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"},{"default":"heatmap","description":"`heatmap`, `monthly`, or `yearly`.","enum":["heatmap","monthly","yearly"],"in":"query","name":"mode","type":"string"},{"default":2024,"description":"Required for `mode=monthly`. Defaults to latest year with both WB + population.","in":"query","name":"year","type":"integer"}],"responses":{"200":{"description":"Per-capita response","schema":{"$ref":"#/definitions/PerCapitaResponse"}},"404":{"description":"Unknown basin OR no population data (RFC 7807)."}},"summary":"Renewable water resources per person, in **m\u00b3/capita\u00b7yr**.","tags":["Water Availability"]}},"/v1/basins/{basin}/water-balance/annual":{"get":{"description":"Annual time-series of the three headline water-balance components in km\u00b3/yr.\n\nReturns rainfall, total ET (blue + green), and outflow as **Plotly bar\ntraces** keyed by calendar year. Designed to drop straight into a\n`Plotly.newPlot(...)` call without transformation.\n\nTogether with the much smaller net-inflow and storage-change terms,\nthese three close the basin balance `P + Q_in = ET + Q_out + \u0394S`.\n\n### Companion endpoint\n\n[`getBasinWaterBalanceSunburst`](#operation/getBasinWaterBalanceSunburst)\n\u2014 typical-year breakdown into the WA+ sub-classes.","operationId":"getBasinWaterBalanceAnnual","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"},{"default":2003,"description":"Window lower bound (inclusive). Default 2003.","in":"query","name":"start_year","type":"integer"},{"default":2024,"description":"Window upper bound (inclusive). Default 2024.","in":"query","name":"end_year","type":"integer"}],"responses":{"200":{"description":"Three bar traces (rainfall, total_et, outflow)","schema":{"$ref":"#/definitions/WaterBalanceAnnual"}},"204":{"description":"Valid request, no data in window."},"404":{"description":"Unknown basin."},"422":{"description":"Invalid time window."}},"summary":"Annual time-series of the three headline water-balance components in km\u00b3/yr.","tags":["Water Balance"]}},"/v1/basins/{basin}/water-balance/sunburst":{"get":{"description":"Long-term-average basin water balance, returned as a sunburst hierarchy.\n\nDecomposes the right-hand side of ``P + Q_in = ET + Q_out + \u0394S`` into\nthe **WA+ (Water Accounting Plus)** categories \u2014 all in **km\u00b3/year** \u2014\naveraged (or summed) over a year window.\n\n### Structure of the returned hierarchy\n\n* **Inflows** = Rainfall (P) + Net Inflow (Q_in)\n* **Losses & Allocation**\n  * **Total ET** = Green ET (rainfall-driven) + Blue ET (irrigation-driven)\n  * **Outflow** (Q_out)\n    * **Exploitable** \u2192 Utilizable Outflow, Reserved Flow, Non-Recoverable Flow\n    * **Other Outflow** \u2014 outflow above the exploitable cap\n  * **Storage Change** (only the positive residual)\n\nThe hierarchy is **mass-consistent**: each parent equals the sum of its\nchildren, so the Plotly sunburst's `branchvalues=total` setting\nyields meaningful percentages.\n\n### Aggregation\n\n* `agg=mean` *(default)* \u2014 typical year\n* `agg=sum`             \u2014 cumulative km\u00b3 over the window\n\n### Companion endpoint\n\n[`getBasinWaterBalanceAnnual`](#operation/getBasinWaterBalanceAnnual) \u2014\nthe inter-annual time-series of the same components.","operationId":"getBasinWaterBalanceSunburst","parameters":[{"default":"limpopo","description":"Basin short code. See `GET /v1/basins`.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"},{"default":2003,"description":"Window lower bound (inclusive). Default 2003.","in":"query","name":"start_year","type":"integer"},{"default":2024,"description":"Window upper bound (inclusive). Default 2024.","in":"query","name":"end_year","type":"integer"},{"default":"mean","description":"`mean` (default) or `sum`.","enum":["mean","sum"],"in":"query","name":"agg","type":"string"}],"responses":{"200":{"description":"Sunburst trace + metrics","schema":{"$ref":"#/definitions/WaterBalanceSunburst"}},"204":{"description":"Valid request, no data in window."},"404":{"description":"Unknown basin (RFC 7807)."},"422":{"description":"Invalid time window (start_year > end_year)."}},"summary":"Long-term-average basin water balance, returned as a sunburst hierarchy.","tags":["Water Balance"]}},"/v1/basins/{basin}/water-yield/geojson":{"get":{"description":"Sub-basin water-yield choropleth as a GeoJSON `FeatureCollection`.\n\nEach feature carries `properties.wy_mm`. Use directly in\nLeaflet/Mapbox/d3 \u2014 no transformation needed.","operationId":"getBasinWaterYieldGeoJSON","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"},{"default":2024,"description":"Calendar year or `average`. Default: latest.","in":"query","name":"year","type":"string"},{"default":2003,"description":"Window-average lower bound.","in":"query","name":"start_year","type":"integer"},{"default":2024,"description":"Window-average upper bound.","in":"query","name":"end_year","type":"integer"},{"description":"Douglas\u2013Peucker tolerance in degrees (~0.005\u20130.02).","in":"query","name":"simplify","type":"number"},{"default":true,"description":"Embed `stats` block. Default `true`.","in":"query","name":"include_stats","type":"string"}],"responses":{"200":{"description":"Water-yield choropleth FeatureCollection","schema":{"$ref":"#/definitions/WaterYieldFeatureCollection"}},"204":{"description":"No data for window."},"404":{"description":"Unknown basin or year not available."},"422":{"description":"Invalid window."}},"summary":"Sub-basin water-yield choropleth as a GeoJSON `FeatureCollection`.","tags":["Water Yield"]}},"/v1/basins/{basin}/water-yield/stats":{"get":{"description":"Distribution statistics for water yield across sub-basins.\n\n`count`, `min`, `p10`, `median`, `mean`, `p90`, `max` \u2014 one summary\nper year or window, no geometry. Use to power key-metric strips on\ndashboards.","operationId":"getBasinWaterYieldStats","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"},{"default":2024,"description":"Calendar year or `average`. Default: latest.","in":"query","name":"year","type":"string"},{"default":2003,"description":"Window-average lower bound.","in":"query","name":"start_year","type":"integer"},{"default":2024,"description":"Window-average upper bound.","in":"query","name":"end_year","type":"integer"}],"responses":{"200":{"description":"Stats only","schema":{"$ref":"#/definitions/WaterYieldStats"}},"204":{"description":"No data for window."},"404":{"description":"Unknown basin or year not available."},"422":{"description":"Invalid window."}},"summary":"Distribution statistics for water yield across sub-basins.","tags":["Water Yield"]}},"/v1/basins/{basin}/water-yield/values":{"get":{"description":"Per-sub-basin water yield values (`{region_code: wy_mm}`) without geometry.\n\nLightweight companion of `getBasinWaterYieldGeoJSON` \u2014 pair with one\npolygon load from `getBasinRegions` and join client-side.","operationId":"getBasinWaterYieldValues","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"},{"default":2024,"description":"Calendar year or `average`. Default: latest.","in":"query","name":"year","type":"string"},{"default":2003,"description":"Window-average lower bound.","in":"query","name":"start_year","type":"integer"},{"default":2024,"description":"Window-average upper bound.","in":"query","name":"end_year","type":"integer"}],"responses":{"200":{"description":"Values + stats","schema":{"$ref":"#/definitions/WaterYieldValues"}},"204":{"description":"No data for window."},"404":{"description":"Unknown basin or year not available."},"422":{"description":"Invalid window."}},"summary":"Per-sub-basin water yield values (`{region_code: wy_mm}`) without geometry.","tags":["Water Yield"]}},"/v1/basins/{basin}/water-yield/years":{"get":{"description":"Calendar years for which water yield is loaded.\n\nReturns the list to feed a year-picker UI, plus the time aggregations\nthe basin supports (`year` and, where there's enough history,\n`average`).","operationId":"listBasinWaterYieldYears","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"}],"responses":{"200":{"description":"Years available","schema":{"$ref":"#/definitions/WaterYieldYears"}},"204":{"description":"Basin has no water-yield data loaded."},"404":{"description":"Unknown basin."}},"summary":"Calendar years for which water yield is loaded.","tags":["Water Yield"]}},"/v1/diagnostics/geo-join":{"get":{"description":"Check whether the sub-basin GeoJSON and the metric tables agree on keys.\n\nProbe call: loads the basin GeoJSON, fetches January `TOTAL_ET_MM`\nrows, and reports any keys present on one side but missing on the\nother. Empty arrays = perfect join.\n\nUse this when a choropleth has blank polygons or polygons without\ndata \u2014 it surfaces the missing IDs so you can patch the upstream\nGeoJSON or DB row.","operationId":"getGeoJoinDiagnostic","parameters":[{"default":"limpopo","description":"Basin short code (case-insensitive).","example":"limpopo","in":"query","name":"basin","required":true,"type":"string"},{"default":"db","description":"Polygon source. `db` (default) or `file`.","enum":["db","file"],"in":"query","name":"source","type":"string"},{"default":10,"description":"Max number of example keys per side (default 10).","in":"query","name":"limit","type":"integer"}],"responses":{"200":{"description":"Geo \u2194 DB join coverage report","schema":{"$ref":"#/definitions/GeoJoinDiagnostic"}},"404":{"description":"Unknown basin."}},"summary":"Check whether the sub-basin GeoJSON and the metric tables agree on keys.","tags":["Diagnostics"]}},"/v1/metrics":{"get":{"description":"Every metric the API exposes, with its URL key, DB code, unit and family.\n\nClients building UIs that let the user pick a metric should call this\nonce at startup and cache the response. Adding a new metric to the\nwarehouse is a one-line entry in the catalogue and shows up here\nautomatically.","operationId":"listMetrics","responses":{"200":{"description":"Catalogue of metrics","schema":{"$ref":"#/definitions/MetricList"}}},"summary":"Every metric the API exposes, with its URL key, DB code, unit and family.","tags":["Metrics"]}},"/v1/metrics/{metric_key}":{"get":{"description":"Detail for one metric by URL key.\n\nReturns **404 Not Found** as RFC 7807 problem-details when the key is\nnot in the catalogue, with `supported_metrics` listing the valid keys.","operationId":"getMetric","parameters":[{"default":"water-yield","description":"URL key, kebab-case. Example: `blue-et`.","example":"water-yield","in":"path","name":"metric_key","required":true,"type":"string"}],"responses":{"200":{"description":"Metric detail","schema":{"$ref":"#/definitions/Metric"}},"404":{"description":"Unknown metric (RFC 7807 problem+json with `supported_metrics`)."}},"summary":"Detail for one metric by URL key.","tags":["Metrics"]}},"/v1/temp-files/{fname}":{"get":{"description":"Fetch a previously rendered chart / CSV by its generated filename.\n\n### Lifetime\n\nFiles are auto-purged **~48 hours** after creation and on each call\nto the parent renderer. Treat the URL as ephemeral; re-render if you\nneed long-lived embedding.\n\n### Security\n\nThe path is constrained to `TEMP_DIR` \u2014 directory traversal attempts\nreturn 404. Filenames are generated server-side using `uuid4()` so\nthe URLs are unguessable.","operationId":"getTempFile","parameters":[{"default":"copilot-limpopo-overview-abc123ef.png","description":"Filename as returned by the renderer.","example":"copilot-limpopo-overview-abc123ef.png","in":"path","name":"fname","required":true,"type":"string"}],"produces":["image/png","text/csv","application/octet-stream"],"responses":{"200":{"description":"Bytes \u2014 `image/png`, `text/csv`, or `application/octet-stream`."},"404":{"description":"File not found or expired."}},"summary":"Fetch a previously rendered chart / CSV by its generated filename.","tags":["Temp Files"]}},"/v1/watercopilot/basins/{basin}/monthly/{metric}/{month}/values":{"get":{"description":"Sub-basin values for one metric, one month, one (or aggregated) year.\n\nIdentical data to `getBasinMonthlyValues` (the dashboard variant), but\nwith a one-sentence summary appended and numbers rounded to whatever\n`decimals` the agent requests. No GeoJSON \u2014 pair with a one-shot\n`getBasinRegions` call client-side if a map is needed.","operationId":"waterCopilotMonthlyValues","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"},{"default":"water-yield","description":"URL key. See `GET /v1/metrics`.","example":"water-yield","in":"path","name":"metric","required":true,"type":"string"},{"default":1,"description":"Calendar month 1-12.","example":1,"in":"path","name":"month","required":true,"type":"integer"},{"default":"mean","description":"`mean` (default) or `sum` when `year` is omitted.","enum":["mean","sum"],"in":"query","name":"agg","type":"string"},{"default":2024,"description":"Single year (overrides `agg`).","in":"query","name":"year","type":"integer"},{"default":2003,"description":"Window lower bound.","in":"query","name":"start_year","type":"integer"},{"default":2024,"description":"Window upper bound.","in":"query","name":"end_year","type":"integer"},{"default":2,"description":"Rounding precision. Default 2.","in":"query","name":"decimals","type":"integer"}],"responses":{"200":{"description":"Envelope","schema":{"$ref":"#/definitions/WaterCopilotMonthlyResponse"}},"204":{"description":"No data for query."},"400":{"description":"Bad metric or month."},"404":{"description":"Unknown basin."}},"summary":"Sub-basin values for one metric, one month, one (or aggregated) year.","tags":["WaterCopilot \u00b7 Monthly"]}},"/v1/watercopilot/basins/{basin}/overview":{"get":{"description":"Single-call basin briefing \u2014 chart + summary + headline stats.\n\nThe endpoint an LLM agent should call first when asked about a basin.\nPre-synthesises four key indicators (rainfall vs ET, outflow trend,\nclosure trend, ET partition) into a single 4-panel chart plus a\nbullet summary the agent can quote verbatim.\n\nSaves one or two round-trips compared to stitching the dashboard\nendpoints together by hand.","operationId":"waterCopilotGetBasinOverview","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"},{"default":2003,"description":"Window lower bound (inclusive). Default 2003.","in":"query","name":"start_year","type":"integer"},{"default":2024,"description":"Window upper bound (inclusive). Default 2024.","in":"query","name":"end_year","type":"integer"},{"default":"markdown","description":"`markdown` (default, prose + chart_url) or `json` (leanest).","enum":["markdown","json"],"in":"query","name":"format","type":"string"},{"default":2,"description":"Rounding for numeric fields. Default 2.","in":"query","name":"decimals","type":"integer"}],"responses":{"200":{"description":"Overview envelope","schema":{"$ref":"#/definitions/WaterCopilotOverviewResponse"}},"404":{"description":"Unknown basin or no data in window."},"422":{"description":"Invalid time window."}},"summary":"Single-call basin briefing \u2014 chart + summary + headline stats.","tags":["WaterCopilot \u00b7 Overview"]}},"/v1/watercopilot/basins/{basin}/water-availability/closure":{"get":{"description":"Basin closure trend (%) \u2014 chart + classification.","operationId":"waterCopilotClosure","parameters":[{"description":"Basin short code.","in":"path","name":"basin","required":true,"type":"string"},{"default":"markdown","description":"`markdown` or `json`.","enum":["markdown","json"],"in":"query","name":"format","type":"string"},{"default":2,"in":"query","name":"decimals","type":"integer"}],"responses":{"200":{"description":"Envelope","schema":{"$ref":"#/definitions/WaterCopilotWAResponse"}},"404":{"description":"Unknown basin or no data."}},"summary":"Basin closure trend (%) \u2014 chart + classification.","tags":["WaterCopilot \u00b7 Water Availability"]}},"/v1/watercopilot/basins/{basin}/water-availability/environmental-stress":{"get":{"description":"Environmental water stress (%) \u2014 chart + SDG-6.4 classification.","operationId":"waterCopilotEnvironmentalStress","parameters":[{"description":"Basin short code.","in":"path","name":"basin","required":true,"type":"string"},{"default":"markdown","description":"`markdown` or `json`.","enum":["markdown","json"],"in":"query","name":"format","type":"string"},{"default":2,"in":"query","name":"decimals","type":"integer"}],"responses":{"200":{"description":"Envelope","schema":{"$ref":"#/definitions/WaterCopilotWAResponse"}},"404":{"description":"Unknown basin or no data."}},"summary":"Environmental water stress (%) \u2014 chart + SDG-6.","tags":["WaterCopilot \u00b7 Water Availability"]}},"/v1/watercopilot/basins/{basin}/water-availability/et-fractions":{"get":{"description":"ET partitioning \u2014 managed/irrigated/agriculture %, chart + summary.","operationId":"waterCopilotETFractions","parameters":[{"description":"Basin short code.","in":"path","name":"basin","required":true,"type":"string"},{"default":"markdown","description":"`markdown` or `json`.","enum":["markdown","json"],"in":"query","name":"format","type":"string"},{"default":2,"in":"query","name":"decimals","type":"integer"}],"responses":{"200":{"description":"Envelope","schema":{"$ref":"#/definitions/WaterCopilotWAResponse"}},"404":{"description":"Unknown basin or no ET data."}},"summary":"ET partitioning \u2014 managed/irrigated/agriculture %, chart + summary.","tags":["WaterCopilot \u00b7 Water Availability"]}},"/v1/watercopilot/basins/{basin}/water-availability/further-use":{"get":{"description":"Water-available-for-further-use trend \u2014 chart + closure narrative.","operationId":"waterCopilotFurtherUse","parameters":[{"description":"Basin short code.","in":"path","name":"basin","required":true,"type":"string"},{"default":"markdown","description":"`markdown` or `json`.","enum":["markdown","json"],"in":"query","name":"format","type":"string"},{"default":2,"in":"query","name":"decimals","type":"integer"}],"responses":{"200":{"description":"Envelope","schema":{"$ref":"#/definitions/WaterCopilotWAResponse"}},"404":{"description":"Unknown basin or no data."}},"summary":"Water-available-for-further-use trend \u2014 chart + closure narrative.","tags":["WaterCopilot \u00b7 Water Availability"]}},"/v1/watercopilot/basins/{basin}/water-availability/per-capita":{"get":{"description":"Per-capita water availability \u2014 chart + Falkenmark classification.","operationId":"waterCopilotPerCapita","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"},{"default":"markdown","description":"`markdown` (default) or `json`.","enum":["markdown","json"],"in":"query","name":"format","type":"string"},{"default":2,"in":"query","name":"decimals","type":"integer"},{"default":"yearly","description":"`yearly` (default), `monthly`, or `heatmap`.","enum":["heatmap","monthly","yearly"],"in":"query","name":"mode","type":"string"},{"default":2024,"description":"Required when `mode=monthly`.","in":"query","name":"year","type":"integer"}],"responses":{"200":{"description":"Envelope","schema":{"$ref":"#/definitions/WaterCopilotWAResponse"}},"404":{"description":"Unknown basin or no population data."}},"summary":"Per-capita water availability \u2014 chart + Falkenmark classification.","tags":["WaterCopilot \u00b7 Water Availability"]}},"/v1/watercopilot/basins/{basin}/water-balance/annual":{"get":{"description":"Annual rainfall / ET / outflow trends \u2014 chart + narrative.\n\nRenders the three headline series as line + bar overlays and adds a\nparagraph describing the inter-annual signal (rising / falling, max\nyear, min year).","operationId":"waterCopilotWBAnnual","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"},{"default":2003,"description":"Window lower bound (inclusive).","in":"query","name":"start_year","type":"integer"},{"default":2024,"description":"Window upper bound (inclusive).","in":"query","name":"end_year","type":"integer"},{"default":"markdown","description":"`markdown` (default) or `json`.","enum":["markdown","json"],"in":"query","name":"format","type":"string"},{"default":2,"in":"query","name":"decimals","type":"integer"}],"responses":{"200":{"description":"Annual envelope","schema":{"$ref":"#/definitions/WaterCopilotWBResponse"}},"404":{"description":"Unknown basin or no data in window."},"422":{"description":"Invalid time window."}},"summary":"Annual rainfall / ET / outflow trends \u2014 chart + narrative.","tags":["WaterCopilot \u00b7 Water Balance"]}},"/v1/watercopilot/basins/{basin}/water-balance/sunburst":{"get":{"description":"Long-term-average water balance as a server-rendered **donut**.\n\nDifferent from the dashboard's full sunburst (which is a Plotly trace\nstructure) \u2014 this returns a flat PNG donut showing the four headline\nflows: Rainfall, Total ET, Outflow, Utilizable Outflow. Designed for\nquick LLM-driven framings of *where does the water go?*","operationId":"waterCopilotWBSunburst","parameters":[{"default":"limpopo","description":"Basin short code.","example":"limpopo","in":"path","name":"basin","required":true,"type":"string"},{"default":2003,"description":"Window lower bound (inclusive).","in":"query","name":"start_year","type":"integer"},{"default":2024,"description":"Window upper bound (inclusive).","in":"query","name":"end_year","type":"integer"},{"default":"markdown","description":"`markdown` (default) or `json`.","enum":["markdown","json"],"in":"query","name":"format","type":"string"},{"default":2,"in":"query","name":"decimals","type":"integer"},{"default":"mean","description":"`mean` (typical year, default) or `sum` (cumulative).","enum":["mean","sum"],"in":"query","name":"agg","type":"string"}],"responses":{"200":{"description":"Sunburst envelope","schema":{"$ref":"#/definitions/WaterCopilotWBResponse"}},"404":{"description":"Unknown basin or no data in window."},"422":{"description":"Invalid time window."}},"summary":"Long-term-average water balance as a server-rendered **donut**.","tags":["WaterCopilot \u00b7 Water Balance"]}}},"produces":["application/json"],"responses":{"MaskError":{"description":"When any error occurs on mask"},"ParseError":{"description":"When a mask can't be parsed"}},"security":[{"Bearer":[]}],"securityDefinitions":{"Bearer":{"description":"Keycloak-issued JWT access token from the **water-accounting** realm, sent as `Bearer <token>`. Required on `/v1` data endpoints when the server runs with `AUTH_ENABLED=true`; `/health` and the docs/spec routes stay public.","in":"header","name":"Authorization","type":"apiKey"}},"swagger":"2.0","tags":[{"description":"Discovery \u2014 list of basins loaded into the warehouse and per-basin metadata. The starting point for any client scripting against the API.","name":"Basins"},{"description":"Canonical metric catalogue. Maps URL keys (kebab-case) to DB metric codes, display labels, units, and the family of endpoints that accept each key.","name":"Metrics"},{"description":"Closed-form basin water balance `P + Q_in = ET + Q_out + \u0394S`, decomposed into WA+ categories. Long-term sunburst + annual time-series.","name":"Water Balance"},{"description":"Five water-availability indicators: per-capita water, ET fractions, water-availability for further use, basin closure, and environmental water stress. All annual time-series.","name":"Water Availability"},{"description":"WA+ Land-Use Water-Accounting (LU_WA) classification \u2014 Protected, Utilized, Modified, Managed \u2014 at basin grain. Donut summary + Plotly-ready bundles.","name":"Land Use"},{"description":"Annual water yield (`P \u2212 ET`, mm/yr) by HydroBASINS sub-basin. Years catalogue, summary stats, per-region values, or full choropleth GeoJSON.","name":"Water Yield"},{"description":"Monthly climatology by sub-basin \u2014 same month averaged across all loaded years to expose the seasonal cycle. Returns a choropleth in five formats or a compact values-only map.","name":"Monthly Climatology"},{"description":"Year-on-year change analysis. Absolute annual series + standardised anomalies (z-scores) for the basin's headline water-balance indicators.","name":"Change Analysis"},{"description":"HydroBASINS sub-basin polygons. Pure geometry \u2014 pair with one of the `\u2026/values` endpoints to render a choropleth.","name":"Regions"},{"description":"One-shot LLM briefing \u2014 4-panel summary chart + headline numbers + a one-sentence prose summary. Saves round-trips when an agent is asked open-ended questions about a basin.","name":"WaterCopilot \u00b7 Overview"},{"description":"LLM-friendly variants of `/v1/basins/{basin}/water-balance/\u2026`. Each returns a rendered chart URL + a one-sentence prose summary.","name":"WaterCopilot \u00b7 Water Balance"},{"description":"LLM-friendly variants of `/v1/basins/{basin}/water-availability/\u2026`. Each returns a rendered chart URL + an interpretive prose summary.","name":"WaterCopilot \u00b7 Water Availability"},{"description":"Compact monthly-climatology values for an LLM agent. Same data as `/v1/basins/{basin}/monthly/{metric}/{month}/values`, with rounded decimals and an appended prose summary. No GeoJSON.","name":"WaterCopilot \u00b7 Monthly"},{"description":"Operational introspection \u2014 used by the team to investigate data-pipeline / map-stack issues. Not the service uptime check (see `/health` for that).","name":"Diagnostics"},{"description":"Server-side rendered artifacts (PNGs, CSVs) saved as short-lived files. URL handoff pattern used by `?format=url` endpoints.","name":"Temp Files"}],"x-tagGroups":[{"name":"Discovery","tags":["Basins","Metrics"]},{"name":"Basin Water Accounting","tags":["Water Balance","Water Availability","Land Use","Water Yield","Monthly Climatology","Change Analysis","Regions"]},{"name":"WaterCopilot (LLM agents)","tags":["WaterCopilot \u00b7 Overview","WaterCopilot \u00b7 Water Balance","WaterCopilot \u00b7 Water Availability","WaterCopilot \u00b7 Monthly"]},{"name":"System","tags":["Diagnostics","Temp Files"]}]}
