GET https://aceofcanes.com/api/v1/season.json
One file with both basins’ current season: ACE total, NOAA classification, storm counts, rank since 1991, every named storm with its landfalls and track, and the ACE of every season since 1991. It is rebuilt with the site, about once an hour during the season. No key, no sign-up, CORS-friendly static file.
url links to its page on this site, which is handy for linking back.The /api/v1/ shape is a public contract. New fields can be added to v1 at any time, so ignore fields you don’t know.
A field will never be renamed or removed in v1: that ships as a new /api/v2/ path, and v1 keeps working.
curl -s https://aceofcanes.com/api/v1/season.json | jq '.basins.atlantic | {ace_total, classification, rank}'
const res = await fetch('https://aceofcanes.com/api/v1/season.json');
const data = await res.json();
const atl = data.basins.atlantic;
console.log(`${atl.year} Atlantic ACE: ${atl.ace_total} (${atl.classification})`);
import requests
data = requests.get('https://aceofcanes.com/api/v1/season.json', timeout=10).json()
for s in data['basins']['atlantic']['storms']:
print(s['name'], s['ace'], s['category'])
<basin> is atlantic or pacific; [] means each item of an array.
| Field | Type | Description |
|---|---|---|
version | integer | Schema version. Always 1 at this URL. |
generated_at | string | UTC time the file was built, ISO 8601 (2026-09-20T12:00:00Z). |
source | string | Where the data comes from. |
site | string | Site URL. |
note | string | The preliminary-data caveat, in plain text. |
basins | object | One entry per basin, keyed atlantic and pacific (East & Central Pacific). |
basins.<basin>.name | string | Display name of the basin. |
basins.<basin>.year | integer | Season year. |
basins.<basin>.preseason | boolean | true before the season has any named storm. |
basins.<basin>.is_backup_data | boolean | true when the live fetch failed and the numbers are a stored fallback. |
basins.<basin>.data_as_of | string | Time of the latest storm data point, ISO 8601 UTC. Can be empty. |
basins.<basin>.ace_total | number | Season ACE so far, 2 decimals. |
basins.<basin>.normal_ace | number | 1991–2020 average season ACE for the basin. |
basins.<basin>.pct_of_normal | number | ace_total as a percent of normal_ace, 1 decimal. |
basins.<basin>.classification | string | NOAA class: Below Normal, Near Normal, Above Normal or Extremely Active. |
basins.<basin>.named_storms | integer | Named storms so far. |
basins.<basin>.hurricanes | integer | Hurricanes so far. |
basins.<basin>.major_hurricanes | integer | Category 3+ hurricanes so far. |
basins.<basin>.rank | integer | Rank of this season’s ACE among all seasons since 1991 (1 = highest). |
basins.<basin>.seasons_ranked | integer | How many seasons rank is out of. |
basins.<basin>.storms | array | Named storms this season. |
basins.<basin>.storms[].name | string | Storm name. |
basins.<basin>.storms[].slug | string | URL-safe id, unique within the season. |
basins.<basin>.storms[].url | string | The storm’s page on this site. |
basins.<basin>.storms[].ace | number | Storm ACE, 2 decimals. |
basins.<basin>.storms[].pct_of_season | number | Share of the season’s ACE, 1 decimal. |
basins.<basin>.storms[].max_wind_kt | integer | Peak sustained wind in knots. |
basins.<basin>.storms[].category | string | Peak category: TS, Cat 1 … Cat 5. |
basins.<basin>.storms[].is_major | boolean | Reached Category 3 or higher. |
basins.<basin>.storms[].is_active | boolean | Still active at build time. |
basins.<basin>.storms[].start_date | string | Formation date as M/D in the season year; — if unknown. |
basins.<basin>.storms[].landfalls | array | Landfalls, in order. Empty if none. |
basins.<basin>.storms[].landfalls[].location | string | Where it made landfall. |
basins.<basin>.storms[].landfalls[].category | string | Category at landfall, not at peak. |
basins.<basin>.storms[].landfall_estimated | boolean | true when landfall was estimated from the track instead of the NHC record. |
basins.<basin>.storms[].track | array | Track points, oldest first. |
basins.<basin>.storms[].track[].lat | number | Latitude, degrees north. |
basins.<basin>.storms[].track[].lon | number | Longitude, degrees east (negative = west). |
basins.<basin>.storms[].track[].wind_kt | integer | Sustained wind in knots. |
basins.<basin>.storms[].track[].status | string | HURDAT2 status code (DB, TD, TS, HU, SS, EX, …). Only TS, SS and HU count toward ACE. |
basins.<basin>.storms[].track[].time | string | Time of the point as M/D HHZ in UTC (10/5 00Z). |
basins.<basin>.yearly_ace | object | Season ACE for every year since 1991, keyed by year as a string. |
https://aceofcanes.com/feed.xml
One item per named storm in both basins, newest first, with its ACE, peak intensity and landfalls.
Each storm keeps the same guid, so your reader announces it once and the description updates as the storm grows.
Data: NOAA National Hurricane Center HURDAT2 and real-time best track, via Tropycal. NOAA data is public domain; please credit NOAA NHC, and a link back to aceofcanes.com is appreciated.
This site is maintained by a hurricane data enthusiast, not a meteorologist. For forecasts, watches and warnings, always use the National Hurricane Center.