Requesting Storm Data
The API also exposes an endpoint to fetch currently active tropical storms/cyclones tracked worldwide, including their observed track, forecast track, and forecast cone. This is separate from the /MetOcean endpoints and has its own request/response format, described below.
API Endpoint: GET /storms
Making a Request
Unlike /MetOcean, this endpoint takes no JSON payload: there are no points, variables, or other body parameters to specify. It takes two query parameters:
provider(required):jtwcorjma. The two track their own sets of storms independently.include_invests(optional, defaulttrue): set tofalseto exclude "invests" (is_invest: true, see below) from theresultsarray.
Authenticate with your API key and GET the endpoint:
import requests
import json
base_url = 'https://api.amphitrite.fr'
api_key = 'YOUR_API_KEY_HERE'
headers = {
"x-api-key": api_key
}
response = requests.get(f"{base_url}/storms", headers=headers, params={"provider": "jtwc", "include_invests": False})
if response.status_code == 200:
result = response.json()
print(f"{len(result['results'])} active storm(s)")
print(json.dumps(result, indent=2))
else:
print(f"Request failed with status code: {response.status_code}")
print(response.text)
Response Format
The response is a JSON object with a single results array, containing one entry per currently active storm. If no storms are active, results is an empty array; there is no task_id/status/error envelope like the /MetOcean endpoints use.
{
"results": [
{
"schema_version": "1.0",
"generated_at": 1721908800,
"provider": "jtwc",
"id": "AL092025",
"name": "HELENE",
"year": 2025,
"basin": "north_atlantic",
"is_active": true,
"is_invest": false,
"units": {
"vmax_kt": "knots",
"mslp_hpa": "hPa",
"speed_kmh": "km/h",
"heading_deg": "degrees",
"wind_radii_km": "km",
"cone_radius_km": "km"
},
"track_bbox": { "s": 14.2, "n": 32.8, "w": -86.5, "e": -70.1 },
"cone": {
"basin": "north_atlantic",
"source": "nhc",
"year": 2025,
"radii_table_km": { "12": 65, "24": 100, "36": 140, "48": 180 },
"circles": [
{ "fhr": 12, "lat": 26.4, "lon": -83.2, "r_km": 65 },
{ "fhr": 24, "lat": 27.9, "lon": -85.0, "r_km": 100 }
],
"center_line": [
{ "lat": 25.1, "lon": -81.6 },
{ "lat": 27.9, "lon": -85.0 }
],
"envelope_polygon": [
{ "lat": 24.5, "lon": -82.0 },
{ "lat": 28.6, "lon": -85.9 },
{ "lat": 26.0, "lon": -80.5 }
],
"source_basin": null
},
"tracks": {
"observed": [
{
"time": 1721880000,
"lat": 22.8,
"lon": -78.4,
"vmax_kt": 45,
"mslp_hpa": 1002,
"type": "TS",
"category": 0,
"heading_deg": 315,
"speed_kmh": 19,
"wind_radii_km": {
"34kn": { "ne": 110, "se": 90, "sw": 70, "nw": 85 },
"50kn": null,
"64kn": null
},
"affectance_bbox": { "s": 20.5, "n": 25.1, "w": -80.9, "e": -75.9 },
"affectance_bbox_estimated": false
}
],
"forecast": {
"issued_at": 1721890800,
"cone_source": "nhc",
"points": [
{
"time": 1721890800,
"lat": 25.1,
"lon": -81.6,
"vmax_kt": 65,
"mslp_hpa": 985,
"type": "HU",
"category": 1,
"heading_deg": 330,
"speed_kmh": 22,
"wind_radii_km": {
"34kn": { "ne": 150, "se": 120, "sw": 95, "nw": 110 },
"50kn": { "ne": 60, "se": 45, "sw": 35, "nw": 40 },
"64kn": null
},
"affectance_bbox": { "s": 22.6, "n": 27.6, "w": -84.1, "e": -79.1 },
"affectance_bbox_estimated": false,
"fhr": 0,
"cone_radius_km": null
},
{
"time": 1721934000,
"lat": 27.9,
"lon": -85.0,
"vmax_kt": 80,
"mslp_hpa": 970,
"type": "HU",
"category": 2,
"heading_deg": 340,
"speed_kmh": 24,
"wind_radii_km": null,
"affectance_bbox": { "s": 24.9, "n": 30.9, "w": -89.0, "e": -81.0 },
"affectance_bbox_estimated": true,
"fhr": 12,
"cone_radius_km": 65
}
]
}
}
}
]
}
Top-Level Storm Fields
| Field | Description |
|---|---|
provider |
Data provider this storm was sourced from: "jtwc" or "jma". Matches the provider you queried with. |
id |
Storm identifier, e.g. "WP122026" (basin prefix + storm number + season year). |
name |
Storm name. null for some jma invests that have not yet been named. |
year |
Season year. |
basin |
One of "north_atlantic", "east_pacific", "west_pacific", ... |
is_active |
true while the storm is being tracked/forecast; false once it has dissipated. |
is_invest |
true if this is an "invest" (pre-depression area of interest) rather than a named/numbered system. |
generated_at |
Unix timestamp (seconds, UTC) when this storm's data file was generated. |
track_bbox |
Bounding box covering the full observed + forecast track. w > e means the box crosses the antimeridian (180°). |
units |
Human-readable unit legend for the numeric fields below (informational only). |
cone |
Forecast cone data, present only while a forecast exists (see below). |
tracks |
Observed and forecast track points (see below). |
Track Points (tracks.observed / tracks.forecast.points)
Each track point shares this structure:
| Field | Description |
|---|---|
time |
Unix timestamp (seconds, UTC) of this track point. |
lat / lon |
Storm center coordinates, in degrees. |
vmax_kt |
Maximum sustained wind speed, in knots. null before the provider has assigned an intensity estimate (e.g. jma invests). jma reports a 10-minute mean wind, vs. jtwc's 1-minute mean — not directly comparable across providers. |
mslp_hpa |
Minimum sea-level pressure, in hPa. Often null on forecast points, which the provider does not always report. |
type |
Storm classification code: "DB" (disturbance), "TD" (tropical depression), "TS" (tropical storm), "HU" (storm/typhoon), "PT" (post-tropical), "LO" (low). Can be null on some forecast points, or on jma invests. |
category |
Saffir-Simpson category: 0 below storm strength (TD/TS/PT/LO/DB), 1-5 for storm/typhoon intensity. null when vmax_kt is null. |
heading_deg |
True bearing of storm motion, in degrees (0=N, 90=E). null when there is no earlier fix to compute motion from (e.g. a storm's very first observed point). |
speed_kmh |
Forward (translation) speed of the storm center, in km/h. null when there is no earlier fix to compute motion from (e.g. a storm's very first observed point). |
wind_radii_km |
Per-quadrant (ne/se/sw/nw) radii in km, keyed by wind threshold. jtwc reports "34kn"/"50kn"/"64kn"; jma reports "30kn"/"50kn" instead of "34kn" ("64kn" always null) and gives one range per named area rather than four independent quadrants, so all four quadrants carry the same value. Any threshold can be null when the provider reports no data for it. |
affectance_bbox |
Bounding box of the area affected by this track point. Always present. |
affectance_bbox_estimated |
true when affectance_bbox is an ESTIMATE (vmax-scaled fallback, used when the provider's lowest wind radii threshold — 34kt for jtwc, 30kt for jma — is null); false when computed from real wind radii. |
Forecast points additionally include:
| Field | Description |
|---|---|
fhr |
Forecast hour offset from issuance (e.g. 0, 12, 24, ..., 120). |
cone_radius_km |
Forecast cone radius, in km, at this forecast hour. Absent at fhr=0. |
tracks.forecast itself also carries issued_at (Unix timestamp when the forecast was issued) and cone_source ("nhc" if this basin has its own official cone table, "borrowed_nhc" if another basin's table was borrowed — see cone.source_basin — or "jma" for JMA's own forecast-error probability circle). tracks.forecast is absent once the storm is no longer active.
Forecast Cone (cone)
| Field | Description |
|---|---|
basin |
Basin this cone was computed for. |
source |
"nhc" = this basin's own official cone table; "borrowed_nhc" = no official table for this basin, so source_basin's real NHC table is used instead; "jma" = JMA's own official forecast-error probability circle. |
source_basin |
Basin whose cone table was borrowed. Set only when source is "borrowed_nhc". |
year |
Year of the cone radii table used (may differ from the storm's own year if reusing a fixed historical table). Always null when source is "jma", which has no such table. |
radii_table_km |
Cone radius in km, keyed by forecast hour string (e.g. "12", "24", ...). Always null when source is "jma", which has no such table. |
circles |
Raw (pre-simplification) cone circles, one per forecast hour: {fhr, lat, lon, r_km}. |
center_line |
RDP-simplified polyline ({lat, lon} points) of the forecast track center line, ready to plot. |
envelope_polygon |
RDP-simplified polygon ({lat, lon} points) of the full cone envelope, ready to plot. Always null when source is "jma", which does not compute a grid/contour envelope -- use circles and center_line instead. |
Errors
The endpoint follows the same authentication and rate-limiting rules as the other endpoints. See Authentication.
// 401 - Invalid API key
{ "detail": "Invalid API key" }
// 403 - Missing x-api-key header
{ "detail": "Not authenticated" }
// 422 - Missing or invalid `provider` query parameter (must be "jtwc" or "jma")
{ "detail": [...] }
// 429 - Rate limit exceeded
{ "error": "Rate limit exceeded: 10 per 1 minute" }