WeatherMax+API

API Reference

WeatherMax API

Base URL https://api.weathermax.app/api. All responses are JSON. Create a key in your dashboard.

Authentication

Send your key on every request. Either header works:

X-API-Key: wmx_live_your_key_here
# or
Authorization: Bearer wmx_live_your_key_here

Example:

curl "https://api.weathermax.app/api/weather?lat=40.71&lon=-74.01" \
  -H "X-API-Key: wmx_live_your_key_here"

On Windows PowerShell use curl.exe — plain curl is an alias for Invoke-WebRequest and won’t accept -H:

curl.exe "https://api.weathermax.app/api/weather?lat=40.71&lon=-74.01" -H "X-API-Key: wmx_live_your_key_here"
const res = await fetch(
  "https://api.weathermax.app/api/weather?lat=40.71&lon=-74.01",
  { headers: { "X-API-Key": process.env.WMX_API_KEY } }
);
const data = await res.json();

Response conventions

These hold everywhere, so the models below only call out where something differs.

  • Units live in the field name. tempF and tempC, windSpeedMph and windSpeedKmh. There is no units parameter and no content negotiation — both are in the payload.
  • Timestamps are ISO 8601. Anything the API computes is UTC with a Z. The exception is alert text passed through from the issuing office, which keeps that office’s local offset.
  • Null means unavailable, not zero. A station reporting no gust returns null for windGustMph. Fall back rather than rendering a 0.
  • Parallel arrays are index-aligned. hourly[i], extendedHourly[i], feelsLikeHourly[i] and aqiHourly[i] all describe the same hour; dailyMetrics[i] matches forecast[i].
  • Fields get added; they don’t change meaning. Parse defensively and ignore keys you don’t recognise. Keys prefixed with an underscore (_source, _forecastUrl) are internal diagnostics that may vanish without notice — don’t build on them.

Endpoints

Every endpoint carries an example response. Field-by-field definitions for the objects inside them are in Models.

Weather

GET/weather
Full weather bundle: current, hourly, 7-day forecast, AQI, pollen, alerts.
Params: lat + lon, or q (place name), city?, state?, countryCode?
Returns: WeatherBundle
Example response (abridged)
{
  "lat": 40.71,
  "lon": -74.01,
  "cityLabel": "New York",
  "stateLabel": "NY",
  "countryCode": "US",
  "cityLabelRoundTrips": true,
  "current":         { … Current },
  "forecast":        [ … 7 × ForecastDay ],
  "hourly":          [ … 24 × HourlyPoint ],
  "extendedHourly":  [ … 24 × ExtendedHour ],
  "feelsLikeHourly": [ 67, 66, 66, … ],
  "dailyMetrics":    [ … 7 × DailyMetrics ],
  "aqiHourly":       [ … 24 × AqiHour ],
  "alerts":          [ … Alert ],
  "astro":           { … Astro },
  "minutely":        { … Minutely },
  "sunrise": "2026-08-29T10:20:00.000Z",
  "sunset":  "2026-08-29T23:33:00.000Z",
  "aqi": 53,
  "aqiPrimary": null,
  "aqiDetails": { "pm25": 16.4, "pm10": 16.7, "ozone": 56,
                  "no2": 38.9, "dust": 0, "co": 249 },
  "pollen": null,
  "uvIndex": 0,
  "histHigh": 81.3,
  "histLow": 64.3
}
GET/weather/quick
Minimal fast payload — current conditions plus sunrise/sunset.
Params: lat + lon, or q (place name)
Returns: QuickWeather — Current, plus sun times and headline AQI
Example response
{
  "lat": 40.71,
  "lon": -74.01,
  "cityLabel": "New York",
  "stateLabel": "NY",
  "countryCode": "US",
  "current": {
    "tempF": 68,
    "tempC": 20,
    "feelsF": 67,
    "humidity": 63,
    "windSpeedMph": 7,
    "windGustMph": 13,
    "windDeg": 228,
    "pressureInHg": 30.18,
    "cloudCoverPct": 0,
    "shortForecast": "Clear",
    "isDaytime": false,
    "weatherCode": 0
  },
  "sunrise": "2026-08-29T10:20:00.000Z",
  "sunset": "2026-08-29T23:33:00.000Z",
  "aqi": 53
}
POST/weather/refresh
Lightweight refresh (forecast, hourly and alerts only).
Params: JSON body: { lat, lon, city?, state? }
Returns: Subset of WeatherBundle
Example response (abridged)
{
  "current":  { … Current },
  "forecast": [ … 7 × ForecastDay ],
  "hourly":   [ … 24 × HourlyPoint ],
  "alerts":   [ … Alert ]
}

Alerts

GET/alerts
Active weather alerts for a point. US and Canada only.
Params: lat, lon, countryCode?
Returns: Alert[] — a bare array, empty when nothing is active
Example response (abridged)
[
  {
    "id": "https://api.weather.gov/alerts/urn:oid:2.49.0.1.840.0.79419…",
    "type": "Feature",
    "geometry": {
      "type": "Polygon",
      "coordinates": [[[-99.66, 45.68], [-99.72, 45.74], … ]]
    },
    "properties": {
      "event": "Severe Thunderstorm Warning",
      "severity": "Severe",
      "certainty": "Observed",
      "urgency": "Immediate",
      "areaDesc": "McPherson, SD",
      "senderName": "NWS Aberdeen SD",
      "headline": "Severe Thunderstorm Warning issued August 29 at 7:12PM CDT…",
      "description": "The National Weather Service in Aberdeen has issued a…",
      "instruction": "Anyone outdoors should move to shelter…",
      "effective": "2026-08-29T19:12:00-05:00",
      "onset":     "2026-08-29T19:12:00-05:00",
      "expires":   "2026-08-29T20:15:00-05:00",
      "ends":      "2026-08-29T20:15:00-05:00",
      "status": "Actual",
      "messageType": "Alert",
      "category": "Met",
      "affectedZones": ["https://api.weather.gov/zones/county/SDC089"],
      "geocode": { "SAME": ["046089"], "UGC": ["SDC089"] },
      "parameters": { "maxHailSize": ["1.75"], "maxWindGust": ["60 MPH"] }
    }
  }
]
GET/national-alerts
Summarized active US Extreme/Severe alerts.
Params:
Returns: NationalAlertSummary
Example response (abridged)
{
  "count": 89,
  "extreme": 0,
  "severe": 47,
  "moderate": 42,
  "affectedStates": ["SD", "UT", "AZ", "MT", "IL", "IN"],
  "topAlerts": [
    {
      "event": "Severe Thunderstorm Warning",
      "severity": "Severe",
      "urgency": "Immediate",
      "headline": "Severe Thunderstorm Warning issued August 29 at 7:12PM CDT…",
      "description": "…",
      "instruction": "…",
      "areaDesc": "McPherson, SD",
      "states": ["SD"],
      "effective": "2026-08-29T19:12:00-05:00",
      "expires":   "2026-08-29T20:15:00-05:00",
      "lat": 45.7814,
      "lon": -99.5843,
      "placeName": "Eureka",
      "placeState": "SD",
      "placeLat": 45.7712,
      "placeLon": -99.6207,
      "parameters": { "maxHailSize": ["1.75"], "maxWindGust": ["60 MPH"] }
    }
  ],
  "fetchedAt": "2026-08-30T00:14:14.071Z"
}
GET/national-alerts/geo
National alerts with polygon geometry (GeoJSON).
Params:
Returns: GeoJSON FeatureCollection — drop straight into a map layer
Example response (abridged)
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [[[-99.66, 45.68], [-99.72, 45.74], … ]]
      },
      "properties": {
        "event": "Severe Thunderstorm Warning",
        "severity": "Severe",
        "urgency": "Immediate",
        "headline": "Severe Thunderstorm Warning issued August 29…",
        "areaDesc": "McPherson, SD",
        "expires": "2026-08-29T20:15:00-05:00",
        "states": ["SD"]
      }
    }
  ]
}

Location

GET/geocode/search
Forward geocoding — place or ZIP to coordinates and labels.
Params: q
Returns: GeocodeResult — one best match, not a list
Example response
{
  "lat": 39.7392,
  "lon": -104.9847,
  "city": "Denver",
  "parentCity": "",
  "state": "Colorado",
  "county": "Denver County",
  "country": "United States",
  "country_code": "US",
  "displayName": "Denver, CO, USA",
  "type": "City",
  "layer": "locality",
  "importance": 1,
  "isPoi": false,
  "results": null
}
GET/geocode/autocomplete
Type-ahead suggestions for a partial query. Debounce it — otherwise this is one call per keystroke.
Params: q (2+ chars), limit? (1–20, default 8)
Returns: GeocodeResult[] — ranked, no results field
Example response (abridged)
[
  {
    "lat": 39.7392,
    "lon": -104.9847,
    "city": "Denver",
    "state": "Colorado",
    "county": "Denver County",
    "country": "United States",
    "country_code": "US",
    "displayName": "Denver, CO, USA",
    "type": "City",
    "layer": "locality",
    "importance": 0.947,
    "isPoi": false
  },
  … up to limit
]
GET/geocode/reverse
Reverse geocoding — coordinates to city and state.
Params: lat, lon
Returns: ReverseGeocodeResult, or null when the point names no place
Example response
{
  "city": "Denver",
  "county": "Denver County",
  "state": "Colorado",
  "country": "United States",
  "country_code": "US"
}
GET/ipweather
Weather for the caller's IP-based location (US).
Params:
Returns: IPWeather
Example response
{
  "lat": 40.7143,
  "lon": -74.006,
  "city": "New York",
  "region": "New York",
  "countryCode": "US",
  "shortForecast": "Mostly Clear",
  "temperature": 68.4,
  "temperatureUnit": "F",
  "isDaytime": false,
  "emoji": "🌙",
  "iconSrc": "/assets/animated/clear-night.svg",
  "windSpeed": "6.8 mph",
  "windDirection": 228,
  "humidity": 63,
  "precipChance": 0
}

Environment

GET/astro
Sun and moon rise/set, moon phase, UV index.
Params: lat, lon, date?
Returns: Astro
Example response
{
  "sun": {
    "sunrise":    "2026-08-29T10:21:28.283Z",
    "sunset":     "2026-08-29T23:35:34.539Z",
    "solarNoon":  "2026-08-29T16:58:31.411Z",
    "firstLight": "2026-08-29T09:53:10.624Z",
    "lastLight":  "2026-08-30T00:03:52.198Z",
    "daylightMinutes": 794
  },
  "moon": {
    "phase": 0.559,
    "phaseName": "Waning Gibbous",
    "illumination": 0.966,
    "moonrise": "2026-08-30T00:03:39.364Z",
    "moonset":  "2026-08-30T12:52:25.560Z",
    "upcoming": [
      { "name": "Last Quarter",  "date": "2026-09-04T06:54:43.789Z" },
      { "name": "New Moon",      "date": "2026-09-11T01:27:55.747Z" },
      { "name": "First Quarter", "date": "2026-09-18T19:46:05.206Z" },
      { "name": "Full Moon",     "date": "2026-09-26T21:33:27.040Z" }
    ]
  }
}
GET/lightning/nearby
Recent cloud-to-ground lightning strikes near a point.
Params: lat, lon, radiusKm?, minutes?
Returns: LightningNearby
Example response (abridged)
{
  "count": 2,
  "windowMinutes": 15,
  "nearest": {
    "lat": 32.812,
    "lon": -97.221,
    "time": "2026-08-30T00:11:52.000Z",
    "distanceKm": 13.4,
    "distanceMi": 8.3,
    "bearing": 47,
    "intensityKa": -18.2,
    "bearingCompass": "NE",
    "secondsAgo": 142
  },
  "strikes": [ … up to 150, nearest first ],
  "fetchedAt": "2026-08-30T00:14:14.071Z"
}
GET/lightpollution
Light-pollution level for a point (NASA VIIRS night-lights) as a 0–100% scale with a label. US only.
Params: lat, lon
Returns: LightPollution
Example response
{
  "radiance": 118.42,
  "percent": 96,
  "label": "City core"
}

Looking up by place name

/weather and /weather/quick take q in place of lat/lon — a city, address or postal code. We geocode it server-side, so you don’t need a separate /geocode/search call first.

curl "https://api.weathermax.app/api/weather?q=Dallas,%20TX" \
  -H "X-API-Key: wmx_live_your_key_here"

The response carries a resolved block naming the point the query landed on, so you can show it, log it, or reject it:

{
  "resolved": {
    "query": "Dallas, TX",
    "lat": 32.7763,
    "lon": -96.7969,
    "city": "Dallas",
    "state": "Texas",
    "countryCode": "US",
    "type": "City",
    "displayName": "Dallas, Dallas County, Texas, United States"
  },
  "current": { ... },
  "forecast": [ ... ]
}

A name that doesn’t resolve confidently returns 404 rather than a nearby guess — a misspelled city never silently becomes a forecast for somewhere else. If your users need to pick between matches before you commit, use /geocode/autocomplete and send coordinates.

A q request is billed as a geocode plus a weather call. Coordinates remain the cheapest and fastest path, and always take precedence when you send them.

Models

The objects the endpoints return. Each is defined once here; an endpoint that embeds one references it by name.

WeatherBundleTop level of GET /weather.
FieldTypeDescription
lat, lonnumberPoint the forecast was produced for.
cityLabel, stateLabelstringResolved place labels. Empty string when nothing resolved.
countryCodestringUS or CA.
cityLabelRoundTripsbooleanTrue when re-geocoding cityLabel lands back on this point — a hint that the label is safe to put in a shareable URL.
currentCurrentBlended present conditions.
forecastForecastDay[7]Day and night in one object per day, starting today.
hourlyHourlyPoint[24]Next 24 hours of narrative conditions.
extendedHourlyExtendedHour[24]The same 24 hours as model metrics. Index-aligned with hourly.
feelsLikeHourlynumber[24]Apparent temperature °F, index-aligned with hourly.
dailyMetricsDailyMetrics[7]Model aggregates, index-aligned with forecast.
aqiHourlyAqiHour[24]Hourly air quality, index-aligned with hourly.
alertsAlert[]Active alerts for the point. Empty array when none.
astroAstroSun and moon detail for today.
minutelyMinutely15-minute precipitation series.
sunrise, sunsetstringISO 8601 UTC.
aqinumber | nullHeadline US AQI — from an EPA ground monitor when one is near, otherwise modelled.
aqiPrimarystring | nullPollutant driving the headline AQI. Only ground-monitor readings report it.
aqiDetailsobjectCurrent concentrations: pm25, pm10, ozone, no2, dust, co.
pollenobject | nullgrass, tree, weed counts. Null outside the pollen model coverage.
uvIndexnumberCurrent UV index.
histHigh, histLownumberClimate normal high and low °F for this date at this point.
resolvedobjectPresent only when the request used q=. See Looking up by place name.
CurrentPresent conditions, blended from station observations and model output.
FieldTypeDescription
tempF, tempCnumberAir temperature.
feelsFnumberApparent temperature °F.
humiditynumberRelative humidity %.
windSpeedMph, windSpeedKmhnumber | nullSustained wind.
windGustMphnumber | nullGust. Null when the station reports none.
windDeg, windDirDegnumber | nullDirection the wind blows from, degrees.
windForecastSpeed, windForecastDirstring | nullForecast wind as text ("7 mph", "SW") — a fallback for stations that report no wind.
visMinumber | nullVisibility, miles.
pressureInHg, pressureMslInHgnumber | nullStation and sea-level pressure, inHg.
dewF, dewCnumber | nullDew point.
cloudCoverPctnumber | nullSky cover %.
precipNowMmnumber | nullPrecipitation rate, mm/h.
weatherCodenumberWMO weather code.
shortForecaststringHuman label, e.g. "Clear", "Light Rain".
isDaytimebooleanWhether the sun is up. Pick day or night iconography from this, not from the clock.
observedobject | nullProvenance of the observation reality check: source, station, stationName, distanceMi, timestamp, ageMin, textDescription, modelSaid, and applied (none, agree, sky, precip, fog, lightning, precip-cleared, kept-model-precip) naming which observation overrode the model, if any.
alertOverridestring | nullHazard headline derived from an active Extreme or Severe alert, e.g. "Thunderstorm Warning". Show it above shortForecast when set.
ForecastDayOne calendar day. Day and night ride in the same object.
FieldTypeDescription
namestringDay label, e.g. "Saturday" or "Today".
hi, lonumberHigh and low.
hiUnit, loUnitstringF or C.
shortForecaststringDaytime summary.
detailedForecaststringFull narrative for the day.
emojistringCondition emoji for the day.
precipnumberDaytime chance of precipitation %.
isDaytimebooleanFalse on the first entry once the day period has already passed.
nightNamestringNight label, e.g. "Tonight".
nightShortForecaststringNight summary.
nightDetailedForecaststringFull narrative for the night.
nightPrecipnumberOvernight chance of precipitation %.
HourlyPointOne hour of narrative conditions.
FieldTypeDescription
timestringISO 8601 UTC, top of the hour.
tempnumberTemperature.
tempUnitstringF or C.
shortForecaststringCondition label.
emojistringCondition emoji.
precipnumberChance of precipitation %.
windSpeedstringFormatted wind, e.g. "7 mph".
windDirectionstring | nullCompass direction, e.g. "SW".
humiditynumberRelative humidity %.
dewpointCnumberDew point °C.
isDaytimebooleanSun up during this hour.
ExtendedHourModel metrics for the same hour as hourly[i]. No labels — pair it with HourlyPoint by index.
FieldTypeDescription
feelsLikeF, dewpointFnumberApparent temperature and dew point, °F.
humidity, cloudCovernumberPercent.
cloudCoverLow, cloudCoverMid, cloudCoverHighnumberSky cover by layer, %.
visibilityMinumberVisibility, miles.
pressureInHg, pressureMslInHgnumberSurface and sea-level pressure.
uvIndex, uvClearSkynumberActual and clear-sky UV index.
precipMm, rainMmnumberTotal and liquid precipitation for the hour.
snowfallCm, snowDepthInnumberNew snow and snow already on the ground.
windSpeedMph, windGustsMph, windDirDegnumberWind.
capenumberConvective available potential energy, J/kg — a severe-storm ingredient.
freezingLevelFtnumberHeight of the 0 °C isotherm.
vpdnumberVapour pressure deficit, kPa.
weatherCodenumberWMO weather code.
isDaytimebooleanSun up during this hour.
DailyMetricsModel aggregates for the same day as forecast[i].
FieldTypeDescription
tempHi, tempLo, feelsHi, feelsLonumberTemperature extremes, °F.
humidityHi, humidityLo, dewpointHi, dewpointLonumberHumidity % and dew point °F extremes.
cloudCoverHi, cloudCoverLo, visibilityHi, visibilityLonumberSky cover % and visibility miles.
pressureHi, pressureLo, pressureMslHi, pressureMslLonumberPressure extremes, inHg.
precipSum, rainSumMm, snowfallSumCmnumberDaily totals.
precipProbMax, precipHoursnumberPeak chance of precipitation % and hours with precipitation.
windSpeedMax, windGustsMax, windDirDominantnumberWind peaks and dominant direction.
uvMax, uvClearSkyMaxnumberPeak UV index.
radiationSumMJ, daylightSec, sunshineSecnumberShortwave radiation total, and daylight and sunshine duration.
sunriseDt, sunsetDtstringISO 8601 UTC.
weatherCodenumberRepresentative WMO code for the day.
AqiHourOne hour of air quality, index-aligned with hourly.
FieldTypeDescription
timestringISO 8601 UTC.
aqinumberUS AQI for the hour.
pm25, pm10, ozone, no2, dustnumberConcentrations, µg/m³.
pm25Index, pm10Index, o3IndexnumberPer-pollutant sub-indices. The largest is what drives aqi.
MinutelyParallel arrays, not an array of objects — index i of each describes the same instant.
FieldTypeDescription
timestring[]ISO 8601 UTC at 15-minute steps.
precipitationnumber[]Rate, in precipUnit.
weather_codenumber[]WMO weather code.
precipUnitstringAlways "mm/h".
utcOffsetSecondsnumberThe point's local UTC offset, for rendering local labels.
AstroReturned by GET /astro and embedded in the weather bundle.
FieldTypeDescription
sun.sunrise, sun.sunset, sun.solarNoonstringISO 8601 UTC.
sun.firstLight, sun.lastLightstringCivil twilight bounds.
sun.daylightMinutesnumberMinutes of daylight.
moon.phasenumber0–1, where 0 and 1 are new moon and 0.5 is full.
moon.phaseNamestringe.g. "Waning Gibbous".
moon.illuminationnumber0–1 fraction of the disc lit.
moon.moonrise, moon.moonsetstring | nullISO 8601 UTC. Null on a day the moon does not rise or set.
moon.upcomingarrayThe next four quarter phases as { name, date }.
AlertA GeoJSON Feature passed through from the issuing agency with its fields intact, so it can go straight onto a map.
FieldTypeDescription
idstringStable alert URN.
geometryobject | nullPolygon or MultiPolygon. Null on zone-based alerts — resolve properties.affectedZones for their shapes.
properties.eventstringe.g. "Tornado Warning".
properties.severitystringExtreme, Severe, Moderate, Minor or Unknown.
properties.urgency, properties.certaintystringImmediate / Expected / Future, and Observed / Likely / Possible.
properties.headline, description, instructionstringIssuing office text. instruction is the protective-action advice.
properties.areaDescstringPlain-language county and zone list.
properties.effective, onset, expires, endsstringISO 8601 in the issuing office's offset, not UTC.
properties.affectedZonesstring[]Zone URLs, for alerts that carry no polygon.
properties.parametersobjectAgency extras — every value is an array. Useful keys: maxHailSize, maxWindGust, tornadoDetection, eventMotionDescription.
GeocodeResultOne best match. Search auto-picks rather than making you disambiguate.
FieldTypeDescription
lat, lonnumberCoordinates to feed back into /weather.
citystringDisplay label. On an address hit this is the street line — which is what lets a shared address link resolve back to the same point instead of collapsing to the city centroid.
parentCitystringEnclosing city when the hit is a POI or address.
state, county, countrystringSpelled out, not abbreviated.
country_codestringISO 3166-1 alpha-2.
displayNamestringFull comma-separated label.
typestringFriendly kind, e.g. City, Town, ZIP code, Landmark.
layerstringRaw provider layer: locality, localadmin, postalcode, venue, address.
importancenumber0–1 confidence.
isPoibooleanTrue for venues and landmarks rather than inhabited places.
resultsnullReserved for a future multi-result mode; always null today. Absent on autocomplete.

Rate limits & quotas

Every response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Policy. On a 429, honour Retry-After rather than retrying immediately.

PlanMonthly quotaRate limit
Free5,000 / mo30 / min
Starter100,000 / mo120 / min
Pro2,000,000 / mo600 / min

Errors

Every failure is the same shape — one error string, carrying the HTTP status:

{ "error": "lat and lon are required" }
401Missing, invalid, or suspended API key.
403Request rejected — no credential and no trusted origin.
429Rate limit or monthly quota exceeded — see Retry-After.
400Missing or invalid parameters (for example lat/lon).
404No location matched q — refine the query or send coordinates.
501Requested outside supported coverage (US and Canada).
502 / 504Upstream weather source temporarily unavailable — retry.

Attribution

Some of the data behind this API is published under licences that require credit wherever the data is displayed — which includes your app, not just ours. If you show forecasts, alerts or geocoded place names to end users, include the following somewhere visible (an About screen or footer is fine):

Weather data from the National Weather Service,
Environment and Climate Change Canada and Open-Meteo.
Geocoding from OpenStreetMap contributors.
SourceLicenceCredit required
National Weather ServiceUS Government — public domainNo (appreciated)
Environment and Climate Change CanadaOpen Government Licence — CanadaYes
Open-MeteoCC BY 4.0Yes
OpenStreetMap (geocoding)ODbLYes

One limit worth knowing: geocoding results are licensed for per-query lookup. Systematically extracting them to build your own place database would create a derivative database under ODbL, with share-alike obligations — that is not permitted under these Terms.

Coverage

Forecasts and alerts cover the United States and Canada. US alerts come from the National Weather Service and Canadian alerts from Environment Canada — both authoritative sources rather than model output. Requests for points outside that area return 501 on the alerts endpoint.

Need a key? See plans & get access →