Weather
Composite blended weather payload returned by `GET /v1/weather`. Section presence is controlled by the `include` query parameter; `location` and `gis` are always present. With the default `view=detailed` and no `fields`, every section that is present is the complete shape documented below. `view=concise` and `fields` project the members of `hourly[]` and `daily[]` rows (every other section stays complete), and `hourly_step` thins `hourly[]` rows; see "Response density, sampling and sparse fieldsets" on `GET /v1/weather`. A shaped body is always a key-subset of the detailed body for the same request.
Properties
| Name | Type | Description |
|---|---|---|
| location | object | |
| current | object | |
| hourly | array | Hourly forecast, ordered ascending by `time`. |
| daily | array | Daily forecast, ordered ascending by `date`. |
| alerts | array | Active NWS alerts for the location, present whenever the section is included and its fetch succeeded. `[]` means no alerts were in effect in the latest alerts snapshot, which can trail `meta.generated |
| outlooks | array | SPC convective outlooks active for the location, present whenever the section is included and its fetch succeeded. `[]` means no outlook was in effect in the latest outlooks snapshot, which can trail |
| astro | object | |
| gis | object | |
| units | object | |
| attribution | object | |
| narrations | object | |
| guidance | object | |
| discussions | object | |
| nowcast | object | |
| climate | object | Day-of-year climate normals for the location, populated when `include=climate` is requested. Identical in shape to the `GET /v1/climate/normals` body. This block is the normals themselves — what is ty |
| metar | object | |
| meta | object |
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://artifacts.apis.io/smarterweather-com/json-schema/smarterweather-com-weather-schema.json",
"title": "Weather",
"description": "Composite blended weather payload returned by `GET /v1/weather`.\nSection presence is controlled by the `include` query parameter;\n`location` and `gis` are always present. With the default `view=detailed` and no `fields`, every section\nthat is present is the complete shape documented below. `view=concise`\nand `fields` project the members of `hourly[]` and `daily[]` rows\n(every other section stays complete), and `hourly_step` thins\n`hourly[]` rows; see \"Response density, sampling and sparse\nfieldsets\" on `GET /v1/weather`. A shaped body is always a\nkey-subset of the detailed body for the same request.\n",
"x-generated": "2026-10-30",
"x-method": "derived",
"x-generator": "derive-json-schema.py",
"x-source": "openapi/smarterweather-com-openapi.yaml#/components/schemas/Weather",
"type": "object",
"required": [
"location",
"gis",
"meta",
"attribution"
],
"properties": {
"location": {
"$ref": "#/$defs/Location"
},
"current": {
"$ref": "#/$defs/Current"
},
"hourly": {
"type": "array",
"description": "Hourly forecast, ordered ascending by `time`.",
"items": {
"$ref": "#/$defs/Hourly"
}
},
"daily": {
"type": "array",
"description": "Daily forecast, ordered ascending by `date`.",
"items": {
"$ref": "#/$defs/Daily"
}
},
"alerts": {
"type": "array",
"description": "Active NWS alerts for the location, present whenever the section is included and its fetch succeeded. `[]` means no alerts were in effect in the latest alerts snapshot, which can trail `meta.generated_at` by up to about 30 seconds. Absent when the section is not included, or when its fetch failed (a `meta.warnings` entry with `section: alerts` says so). A stale replay (`X-SW-Stale: 1` header, or a `stale_response` warning on a batch row) repeats the alerts as of its own `meta.generated_at`, not the current set.",
"items": {
"$ref": "#/$defs/Alert"
}
},
"outlooks": {
"type": "array",
"description": "SPC convective outlooks active for the location, present whenever the section is included and its fetch succeeded. `[]` means no outlook was in effect in the latest outlooks snapshot, which can trail `meta.generated_at` by up to about 30 seconds. Absent when the section is not included, or when its fetch failed (a `meta.warnings` entry with `section: outlooks` says so). A stale replay repeats the outlooks as of its own `meta.generated_at`.",
"items": {
"$ref": "#/$defs/Outlook"
}
},
"astro": {
"$ref": "#/$defs/Astro"
},
"gis": {
"$ref": "#/$defs/GIS"
},
"units": {
"$ref": "#/$defs/Units"
},
"attribution": {
"$ref": "#/$defs/Attribution"
},
"narrations": {
"$ref": "#/$defs/Narrations"
},
"guidance": {
"$ref": "#/$defs/Guidance"
},
"discussions": {
"$ref": "#/$defs/Discussions"
},
"nowcast": {
"$ref": "#/$defs/Nowcast"
},
"climate": {
"allOf": [
{
"$ref": "#/$defs/ClimateNormals"
}
],
"description": "Day-of-year climate normals for the location, populated when\n`include=climate` is requested. Identical in shape to the\n`GET /v1/climate/normals` body.\n\nThis block is the normals themselves — what is typical here. For\nhow the forecast compares to them, read `daily[].climate`, which\ncarries the same normals joined to each forecast day along with\nthe signed departure.\n\nOmitted when no station with normals is near the point; that case\nreports `coverage_limited` in `meta.warnings[]` rather than\nfailing the request.\n"
},
"metar": {
"$ref": "#/$defs/Metar"
},
"meta": {
"$ref": "#/$defs/Meta"
}
},
"$defs": {
"AFDGuidance": {
"type": "object",
"x-stability": "experimental",
"description": "Area Forecast Discussion: structured fields plus optional raw bulletin\n`body`.\n",
"properties": {
"synopsis": {
"type": "string"
},
"key_takeaway": {
"type": "string"
},
"confidence": {
"type": "string",
"description": "Forecaster-stated confidence level (free text)."
},
"issued_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"wfo": {
"type": "string",
"description": "Issuing Weather Forecast Office identifier."
},
"body": {
"type": "string",
"description": "Full AFD bulletin text when available."
}
}
},
"Alert": {
"type": "object",
"description": "NWS weather alert active for the requested location.",
"required": [
"id",
"event",
"severity",
"urgency",
"certainty",
"headline",
"sender",
"status",
"onset",
"ends",
"effective",
"expires",
"expiration"
],
"properties": {
"id": {
"type": "string",
"description": "Unique alert identifier (the NWS message id). Pass it to\n`GET /v1/alerts/{id}` for the full alert.\n"
},
"event": {
"type": "string"
},
"severity": {
"type": "string",
"enum": [
"Extreme",
"Severe",
"Moderate",
"Minor",
"Unknown"
]
},
"urgency": {
"type": "string",
"enum": [
"Immediate",
"Expected",
"Future",
"Past",
"Unknown"
]
},
"certainty": {
"type": "string",
"enum": [
"Observed",
"Likely",
"Possible",
"Unlikely",
"Unknown"
]
},
"headline": {
"type": "string"
},
"sender": {
"type": "string",
"description": "Issuing NWS office identifier."
},
"status": {
"type": "string",
"description": "Alert lifecycle status (e.g., `Actual`, `Exercise`, `Test`)."
},
"onset": {
"type": "string",
"format": "date-time"
},
"ends": {
"type": "string",
"format": "date-time"
},
"effective": {
"type": "string",
"format": "date-time"
},
"expires": {
"type": "string",
"format": "date-time"
},
"expiration": {
"type": "string",
"format": "date-time",
"description": "Final expiration time used for cache invalidation."
},
"area_desc": {
"type": "string",
"description": "Human-readable affected area."
},
"highlights": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Map of salient callouts extracted from the alert text\n(e.g., `{\"hazard\": \"Strong winds\", \"impact\": \"Loose debris possible\"}`).\n"
}
}
},
"Astro": {
"type": "object",
"description": "Astronomical data for the requested location and date.",
"required": [
"day_length",
"daylight_length",
"moon_phase",
"moon_phase_name",
"moon_illumination"
],
"properties": {
"civil_dawn": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Null when civil twilight does not begin or end on this date."
},
"sunrise": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Null on polar day and night (see `polar`)."
},
"solar_noon": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"sunset": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Null on polar day and night (see `polar`)."
},
"civil_dusk": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Null when civil twilight does not begin or end on this date."
},
"day_length": {
"type": "integer",
"minimum": 0,
"description": "Seconds from sunrise to sunset; 86400 under midnight sun, 0 in polar night."
},
"daylight_length": {
"type": "integer",
"minimum": 0,
"description": "Seconds from civil dawn to civil dusk; 86400 when civil twilight never ends (white nights, midnight sun). 0 when there is no civil daylight or it is unknown; see civil_dawn, civil_dusk and polar."
},
"moonrise": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Null when no moonrise occurs on this date."
},
"moonset": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Null when no moonset occurs on this date."
},
"moon_phase": {
"type": "number",
"format": "double",
"minimum": 0,
"maximum": 1,
"description": "Moon phase (0 = new, 0.5 = full, 1 = new)."
},
"moon_phase_name": {
"type": "string",
"enum": [
"New Moon",
"Waxing Crescent",
"First Quarter",
"Waxing Gibbous",
"Full Moon",
"Waning Gibbous",
"Last Quarter",
"Waning Crescent"
]
},
"moon_illumination": {
"type": "number",
"format": "double",
"minimum": 0,
"maximum": 1
},
"polar": {
"type": [
"string",
"null"
],
"enum": [
"midnight_sun",
"polar_night",
null
],
"description": "Set when the sun neither rises nor sets on this date: midnight_sun (above the horizon all day; day_length is 86400) or polar_night (below it all day; day_length is 0). sunrise and sunset are then null. Null when the sun rises and sets."
},
"sky": {
"x-stability": "experimental",
"allOf": [
{
"$ref": "#/$defs/Sky"
}
],
"description": "Sunrise and sunset color forecast for this date, present only\nwhen `include=sky` is requested, enabled for the API key, and a\nforecast exists for the date.\n\n**Experimental** (`x-stability: experimental`): excluded from the\n90-day breaking-change commitment.\n"
}
}
},
"Attribution": {
"type": "object",
"description": "Attribution for the data sources that contributed to this response.\n`sources` is an explicit list of canonical identifiers suitable\nfor compliance checklists; `notice` is a human-readable catch-all\ncovering licensing / credit language.\n",
"required": [
"sources",
"notice"
],
"properties": {
"sources": {
"type": "array",
"description": "Canonical source identifiers that contributed data. `EPA AirNow`\nis listed only when the body as returned carries an air-quality\nvalue (`current.aqi`, `pm25`, `ozone` or `pm10`, `hourly[].aqi`,\n`daily[].aqi_max`, `daily[].day.aqi` or `daily[].night.aqi`), so a\n`view` or `fields` selection that drops those columns drops it.\n",
"items": {
"type": "string"
}
},
"notice": {
"type": "string",
"description": "Human-readable attribution notice."
}
}
},
"ClimateNormals": {
"type": "object",
"description": "Day-of-year climate normals for a point, read from the gridded normals\nacross CONUS and otherwise from the nearest station with records. The\nresolved station is always named, whichever supplied the values.\n",
"required": [
"station",
"meta",
"days"
],
"properties": {
"station": {
"$ref": "#/$defs/ClimateNormalsStation"
},
"meta": {
"$ref": "#/$defs/ClimateNormalsMeta"
},
"days": {
"type": "array",
"description": "Per-day normals series, in requested date order.",
"items": {
"$ref": "#/$defs/ClimateNormalsDay"
}
},
"location": {
"$ref": "#/$defs/Location",
"description": "Resolved location, as `/v1/weather` returns it. Present when the\nplace was resolved: always for a `zip` or `location` request, and\nfor `lat`/`lon` when the coverage check's lookup answered in time\n(omitted when that check fails open).\n"
}
}
},
"ClimateNormalsDay": {
"type": "object",
"description": "One day-of-year slice. Fields are omitted when no normal is available,\nwhich is not the same as a value of zero. `normal_precip` is\nadditionally omitted on any station-sourced day — see its description.\n",
"required": [
"date",
"month",
"day"
],
"properties": {
"date": {
"type": "string",
"format": "date",
"description": "Calendar date this slice was requested for."
},
"month": {
"type": "integer",
"description": "Month of the day-of-year slice (1-12)."
},
"day": {
"type": "integer",
"description": "Day of month (1-31)."
},
"normal_high": {
"type": "number",
"format": "double",
"description": "Average daily maximum temperature."
},
"normal_low": {
"type": "number",
"format": "double",
"description": "Average daily minimum temperature."
},
"normal_mean": {
"type": "number",
"format": "double",
"description": "Average daily mean temperature."
},
"normal_high_stddev": {
"type": "number",
"format": "double",
"description": "Standard deviation of the daily maximum. An interval, so it scales\nwithout the freezing-point offset: 3 °C of spread is 5.4 °F.\n\nAlways from the nearest station, including on a day whose\ntemperatures came from the grid — the gridded normals publish no\nstandard deviations. On such a day the temperatures describe your\npoint while this describes the named station, so read\n`station.distance_km` before narrating \"unusually warm\" off this\nspread. The same holds for `normal_low_stddev`,\n`normal_mean_stddev`, `years` and `completeness_flag`.\n"
},
"normal_low_stddev": {
"type": "number",
"format": "double",
"description": "Standard deviation of the daily minimum. Station-sourced on the\nsame terms as `normal_high_stddev`.\n"
},
"normal_mean_stddev": {
"type": "number",
"format": "double",
"description": "Standard deviation of the daily mean. Station-sourced on the same\nterms as `normal_high_stddev`.\n"
},
"normal_precip": {
"type": "number",
"format": "double",
"description": "Average daily precipitation amount — inches when `unit=imperial`,\nmillimetres when `unit=metric`.\n\nThe exact inverse of `normal_high_stddev`: that is always\nstation-sourced, this is always grid-sourced. The station product\npublishes no daily precipitation normal at all, so this field comes\nonly from the gridded CONUS product and is **omitted** on any day\nwhose `source` is `station` — which includes every point outside\nCONUS. A series over Alaska or Hawaii carries temperatures with no\nprecipitation until gridded normals exist there.\n\n`0` is a real value and is not the same as omitted: a daily normal\nis a 30-year mean spread across wet and dry days, so much of the\narid West is a few hundredths of an inch. Do not treat a present\nzero as missing data.\n"
},
"years": {
"type": "integer",
"description": "Years of the base period contributing to this day, at the station.\nStation-sourced on the same terms as `normal_high_stddev`, so it\ndoes not describe the depth of a gridded value.\n"
},
"completeness_flag": {
"type": "string",
"description": "NCEI per-value completeness code, for the station. Station-sourced\non the same terms as `normal_high_stddev`.\n"
}
}
},
"ClimateNormalsMeta": {
"type": "object",
"description": "Provenance for a normals response.",
"required": [
"source",
"unit"
],
"properties": {
"normals_period": {
"type": "string",
"description": "Base period the normals were computed over."
},
"source": {
"type": "string",
"description": "Where the values came from: `station` for the NCEI station\nproduct, `grid` for gridded normals, `mixed` when a series draws\non both.\n"
},
"normals_method": {
"type": "string",
"enum": [
"official",
"derived"
],
"description": "How the normals were produced, which `source` does not answer.\n`official` means the provider publishes them as a normals product\n-- true of both the NCEI station normals and the NCEI gridded\nnormals, so a station/grid mix is still wholly official.\n`derived` means they were computed from raw climate data, which is\na weaker claim a client should qualify. Absent when upstream does\nnot report it.\n"
},
"unit": {
"type": "string",
"enum": [
"imperial",
"metric"
],
"description": "Unit system applied to the values: °F and inches for `imperial`,\n°C and millimetres for `metric`.\n"
},
"approximate": {
"type": "boolean",
"description": "True when a station more than 50 km away supplied values that are\nactually being served — `station.distance_km` says how far.\n\nIt is not a plain distance test. A `grid` day is the requested\npoint's own normal, so no station distance makes it approximate,\nand a series whose `source` is `grid` is never flagged however far\nthe named station sits. A `mixed` series is flagged, because the\nstation-sourced days in it genuinely are approximations.\n"
},
"missing_days": {
"type": "integer",
"description": "How many days in the requested range no normal is available for,\nfrom either the grid or the station. Those days are still present\nin `days` with their temperature fields omitted.\n"
}
}
},
"ClimateNormalsStation": {
"type": "object",
"description": "The station a normals series was drawn from. Normals describe this\nstation, not necessarily the point you asked about.\n",
"required": [
"station_id",
"latitude",
"longitude",
"distance_km"
],
"properties": {
"station_id": {
"type": "string",
"description": "GHCN station identifier."
},
"name": {
"type": "string",
"description": "Station name as published by NCEI."
},
"state": {
"type": "string",
"description": "Two-letter state or territory code."
},
"latitude": {
"type": "number",
"format": "double",
"description": "Station latitude."
},
"longitude": {
"type": "number",
"format": "double",
"description": "Station longitude."
},
"elevation_m": {
"type": "number",
"format": "double",
"description": "Station elevation in metres. Worth comparing against your point:\nan elevation difference biases normals more than distance does.\n"
},
"distance_km": {
"type": "number",
"format": "double",
"description": "Great-circle distance from the requested point to the station,\nrounded to 0.1 km. The single number that says how much to trust\nthis series.\n"
}
}
},
"Current": {
"type": "object",
"description": "Current weather conditions derived from the RTMA + MRMS blend.\n",
"required": [
"time",
"conditions",
"icon"
],
"properties": {
"time": {
"type": "string",
"format": "date-time",
"description": "Observation valid time (ISO 8601, UTC) of the analysis behind `temperature`, or the response time when no fresh observation is available."
},
"temperature": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Temperature (unit per `units.temperature`). Null only when no source in the current chain resolves it."
},
"feels_like": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Feels-like temperature: the air temperature unless wind chill (50°F or below, wind 3 mph or more) or heat index (80°F or above, relative humidity 40% or more) applies. Null when the index that applies lacks its input and no forecast apparent temperature covers now; never derived from an unknown value."
},
"humidity": {
"type": [
"number",
"null"
],
"format": "double",
"minimum": 0,
"maximum": 100,
"description": "Relative humidity, percent. Null only when no source in the current chain resolves it."
},
"dew_point": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Dew point (unit per `units.temperature`). Null only when no source in the current chain resolves it, or its derivation lacks the temperature or humidity."
},
"pressure": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Sea-level pressure (unit per `units.pressure`): the quantity US NWS stations report in the METAR SLP group. From the observation-anchored RTMA analysis, its station pressure reduced to sea level with the WMO CIMO Guide 3.11 formula and the FMH-1 12-hour mean temperature; else the GFS mean-sea-level pressure field at now. Not the altimeter setting and not station pressure. Null only when neither source is fresh."
},
"wind_speed": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Sustained wind speed; `0` is calm (below 1 knot, FMH-1 5.5.2: served as `0` in every unit system). Null only when no source in the current chain resolves it."
},
"wind_gust": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Wind gust, served only next to a non-calm `wind_speed`. Null when no source carries a gust, or the wind is calm or unknown."
},
"wind_direction": {
"type": [
"integer",
"null"
],
"minimum": 0,
"maximum": 360,
"description": "Wind direction in degrees (0 = N, 90 = E). Null when calm (`wind_speed` 0) and when no source resolves it."
},
"visibility": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Visibility distance (null when no station or model value is available)."
},
"cloud_cover": {
"type": [
"number",
"null"
],
"format": "double",
"minimum": 0,
"maximum": 100,
"description": "Cloud cover, percent. Null only when no source in the current chain resolves it."
},
"cloud_ceiling": {
"type": [
"number",
"null"
],
"format": "double",
"minimum": 0,
"description": "Analysis cloud-base height above ground (RTMA/URMA), in the `units.altitude` unit. Null when no ceiling is reported (clear or high thin cloud) or outside analysis coverage."
},
"cloud_cover_low": {
"type": [
"number",
"null"
],
"format": "double",
"minimum": 0,
"maximum": 100,
"description": "HRRR low-cloud-layer cover, percent (CONUS). Present only with `cloud_cover_mid` and `cloud_cover_high` (all three numbers or all three null). Null outside HRRR coverage or before the first post-deploy cycle."
},
"cloud_cover_mid": {
"type": [
"number",
"null"
],
"format": "double",
"minimum": 0,
"maximum": 100,
"description": "HRRR mid-cloud-layer cover, percent (CONUS). Same all-three-or-null contract as `cloud_cover_low`."
},
"cloud_cover_high": {
"type": [
"number",
"null"
],
"format": "double",
"minimum": 0,
"maximum": 100,
"description": "HRRR high-cloud-layer cover, percent (CONUS). Same all-three-or-null contract as `cloud_cover_low`."
},
"uv_index": {
"type": [
"number",
"null"
],
"format": "double"
},
"aqi": {
"type": [
"integer",
"null"
],
"description": "Air-quality index (US EPA scale): usually 0-500, can exceed 500\nin extreme events (\"Beyond the AQI\"). `null` when AirNow has no\nvalue at the point, or when its latest observation is older than\nthe source's freshness limit (currently 3 hours for AirNow). The\nstale case also adds a `stale_source` warning to `meta.warnings`\n(`section: current`, `product_id: airquality_combined`), which\ntells the two apart. The product's age is the `meta.freshness`\nentry with the same `product_id`. A reported 0 is currently also\nserved as `null`: AirNow stores cells outside its coverage as 0,\nso a 0 cannot yet be told from no data.\n"
},
"aqi_category": {
"type": "string",
"description": "Human-readable AQI category (e.g., `\"Good\"`, `\"Moderate\"`,\n`\"Unhealthy for Sensitive Groups\"`). Omitted when AQI is\nunavailable.\n"
},
"pm25": {
"type": [
"number",
"null"
],
"format": "double",
"description": "AirNow AQI sub-index for PM2.5, on the same scale as `aqi`:\nusually 0-500, can exceed 500 in extreme events. Integer-valued\nat the source; a value may show a small fractional error, so\nround to a whole number. Not a concentration: the field name\nnames the pollutant and is kept for compatibility. `null` when\nAirNow has no value at the point, when its latest hour is stale\n(reported by a `stale_source` warning, see `aqi`), or when the\nreported value is 0 (currently indistinguishable from no data,\nsee `aqi`).\n"
},
"ozone": {
"type": [
"number",
"null"
],
"format": "double",
"description": "AirNow AQI sub-index for ozone, on the same scale as `aqi`:\nusually 0-500, can exceed 500 in extreme events. Integer-valued\nat the source; a value may show a small fractional error, so\nround to a whole number. Not a concentration: the field name\nnames the pollutant and is kept for compatibility. `null` when\nAirNow has no value at the point, when its latest hour is stale\n(reported by a `stale_source` warning, see `aqi`), or when the\nreported value is 0 (currently indistinguishable from no data,\nsee `aqi`).\n"
},
"pm10": {
"type": [
"number",
"null"
],
"format": "double",
"description": "AirNow AQI sub-index for PM10, on the same scale as `aqi`:\nusually 0-500, can exceed 500 in extreme events. Integer-valued\nat the source; a value may show a small fractional error, so\nround to a whole number. Not a concentration: the field name\nnames the pollutant and is kept for compatibility. `null` when\nAirNow has no value at the point, when its latest hour is stale\n(reported by a `stale_source` warning, see `aqi`), or when the\nreported value is 0 (currently indistinguishable from no data,\nsee `aqi`).\n"
},
"precip_rate": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Current precipitation rate per hour. `0` when dry (`precip_type` `none`); null when neither radar nor a forecast source covers the point now."
},
"precip_type": {
"type": "string",
"enum": [
"none",
"rain",
"snow",
"mix",
"freezing_rain",
"hail",
"unknown"
],
"description": "Current precipitation type: MRMS radar where it covers the point,\nelse the current chain's forecast type at now, which is served\nonly with a measurable rate (0.01 in per hour); below it, `none`.\n`none` is a known dry reading. Omitted when neither radar nor a\nforecast source covers the point now. Radar serves\n`freezing_rain` and `mix` where its rain or snow is reclassified\nby the analysis wet-bulb. `mix` is rain and snow, ice pellets,\nor a wintry mix; `hail` and `unknown` are reserved and not\ncurrently served.\n"
},
"precip_24h": {
"type": [
"number",
"null"
],
"format": "double",
"x-stability": "experimental",
"description": "Observed precipitation accumulated over the trailing 24 hours,\nfrom MRMS MultiSensor QPE Pass 2. The window ends at the\nproduct's valid time, listed under `meta.freshness`. Always\nmillimetres regardless of `units`. CONUS only; `null` outside\nCONUS, when no sample is available, or when the sample's valid\ntime is older than the product's hourly-cadence staleness\nwindow (currently 3 hours, the same window `/v1/point` uses to\nmark it approximate). Source resolution is about 2 mm.\n\n**Experimental.** May change without notice: excluded from the\n90-day breaking-change commitment.\n"
},
"lightning_density": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Lightning strike density (strikes per unit area per time window)."
},
"lightning_prob": {
"type": [
"integer",
"null"
],
"minimum": 0,
"maximum": 100,
"description": "Lightning probability, percent."
},
"conditions": {
"type": "string",
"description": "Human-readable weather description. Empty string when neither the sky (cloud cover) nor precipitation is known."
},
"icon": {
"type": "string",
"description": "Icon slug for UI rendering. Empty string exactly when `conditions` is."
},
"severe": {
"type": "boolean",
"description": "True when severe conditions are present or imminent.",
"default": false
}
}
},
"Daily": {
"type": "object",
"description": "Single daily forecast entry. Per-period weather (temperature, wind,\nprecipitation, narrative) lives in `day` / `night`, the row's local\n06:00-18:00 and 18:00-06:00 halves, so a row spans 06:00 local on\n`date` to 06:00 local the next day rather than the calendar day.\nPrecipitation, snow and ice totals are built on that
# --- truncated at 32 KB (110 KB total) ---
# Full source: https://artifacts.apis.io/smarterweather-com/json-schema/smarterweather-com-weather-schema.json
Work with this as data
Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for schemas
4 MCP tools reach this
find_json_schemasBrowse and filter every JSON Schema in the catalog.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
curl "https://apis.io/api/v1/json-schemas/smarterweather-com-weather"
curl "https://apis.io/api/v1/json-schemas?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.