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.
tempFandtempC,windSpeedMphandwindSpeedKmh. 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
nullforwindGustMph. Fall back rather than rendering a 0. - Parallel arrays are index-aligned.
hourly[i],extendedHourly[i],feelsLikeHourly[i]andaqiHourly[i]all describe the same hour;dailyMetrics[i]matchesforecast[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
/weatherlat + lon, or q (place name), city?, state?, countryCode?WeatherBundleExample 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
}/weather/quicklat + lon, or q (place name)QuickWeather — Current, plus sun times and headline AQIExample 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
}/weather/refreshJSON body: { lat, lon, city?, state? }Subset of WeatherBundleExample response (abridged)
{
"current": { … Current },
"forecast": [ … 7 × ForecastDay ],
"hourly": [ … 24 × HourlyPoint ],
"alerts": [ … Alert ]
}Alerts
/alertslat, lon, countryCode?Alert[] — a bare array, empty when nothing is activeExample 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"] }
}
}
]/national-alerts—NationalAlertSummaryExample 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"
}/national-alerts/geo—GeoJSON FeatureCollection — drop straight into a map layerExample 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
/geocode/searchqGeocodeResult — one best match, not a listExample 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
}/geocode/autocompleteq (2+ chars), limit? (1–20, default 8)GeocodeResult[] — ranked, no results fieldExample 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
]/geocode/reverselat, lonReverseGeocodeResult, or null when the point names no placeExample response
{
"city": "Denver",
"county": "Denver County",
"state": "Colorado",
"country": "United States",
"country_code": "US"
}/ipweather—IPWeatherExample 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
/astrolat, lon, date?AstroExample 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" }
]
}
}/lightning/nearbylat, lon, radiusKm?, minutes?LightningNearbyExample 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"
}/lightpollutionlat, lonLightPollutionExample 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.
| Field | Type | Description |
|---|---|---|
| lat, lon | number | Point the forecast was produced for. |
| cityLabel, stateLabel | string | Resolved place labels. Empty string when nothing resolved. |
| countryCode | string | US or CA. |
| cityLabelRoundTrips | boolean | True when re-geocoding cityLabel lands back on this point — a hint that the label is safe to put in a shareable URL. |
| current | Current | Blended present conditions. |
| forecast | ForecastDay[7] | Day and night in one object per day, starting today. |
| hourly | HourlyPoint[24] | Next 24 hours of narrative conditions. |
| extendedHourly | ExtendedHour[24] | The same 24 hours as model metrics. Index-aligned with hourly. |
| feelsLikeHourly | number[24] | Apparent temperature °F, index-aligned with hourly. |
| dailyMetrics | DailyMetrics[7] | Model aggregates, index-aligned with forecast. |
| aqiHourly | AqiHour[24] | Hourly air quality, index-aligned with hourly. |
| alerts | Alert[] | Active alerts for the point. Empty array when none. |
| astro | Astro | Sun and moon detail for today. |
| minutely | Minutely | 15-minute precipitation series. |
| sunrise, sunset | string | ISO 8601 UTC. |
| aqi | number | null | Headline US AQI — from an EPA ground monitor when one is near, otherwise modelled. |
| aqiPrimary | string | null | Pollutant driving the headline AQI. Only ground-monitor readings report it. |
| aqiDetails | object | Current concentrations: pm25, pm10, ozone, no2, dust, co. |
| pollen | object | null | grass, tree, weed counts. Null outside the pollen model coverage. |
| uvIndex | number | Current UV index. |
| histHigh, histLow | number | Climate normal high and low °F for this date at this point. |
| resolved | object | Present only when the request used q=. See Looking up by place name. |
CurrentPresent conditions, blended from station observations and model output.
| Field | Type | Description |
|---|---|---|
| tempF, tempC | number | Air temperature. |
| feelsF | number | Apparent temperature °F. |
| humidity | number | Relative humidity %. |
| windSpeedMph, windSpeedKmh | number | null | Sustained wind. |
| windGustMph | number | null | Gust. Null when the station reports none. |
| windDeg, windDirDeg | number | null | Direction the wind blows from, degrees. |
| windForecastSpeed, windForecastDir | string | null | Forecast wind as text ("7 mph", "SW") — a fallback for stations that report no wind. |
| visMi | number | null | Visibility, miles. |
| pressureInHg, pressureMslInHg | number | null | Station and sea-level pressure, inHg. |
| dewF, dewC | number | null | Dew point. |
| cloudCoverPct | number | null | Sky cover %. |
| precipNowMm | number | null | Precipitation rate, mm/h. |
| weatherCode | number | WMO weather code. |
| shortForecast | string | Human label, e.g. "Clear", "Light Rain". |
| isDaytime | boolean | Whether the sun is up. Pick day or night iconography from this, not from the clock. |
| observed | object | null | Provenance 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. |
| alertOverride | string | null | Hazard 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.
| Field | Type | Description |
|---|---|---|
| name | string | Day label, e.g. "Saturday" or "Today". |
| hi, lo | number | High and low. |
| hiUnit, loUnit | string | F or C. |
| shortForecast | string | Daytime summary. |
| detailedForecast | string | Full narrative for the day. |
| emoji | string | Condition emoji for the day. |
| precip | number | Daytime chance of precipitation %. |
| isDaytime | boolean | False on the first entry once the day period has already passed. |
| nightName | string | Night label, e.g. "Tonight". |
| nightShortForecast | string | Night summary. |
| nightDetailedForecast | string | Full narrative for the night. |
| nightPrecip | number | Overnight chance of precipitation %. |
HourlyPointOne hour of narrative conditions.
| Field | Type | Description |
|---|---|---|
| time | string | ISO 8601 UTC, top of the hour. |
| temp | number | Temperature. |
| tempUnit | string | F or C. |
| shortForecast | string | Condition label. |
| emoji | string | Condition emoji. |
| precip | number | Chance of precipitation %. |
| windSpeed | string | Formatted wind, e.g. "7 mph". |
| windDirection | string | null | Compass direction, e.g. "SW". |
| humidity | number | Relative humidity %. |
| dewpointC | number | Dew point °C. |
| isDaytime | boolean | Sun up during this hour. |
ExtendedHourModel metrics for the same hour as hourly[i]. No labels — pair it with HourlyPoint by index.
| Field | Type | Description |
|---|---|---|
| feelsLikeF, dewpointF | number | Apparent temperature and dew point, °F. |
| humidity, cloudCover | number | Percent. |
| cloudCoverLow, cloudCoverMid, cloudCoverHigh | number | Sky cover by layer, %. |
| visibilityMi | number | Visibility, miles. |
| pressureInHg, pressureMslInHg | number | Surface and sea-level pressure. |
| uvIndex, uvClearSky | number | Actual and clear-sky UV index. |
| precipMm, rainMm | number | Total and liquid precipitation for the hour. |
| snowfallCm, snowDepthIn | number | New snow and snow already on the ground. |
| windSpeedMph, windGustsMph, windDirDeg | number | Wind. |
| cape | number | Convective available potential energy, J/kg — a severe-storm ingredient. |
| freezingLevelFt | number | Height of the 0 °C isotherm. |
| vpd | number | Vapour pressure deficit, kPa. |
| weatherCode | number | WMO weather code. |
| isDaytime | boolean | Sun up during this hour. |
DailyMetricsModel aggregates for the same day as forecast[i].
| Field | Type | Description |
|---|---|---|
| tempHi, tempLo, feelsHi, feelsLo | number | Temperature extremes, °F. |
| humidityHi, humidityLo, dewpointHi, dewpointLo | number | Humidity % and dew point °F extremes. |
| cloudCoverHi, cloudCoverLo, visibilityHi, visibilityLo | number | Sky cover % and visibility miles. |
| pressureHi, pressureLo, pressureMslHi, pressureMslLo | number | Pressure extremes, inHg. |
| precipSum, rainSumMm, snowfallSumCm | number | Daily totals. |
| precipProbMax, precipHours | number | Peak chance of precipitation % and hours with precipitation. |
| windSpeedMax, windGustsMax, windDirDominant | number | Wind peaks and dominant direction. |
| uvMax, uvClearSkyMax | number | Peak UV index. |
| radiationSumMJ, daylightSec, sunshineSec | number | Shortwave radiation total, and daylight and sunshine duration. |
| sunriseDt, sunsetDt | string | ISO 8601 UTC. |
| weatherCode | number | Representative WMO code for the day. |
AqiHourOne hour of air quality, index-aligned with hourly.
| Field | Type | Description |
|---|---|---|
| time | string | ISO 8601 UTC. |
| aqi | number | US AQI for the hour. |
| pm25, pm10, ozone, no2, dust | number | Concentrations, µg/m³. |
| pm25Index, pm10Index, o3Index | number | Per-pollutant sub-indices. The largest is what drives aqi. |
MinutelyParallel arrays, not an array of objects — index i of each describes the same instant.
| Field | Type | Description |
|---|---|---|
| time | string[] | ISO 8601 UTC at 15-minute steps. |
| precipitation | number[] | Rate, in precipUnit. |
| weather_code | number[] | WMO weather code. |
| precipUnit | string | Always "mm/h". |
| utcOffsetSeconds | number | The point's local UTC offset, for rendering local labels. |
AstroReturned by GET /astro and embedded in the weather bundle.
| Field | Type | Description |
|---|---|---|
| sun.sunrise, sun.sunset, sun.solarNoon | string | ISO 8601 UTC. |
| sun.firstLight, sun.lastLight | string | Civil twilight bounds. |
| sun.daylightMinutes | number | Minutes of daylight. |
| moon.phase | number | 0–1, where 0 and 1 are new moon and 0.5 is full. |
| moon.phaseName | string | e.g. "Waning Gibbous". |
| moon.illumination | number | 0–1 fraction of the disc lit. |
| moon.moonrise, moon.moonset | string | null | ISO 8601 UTC. Null on a day the moon does not rise or set. |
| moon.upcoming | array | The 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.
| Field | Type | Description |
|---|---|---|
| id | string | Stable alert URN. |
| geometry | object | null | Polygon or MultiPolygon. Null on zone-based alerts — resolve properties.affectedZones for their shapes. |
| properties.event | string | e.g. "Tornado Warning". |
| properties.severity | string | Extreme, Severe, Moderate, Minor or Unknown. |
| properties.urgency, properties.certainty | string | Immediate / Expected / Future, and Observed / Likely / Possible. |
| properties.headline, description, instruction | string | Issuing office text. instruction is the protective-action advice. |
| properties.areaDesc | string | Plain-language county and zone list. |
| properties.effective, onset, expires, ends | string | ISO 8601 in the issuing office's offset, not UTC. |
| properties.affectedZones | string[] | Zone URLs, for alerts that carry no polygon. |
| properties.parameters | object | Agency extras — every value is an array. Useful keys: maxHailSize, maxWindGust, tornadoDetection, eventMotionDescription. |
GeocodeResultOne best match. Search auto-picks rather than making you disambiguate.
| Field | Type | Description |
|---|---|---|
| lat, lon | number | Coordinates to feed back into /weather. |
| city | string | Display 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. |
| parentCity | string | Enclosing city when the hit is a POI or address. |
| state, county, country | string | Spelled out, not abbreviated. |
| country_code | string | ISO 3166-1 alpha-2. |
| displayName | string | Full comma-separated label. |
| type | string | Friendly kind, e.g. City, Town, ZIP code, Landmark. |
| layer | string | Raw provider layer: locality, localadmin, postalcode, venue, address. |
| importance | number | 0–1 confidence. |
| isPoi | boolean | True for venues and landmarks rather than inhabited places. |
| results | null | Reserved 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.
| Plan | Monthly quota | Rate limit |
|---|---|---|
| Free | 5,000 / mo | 30 / min |
| Starter | 100,000 / mo | 120 / min |
| Pro | 2,000,000 / mo | 600 / min |
Errors
Every failure is the same shape — one error string, carrying the HTTP status:
{ "error": "lat and lon are required" }| 401 | Missing, invalid, or suspended API key. |
| 403 | Request rejected — no credential and no trusted origin. |
| 429 | Rate limit or monthly quota exceeded — see Retry-After. |
| 400 | Missing or invalid parameters (for example lat/lon). |
| 404 | No location matched q — refine the query or send coordinates. |
| 501 | Requested outside supported coverage (US and Canada). |
| 502 / 504 | Upstream 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.
| Source | Licence | Credit required |
|---|---|---|
| National Weather Service | US Government — public domain | No (appreciated) |
| Environment and Climate Change Canada | Open Government Licence — Canada | Yes |
| Open-Meteo | CC BY 4.0 | Yes |
| OpenStreetMap (geocoding) | ODbL | Yes |
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 →