API Reference
Authenticate every request with an x-api-key: YOUR_API_KEY header. Manage keys in the API Keys tab.
Current Coverage
Quick Start
curl
# GET — Drought data for a coordinate
curl "https://climate.globmaps.com/api/risk-map/drought?lat=13.7563&lng=100.5018" \
-H "x-api-key: YOUR_API_KEY"
# GET — Province drought data
curl "https://climate.globmaps.com/api/risk-map/drought/province?country=THA&name=Chiang+Mai" \
-H "x-api-key: YOUR_API_KEY"
# POST — Risk score
curl -X POST "https://climate.globmaps.com/api/risk-map/score" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"lat": 13.7563, "lng": 100.5018, "riskType": "DROUGHT"}'python
import requests
BASE = "https://climate.globmaps.com"
HEADERS = {"x-api-key": "YOUR_API_KEY"}
# Grid drought at Bangkok
r = requests.get(f"{BASE}/api/risk-map/drought", headers=HEADERS,
params={"lat": 13.7563, "lng": 100.5018})
data = r.json()["data"]
print(data["drought"]["score"], data["drought"]["level"])
# Province query
r = requests.get(f"{BASE}/api/risk-map/drought/province", headers=HEADERS,
params={"country": "THA", "name": "Chiang Mai"})
province = r.json()["data"]
print(province["province"], province["mdi_severity"], province["severity_class"])
# Batch — 3 farms
r = requests.post(f"{BASE}/api/risk-map/batch",
headers={**HEADERS, "Content-Type": "application/json"},
json={"riskType": "DROUGHT", "points": [
{"id": "farm-01", "lat": 13.75, "lng": 100.50},
{"id": "farm-02", "lat": 18.79, "lng": 98.97},
{"id": "farm-03", "lat": 21.02, "lng": 105.83},
]})
for item in r.json()["results"]:
print(item["id"], item["riskScore"], item["riskLevel"])js
const BASE = "https://climate.globmaps.com";
const HEADERS = { "x-api-key": "YOUR_API_KEY" };
// Grid drought at Bangkok
const droughtRes = await fetch(
`${BASE}/api/risk-map/drought?lat=13.7563&lng=100.5018`,
{ headers: HEADERS }
);
const { data } = await droughtRes.json();
console.log(data.drought.score, data.drought.level);
// Province query
const provRes = await fetch(
`${BASE}/api/risk-map/drought/province?country=THA&name=Chiang+Mai`,
{ headers: HEADERS }
);
const { data: prov } = await provRes.json();
console.log(prov.province, prov.mdi_severity, prov.severity_class);
// Batch
const batchRes = await fetch(`${BASE}/api/risk-map/batch`, {
method: "POST",
headers: { ...HEADERS, "Content-Type": "application/json" },
body: JSON.stringify({ riskType: "DROUGHT", points: [
{ id: "farm-01", lat: 13.75, lng: 100.50 },
{ id: "farm-02", lat: 18.79, lng: 98.97 },
]}),
});
const { results } = await batchRes.json();
results.forEach(r => console.log(r.id, r.riskScore));Drought API
/api/risk-map/droughtGrid-level drought index at a coordinate (nearest ~25 km grid cell). Returns a drought score, a per-index severity class map, and the SPEI/SPI/SSI/MCDI index values at four accumulation windows.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| lat | number | required | Latitude (-90 to 90) |
| lng | number | required | Longitude (-180 to 180) |
| month | string | optional | Data month in YYYY-MM format. Defaults to latest available. |
Response (200 OK)
{
"success": true,
"data": {
"location": {
"requestedLat": 13.7563,
"requestedLng": 100.5018,
"gridId": "THA_grid_0042",
"gridLat": 13.75,
"gridLng": 100.50,
"distanceKm": 0.8,
"country": "THA"
},
"period": {
"month": "2026-07",
"availableMonths": ["2021-01", "2021-02", "…", "2026-06", "2026-07"],
"climatologyBaseline": "1991-2020"
},
"drought": {
"score": 3,
"level": "low",
"rating": null,
"risk_rating": null,
"risk_label": null,
"risk_display": null,
"indices": {
"spei1": -0.06, "spei3": -0.143, "spei6": -0.661, "spei12": -0.403,
"spi1": -0.401, "spi3": -0.726, "spi6": -1.35, "spi12": -0.996,
"ssi1": -1.081, "ssi3": -1.049, "mcdi": -0.827
},
"severity": {
"spei1": null, "spei3": null, "spei6": "D0", "spei12": null,
"spi1": null, "spi3": "D0", "spi6": "D2", "spi12": "D1"
}
},
"confidenceScore": 0.673,
"disclaimer": "Climate risk scores are probabilistic estimates based on available data and models. Actual conditions may differ. Not intended as sole basis for critical decisions."
}
}
// availableMonths is the full month list — 67 entries as of 2026-07, elided above.
// severity is an OBJECT keyed by index, not a string. A window with no class returns null.
// rating / risk_rating / risk_label / risk_display are null when no severity class is assigned./api/risk-map/drought/provinceProvince-level drought data. Coverage: Thailand (77 provinces), Vietnam (63 provinces), Malaysia (16 states), India (36 states/UTs).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | required | Province name (e.g. "Chiang Mai", "Ha Noi", "Johor") |
| country | string | required | "THA" | "VNM" | "MYS" | "IND" |
| month | string | optional | Data month in YYYY-MM format. Defaults to latest available. |
Response (200 OK)
{
"success": true,
"data": {
"province": "Chiang Mai",
"lat": 18.789,
"lng": 98.7335,
"month": "2026-07",
"mdi_score": 0,
"mdi_severity": "none",
"severity_class": "None",
"alert_level": "none",
"spei1": 0.345,
"spei1_class": "N",
"spei3": 0.455,
"spei6": 0.1336,
"spei12": 0.4634,
"spi1": 0.2059,
"spi3": 0.3054,
"forecast": [
{ "ym": "2026-08", "spei1": 1.0744, "severity": "W1", "tp_mm": 423.7, "t2m_c": 23.18, "tp_cv": 0.221 },
{ "ym": "2026-09", "spei1": 0.0286, "severity": "N", "tp_mm": 265.55, "t2m_c": 23.31, "tp_cv": 0.25 }
],
"severity": "N",
"riskScore": 0,
"confidence": 0.756,
"confidenceLabel": "High",
"sustained_drought": {
"window": "spei12",
"class": null,
"spei12_value": 0.4634,
"as_of": "2026-07"
},
"riskLevel": "low",
"rating": null,
"risk_rating": null,
"risk_label": null,
"risk_display": null,
"enso_confidence": {
"flag": "enso_watch",
"direction": "el_nino",
"oni": 0.98,
"season_overlaps": 1,
"cpc_alert": "none",
"display": "ENSO Watch (ONI +0.98, developing). Forecast confidence: Moderate — conditions evolving; revisit at next monthly update.",
"source": "NOAA CPC ONI (ERSSTv5)",
"updated_at": "2026-07-09",
"next_update_expected": "2026-08-15"
}
}
}
// There is no "mdi" object and no "indices" object — the fields are flat, as shown.
// alert_level is a STRING: "none" | "watch" | "warning" | "alert".
// severity_class is "None" | "D0"–"D4" | "W0"–"W2".
// forecast is the 6-month outlook; two of the six entries are shown here.
// forecast[].spei1 can be null where the forecast has no value for that month./api/risk-map/drought/summaryCountry-level drought summary with AI-generated narrative and aggregate statistics.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| country | string | required | "THA" | "VNM" | "MYS" | "IND" |
Response (200 OK)
{
"success": true,
"data": {
"generated_at": "2026-07-15T13:20:29.242264+00:00",
"country": "THA",
"reference_month": "2026-06",
"summary": {
"latest_month": "2026-06",
"total_points": 726,
"severity_distribution": {
"D4": 6, "D3": 20, "D2": 57, "D1": 111, "D0": 95,
"N": 334, "W1": 91, "W2": 12
},
"drought_pct": 39.8,
"wet_pct": 14.2,
"mean_spei1": -0.336,
"anomaly_count": 121,
"forecast_outlook": {
"2026-07": { "N": 26, "W1": 14, "W2": 1, "D0": 5, "D1": 1, "D2": 1, "D4": 2 },
"2026-08": { "N": 26, "W1": 20, "D0": 1, "D1": 1, "D4": 2 },
"2026-09": { "N": 34, "W1": 14, "D1": 2 }
},
"init_month": "2026-07"
},
"narrative": "# รายงานติดตามสถานการณ์ภัยแล้ง ประเทศไทย …",
"data_sources": "…"
}
}
// data_sources is present in every response; its inner shape is not shown here because the
// capture this sample was written from truncated before it. Read it from a live call.
// There is no "month" key — the month fields are reference_month and summary.latest_month,
// and they can lag period.month on the grid endpoint by one cycle.
// severity_distribution counts GRID POINTS (total_points), not provinces, and includes the
// wet classes N / W1 / W2 alongside D0–D4.
// forecast_outlook is a country-level count per class per month — it is NOT a per-province series.
// narrative is Markdown and locale-dependent; it can run to several thousand characters./api/risk-map/drought/confidencePer-month forecast confidence for one province, one entry per forecast month.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| province | string | required | Province name (e.g. "Chiang Mai"). Required — a call without it returns 400. |
| country | string | optional | "THA" | "VNM" | "MYS" | "IND". Defaults to "THA". |
| lead | number | optional | Forecast lead in months. |
Response (200 OK)
{
"success": true,
"data": [
{ "ym": "2026-08", "confidence": 0.756, "confidence_label": "High" },
{ "ym": "2026-09", "confidence": 0.624, "confidence_label": "Medium" },
{ "ym": "2026-10", "confidence": 0.519, "confidence_label": "Low" },
{ "ym": "2026-11", "confidence": 0.421, "confidence_label": "Low" },
{ "ym": "2026-12", "confidence": 0.33, "confidence_label": "Low" },
{ "ym": "2027-01", "confidence": 0.253, "confidence_label": "Low" }
]
}
// data is an ARRAY, not an object. There is no "country", "month" or "composite" key.
// province is REQUIRED: GET …/confidence?country=THA alone returns
// 400 {"error":"province is required."}/api/risk-map/drought/alertActive drought alerts filtered by severity threshold. Returns provinces meeting or exceeding the specified level.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| country | string | required | "THA" | "VNM" | "MYS" | "IND" |
| severity | string | optional | Comma-separated classes to include, e.g. "D2" or "D2,D3,D4". Defaults to "D3,D4". |
Response (200 OK)
{
"success": true,
"count": 2,
"data": [
{
"province": "Prachuap Khiri Khan",
"month": "2026-07",
"spei1": -1.5887,
"spei3": -0.0386,
"severity": "D2",
"forecast": [
{ "ym": "2026-08", "spei1": 0.2618, "severity": "N", "tp_mm": 225.19, "t2m_c": 24.94, "tp_cv": 0.203 },
{ "ym": "2026-09", "spei1": -0.1216, "severity": "N", "tp_mm": 217.32, "t2m_c": 25.26, "tp_cv": 0.23 },
{ "ym": "2026-10", "spei1": 0.4315, "severity": "N", "tp_mm": 228.57, "t2m_c": 25.33, "tp_cv": 0.373 }
],
"risk_rating": "D",
"risk_label": "Severe Drought",
"risk_display": "-0.04 · D (D2 Severe)"
}
]
}
// count sits BESIDE success, not inside data, and data is an ARRAY of provinces.
// There is no "country", "severity_threshold", "alert_count" or "provinces" key.
// forecast[].spei1 can be null where the forecast has no value for that month.Point Query
/api/point-queryReverse-geocode a lat/lng to a province then return full MDI drought data. Single call for location → risk lookup.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| lat | number | required | Latitude (-90 to 90) |
| lng | number | required | Longitude (-180 to 180) |
Response (200 OK)
{
"status": "ok",
"province": "Bangkok Metropolis",
"country": "THA",
"mdi": { "score": 0.41, "level": "mild", "severity": "D0 Abnormally Dry" },
"indices": { "spei": 0.38, "spi": 0.44, "vci": 0.36, "tci": 0.47, "vhi": 0.40, "pdsi": 0.42, "sma": 0.39 },
"month": "2026-04"
}
// status: "out_of_coverage" if point is outside THA/VNM/MYS/IND
//
// NOT YET VERIFIED against a live response. The five Drought API samples above were
// rewritten from a real capture (e2e run 33069973775 / API capture run 33078137741);
// this one was not captured, so treat its shape as unconfirmed. The "indices" set shown
// here (vci/tci/vhi/pdsi/sma) does not appear in any captured drought response, which is
// reason to doubt it rather than reason to copy it.Risk Score
/api/risk-map/scoreComposite risk score for a coordinate across risk types. Returns a 0–1 score with level label.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| lat | number | required | Latitude |
| lng | number | required | Longitude |
| riskType | string | required | "DROUGHT" | "FLOOD" | "WILDFIRE" |
Response (200 OK)
{
"riskScore": 0.61,
"riskLevel": "moderate",
"country": "THA",
"province": "Chiang Mai",
"month": "2026-04"
}Batch
/api/risk-map/batchBulk risk scoring for multiple coordinates in a single request. More efficient than individual calls. Max 100 points per request.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| points | array | required | Array of {lat, lng, id?} objects. Max 100. |
| riskType | string | required | "DROUGHT" | "FLOOD" | "WILDFIRE" |
Response (200 OK)
{
"results": [
{ "id": "farm-01", "lat": 13.75, "lng": 100.50, "riskScore": 0.61, "riskLevel": "moderate" },
{ "id": "farm-02", "lat": 18.79, "lng": 98.97, "riskScore": 0.72, "riskLevel": "severe" }
],
"processed": 2,
"failed": 0
}Coming Soon — Not Yet Available
501 Not Implemented and must not be integrated into production applications. When a pipeline ships and passes QA, the endpoint will be re-badged Beta → GA and announced in the changelog./api/outbreak-radar/queryComing SoonDisease surveillance and outbreak risk intelligence. Real-time monitoring across 180+ countries using WHO EIOS, CDC FluNet, ProMED, and climate-disease correlation models.
501 Not Implemented·Roadmap — no confirmed date/api/supply-chain/queryComing SoonPort congestion, vessel tracking, and maritime trade risk intelligence. Covers 120+ major global ports with AIS data, UN Comtrade flows, and cargo delay estimates.
501 Not Implemented·Roadmap — no confirmed dateRate Limits
| Plan | Per Minute | Monthly | Notes |
|---|---|---|---|
| Free / Trial | 10 req/min | 1,000 req/mo | For evaluation only |
| Platform Pro | 60 req/min | 10,000 req/mo | Single country |
| Bundle Pro | 60 req/min | 30,000 req/mo | THA + VNM + MYS |
| SEA Bundle | 300 req/min | 200,000 req/mo | Full SEA coverage + Batch |
| Enterprise | Custom | Custom | SLA + dedicated support |
When a rate limit is hit the API returns 429 Too Many Requests. Use exponential back-off before retrying. The X-RateLimit-Remaining response header shows calls left in the current window.
Error Codes
| Code | Status | Description |
|---|---|---|
| 400 | Bad Request | Missing or invalid parameters (e.g. lat/lng out of range, bad YYYY-MM format) |
| 401 | Unauthorized | Missing x-api-key header or key not found |
| 403 | Forbidden | Active subscription does not include the requested country |
| 404 | Not Found | Province name not recognised, or no data for this location/period |
| 429 | Too Many Reqs | Rate limit exceeded — back off and retry after the window resets |
| 500 | Server Error | Unexpected error — contact support@globmaps.com with the request ID |
All error responses follow the shape: { "error": "Human-readable message." }
Data Attribution
Contains modified Copernicus Climate Change Service information 2026. Neither the European Commission nor ECMWF is responsible for any use that may be made of the Copernicus information or data it contains.
Data sources: ERA5 (Copernicus/ECMWF) · SEAS5 seasonal forecast · NOAA GHCND station data · GloFAS river discharge.
Administrative boundaries: geoBoundaries (gbOpen), Runfola et al. (2020), licensed CC BY 4.0.
MDI scores are probabilistic estimates for decision-support purposes. Not intended as the sole basis for critical infrastructure, financial, or emergency decisions. Applications using this API must display: "Powered by GlobMaps MDI".
Support