Community. Driven. Weather. Data. | Always Ad-Free | Developer FriendlyChecking statusDiscord
Become a supporter
Sign in
API

Low visibility

Fog, marine fog and smoke as polygons by visibility category, every 15 minutes, with a confidence, a cause and the sources behind each area. Plus everything known at a single point.


Base URL: https://api.wxalerts.org

Where visibility is down right now, and why: fog, marine fog and smoke, as polygons by category, refreshed every 15 minutes. Each area says how sure the product is and what it is based on. No polygon means normal visibility.

GET /visibility?bbox=-88.6,30.1,-86.4,31.2
GET /visibility?bbox=-88.6,30.1,-86.4,31.2&min_category=2
GET /visibility/point?lat=30.69&lon=-88.04
GET /visibility/point?q=mobile+al

No authentication. CORS is open. Design against 60 requests a minute. Both endpoints send Cache-Control: public, max-age=120; a new analysis lands every 15 minutes, so polling faster than that learns nothing.

WxAlerts sets no thresholds

This product describes; it does not decide. It never says “dangerous”, never issues an alert, and never hides a category as too minor to show. Every area carries its category, confidence, cause and sources, and what is worth drawing or alerting on is your call. A traffic app might alert only on very_low and worse at medium confidence or higher; a marine app might care about any marine_fog. Filter on the fields.

Categories

Prevailing visibility, from aviation and NWS practice.

category category_name visibility
1 reduced 3 to 5 mi (4828 to 8047 m)
2 low 1 to 3 mi (1609 to 4828 m)
3 very_low 1/4 to 1 mi (402 to 1609 m)
4 near_zero under 1/4 mi (under 402 m)
0 normal 5 mi or more. Never a polygon; used only by /visibility/point

Each lower edge is inclusive: 1609 m is low, 1608 m is very_low, 8047 m is normal.

Where it comes from

Four independent sources, fused on a 2.5 km grid:

source what it adds
analysis NOAA’s RTMA Rapid Update visibility analysis, every 15 minutes, the base layer everywhere
station airport (METAR) and buoy (NDBC) visibility, which pulls the analysis toward the measurement within 15 km
advisory NWS Dense Fog, Marine Dense Fog, Freezing Fog and Dense Smoke Advisories. Inside one, the category is at least very_low and the cause is the advisory’s
reports clusters of driver reports from integrations. No single driver is trusted: ten or more independent reporters within 2 km and 30 minutes create an area, marked reported: true

sources on each area lists the ones that agree with it.

Confidence follows from how many independent sources agree: one is low, two medium, three or more high. A reported area is always high.

Cause is fog, marine_fog or smoke. Freezing fog is reported as fog.

GET /visibility

The current areas that intersect a bounding box, clipped to it, as a GeoJSON FeatureCollection, least severe first so drawing in order puts the worst on top.

parameter
bbox west,south,east,north in degrees. At most 30 degrees a side
min_category 1 (default) to 4: only areas this bad or worse
{
  "type": "FeatureCollection",
  "analysis_time": "2026-11-09T11:45:00Z",
  "published_at": "2026-11-09T11:52:10Z",
  "bbox": [-88.6, 30.1, -86.4, 31.2],
  "min_category": 1,
  "legend": [
    { "category": 1, "category_name": "reduced", "range_mi": "3 to 5 mi", "min_m": 4828.0, "max_m": 8047.0 },
    "..."
  ],
  "features": [
    {
      "type": "Feature",
      "geometry": { "type": "MultiPolygon", "coordinates": ["..."] },
      "properties": {
        "category": 3,
        "category_name": "very_low",
        "cause": "fog",
        "confidence": "high",
        "sources": ["analysis", "station", "advisory"],
        "reported": false,
        "vis_m_min": 420.0,
        "analysis_time": "2026-11-09T11:45:00Z"
      }
    }
  ]
}

vis_m_min is the lowest analysed visibility inside the area, in metres. Coordinates are to 5 decimal places, about a metre. An empty features list is a clear analysis. A bbox that is malformed or too large is a 422. Before the first analysis has been published the endpoint answers 503; retry.

GET /visibility/point

Everything known at one place: the analysis, the nearest measurement, any advisory, and the model’s next six hours.

parameter
lat, lon the point. Or q (a place name) or location_id, as on /forecast
{
  "location": { "name": "Mobile", "display_name": "Mobile, AL", "state": "AL", "lat": 30.69, "lon": -88.04 },
  "analysis_time": "2026-11-09T11:45:00Z",
  "published_at": "2026-11-09T11:52:10Z",
  "message": null,
  "current": {
    "category": 3, "category_name": "very_low", "cause": "fog", "confidence": "high",
    "sources": ["analysis", "station", "advisory"], "reported": false, "vis_m_min": 420.0
  },
  "station": {
    "station_id": "KMOB", "source": "metar", "distance_km": 18.4,
    "visibility_m": 402.0, "observed_at": "2026-11-09T11:53:00Z"
  },
  "advisories": [
    { "event": "Dense Fog Advisory", "phenomena": "FG", "office": "MOB",
      "expires": "2026-11-09T15:00:00Z", "ends": "2026-11-09T15:00:00Z" }
  ],
  "outlook": {
    "model": "hrrr", "cycle": "2026-11-09T11:00:00Z", "cell_id": 812345, "resolution_km": 6.0,
    "hours": [
      { "valid_time": "2026-11-09T12:00:00Z", "visibility_m": 300, "category": 4, "category_name": "near_zero" },
      { "valid_time": "2026-11-09T13:00:00Z", "visibility_m": 1200, "category": 3, "category_name": "very_low" },
      "..."
    ]
  },
  "legend": ["..."]
}
  • current is the worst area covering the point: the highest category, then the highest confidence. Outside every area it is {"category": 0, "category_name": "normal"}. Before the first analysis it is null and message says so.
  • station is the nearest airport or buoy within 25 km that reported a visibility in the last 90 minutes, or null.
  • advisories are the NWS fog and smoke advisories in force at the point.
  • outlook is HRRR surface visibility for the next six hours, from the hour in progress, each mapped to the same categories. It is the lowest value in a 6 km block, so it leans pessimistic. null outside the HRRR grid (the contiguous United States and its surroundings).

Report intake

POST /visibility/reports accepts anonymized driver fog reports from integrations by arrangement, authenticated with a shared token. It is not open to the public. Reports are never served back by this API; they only shape the product, and only in clusters. Get in touch if you run an app whose users could report fog.

May we use Microsoft Clarity to see how pages are used (clicks, scrolling and replays of a visit, with anything you type hidden), plus a random ID linking that to crash reports? Only to find bugs and confusing screens. Never advertising, never sold.