🏞️

Western Ghats ESA Atlas

API reference

Using the data programmatically

The API is a tree of static JSON files served over HTTPS with Access-Control-Allow-Origin: *. You can call it from a browser, a notebook or another website with no key, no sign-up and no rate limit.

It is read-only and addressed entirely by path. There are no query parameters, because there is no server — filtering happens on your side, after you fetch. In exchange you get something that cannot go down under load, cannot rotate a key on you, and is cached on a CDN.

Base URL:

https://nikunjfriends25-droid.github.io/western-ghats-esa/

Endpoints

PathReturns
api/v1/summary.json Per-state village counts, mapped area, notified area and ratio
api/v1/states/{CODE}.json Every village in one state, attributes only, no geometry.
Codes: GA GJ KA KL MH TN
api/v1/geometry/{CODE}.json Every village in one state with geometry, as a GeoJSON FeatureCollection. Simplified to ~33 m for overlay use
api/v1/outline/{CODE}.json One state's ESA dissolved to a single outer boundary
api/v1/outline.json The whole ESA dissolved, one feature per state — the lightest way to draw it
api/v1/villages/{censuscode}.json One village as a GeoJSON Feature, full resolution
api/v1/boundary-points.json The 401 Annexure B boundary points with state and gazette page
api/v1/unmatched.json Gazette rows with no polygon, each with a reason
api/v1/analysis-summary.json Derived totals, per-state rows, priority bands, and the limitations list
api/v1/analysis/{CODE}.json Every village in a state with its derived indicators
api/v1/kerala-comparison.json The same metrics computed on whole villages and on Kerala's official boundary — a measurement of how much the whole-village approximation shifts each figure

Bulk geometry

Whole-state GeoJSON, Shapefile, KML and CSV are plain files under downloads/ — fetch them the same way. The merged full-resolution GeoPackage is attached to the latest release rather than served here.

Overlaying the ESA on your own map

Three levels of detail, so you can pick the lightest thing that answers your question.

UseEndpointSize
Just show where the ESA isapi/v1/outline.jsonsmallest
Show one state's villagesapi/v1/geometry/{CODE}.jsonmoderate
Exact boundary of one villageapi/v1/villages/{censuscode}.jsontiny, full resolution

Every one of these returns valid GeoJSON, so it drops straight into MapLibre, Leaflet, OpenLayers, Mapbox, QGIS or GeoPandas with no conversion.

MapLibre or Mapbox:

const base = 'https://nikunjfriends25-droid.github.io/western-ghats-esa/';

map.addSource('esa', { type: 'geojson', data: base + 'api/v1/outline.json' });
map.addLayer({ id: 'esa-fill', type: 'fill', source: 'esa',
  paint: { 'fill-color': '#2f6d3a', 'fill-opacity': 0.35 } });
map.addLayer({ id: 'esa-line', type: 'line', source: 'esa',
  paint: { 'line-color': '#1d4a25', 'line-width': 1.2 } });

Leaflet:

fetch(base + 'api/v1/geometry/KL.json')
  .then(r => r.json())
  .then(gj => L.geoJSON(gj, {
    style: { color: '#2f6d3a', weight: 1, fillOpacity: 0.3 },
    onEachFeature: (f, l) => l.bindPopup(f.properties.gz_village)
  }).addTo(map));

QGIS — add these as a vector layer straight from the URL (Layer ▸ Add Layer ▸ Add Vector Layer ▸ Protocol: HTTP), or in the Python console:

iface.addVectorLayer(
    "https://nikunjfriends25-droid.github.io/western-ghats-esa/api/v1/outline.json",
    "Western Ghats ESA", "ogr")

Intersect the ESA with your own points, in GeoPandas:

import geopandas as gpd
base = "https://nikunjfriends25-droid.github.io/western-ghats-esa/"
esa   = gpd.read_file(base + "api/v1/outline.json")
sites = gpd.read_file("my_sites.geojson").to_crs(esa.crs)
inside = gpd.sjoin(sites, esa, predicate="within")
print(len(inside), "of", len(sites), "sites fall inside the draft ESA")

Geometry from outline and geometry is simplified to about 33 m for overlay use, so it is not suitable for measuring or for any parcel-level question. Use api/v1/villages/{censuscode}.json, or the release GeoPackage, when you need the full-resolution edge — and read the caveats first.

Examples

One village, by 2011 Census code:

curl https://nikunjfriends25-droid.github.io/western-ghats-esa/api/v1/villages/626770.json

Every Kerala village that the gazette marks as bifurcated:

const base = 'https://nikunjfriends25-droid.github.io/western-ghats-esa/';
const kl = await fetch(base + 'api/v1/states/KL.json').then(r => r.json());
const partial = kl.rows.filter(r => r.bifurcated);
console.log(partial.map(r => r.gz_village));

Load a whole state into GeoPandas:

import geopandas as gpd
base = "https://nikunjfriends25-droid.github.io/western-ghats-esa/"
ka = gpd.read_file(base + "downloads/WG_ESA_2024_KA.geojson")
print(ka.area_km2.sum(), "km2 across", len(ka), "villages")

Total mapped area against what was notified:

curl -s https://nikunjfriends25-droid.github.io/western-ghats-esa/api/v1/summary.json \
  | jq '.states[] | {state, area_km2, notified_km2, ratio}'

There are no Zone 1/2/3 fields. The 2024 notification defines a single, undivided ESA. esa_category records how a village was mapped, not a level of legal protection — see why there are no zones.

Field reference

FieldMeaning
gz_state, gz_district, gz_taluka, gz_village As printed in Annexure C of the notification
gz_village_rawVerbatim, including the * bifurcation marker
gz_snoGazette serial number within its state
cen_village, cen_subdistrict, cen_district The matched census record
censuscode2011 Census village code — the join key to census tables
lgd_villagecodeLocal Government Directory village code
esa_category whole_village, bifurcated_village, notified_forest, kerala_village, kerala_bifurcated_village
bifurcatedtrue when only part of the village is in the ESA
scoreName similarity, 0–100
scopeHow wide the search had to go: dist+tal, dist, state
area_km2Polygon area, computed in EPSG:7755
analysis Present on each village endpoint: population and census composition, land cover, protection and tenure overlaps, forest and hydrological setting, and the two composite scores. See the analysis layer — these are derived figures with real limitations, not transcribed ones.

Read the caveats before drawing conclusions. Villages with bifurcated: true are returned as whole polygons and over-state the ESA, and all Kerala rows are whole villages where the state's own definition is portion-wise. A low score or a scope of state means the pairing is less certain. See Method & caveats.

Stability & licence

Paths under api/v1/ are intended to stay put; a breaking change would appear as api/v2/. Data is released under CC BY 4.0, and derived from the MoEFCC draft notification S.O. 3060(E) (PDF, 4.9 MB) — attribute Western Ghats ESA Atlas, Nikunj Jambu and link back. The underlying government data remains under its own terms.