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): jtwc or jma. The two track their own sets of storms independently.
  • include_invests (optional, default true): set to false to exclude "invests" (is_invest: true, see below) from the results array.

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" }