Developers
Every active tropical cyclone on the planet — typhoons, cyclones and hurricanes — with the official forecast track from the agency responsible for it, as JSON. Plus a curated archive of real historical tracks from NOAA IBTrACS. Free, with a key.
We email it to you. 1,000 requests a day, 60 a minute.
Send the key in the X-API-Key header (or Authorization: Bearer).
curl -H "X-API-Key: bgy_…" https://bagyo.io/v1/storms
GET /v1/storms | Every active storm in every basin, each with its current fix and full forecast track. Refreshed from the agencies every five minutes; an empty list when nothing is active. |
GET /v1/storms/{id} | One active storm, by the id in the list (TC2630, IO0126, AL132026). 404 once it has dissipated. |
GET /v1/storms/historical | The archive: selected real storms with six-hourly IBTrACS tracks. |
GET /v1/storms/historical/{id} | One archived storm, by archive id (katrina-2005) or IBTrACS SID. |
The full schema is at /v1/openapi.json (OpenAPI 3.1), ready for code generators and API clients.
{
"data": [
{
"id": "TC2630",
"name": "CHAMPI",
"philippineName": "Rosal",
"developing": false,
"basin": "wpac",
"agency": "JMA",
"agencyName": "Japan Meteorological Agency",
"designation": "2630",
"updatedAt": "2026-10-20T15:45:00.000Z",
"advisoryUrl": "https://www.data.jma.go.jp/…",
"current": {
"time": "2026-10-20T15:00:00.000Z",
"kind": "analysis",
"lat": 17, "lon": 133,
"windMps": 55, "windKt": 107,
"pressureHpa": 925,
"uncertaintyRadiusKm": 0,
"galeRadiusKm": 650
},
"track": [ … ]
}
],
"meta": {
"retrievedAt": "2026-10-20T15:52:10.000Z",
"stale": false,
"partial": false,
"sources": ["Japan Meteorological Agency", "Joint Typhoon Warning Center", "National Hurricane Center"],
"attribution": "Storm data from the Japan Meteorological Agency, …"
}
}
basin is one of wpac, epac, atl, nio, shem. Filter on it to keep to one ocean.philippineName is PAGASA's local name, present only while the storm is in the Philippine Area of Responsibility.meta.stale is true when a source could not be reached and the last good data was served instead.1,000 requests per key per UTC day, and 60 per minute. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; over the limit you get 429 with Retry-After. Storm data changes every few minutes at most, so polling /v1/storms once a minute is plenty. Errors are JSON: {"error": {"code": "…", "message": "…"}}.
Calls from a browser are allowed from any origin. A key in front-end code is visible to anyone who looks; for anything public, call the API from your server.
meta.attribution text wherever the data appears. The data is the agencies'; Bagyo collects it.advisoryUrl on each storm links to its official advisory.