{"openapi":"3.1.0","info":{"title":"Severe Weather API","description":"Unified severe weather data aggregation platform. Aggregates data from NWS, SPC, IEM, and other public sources into a single REST API with GeoJSON output and spatial queries.","version":"0.1.0"},"paths":{"/api/v1/alerts":{"get":{"tags":["Alerts"],"summary":"Get Alerts","description":"Get active and recent NWS weather alerts.\n\nReturns a GeoJSON FeatureCollection of alert polygons with full alert details\nin the properties of each feature.","operationId":"get_alerts_api_v1_alerts_get","parameters":[{"name":"bbox","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bounding box: west,south,east,north","title":"Bbox"},"description":"Bounding box: west,south,east,north"},{"name":"point","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Center point: lat,lon","title":"Point"},"description":"Center point: lat,lon"},{"name":"radius","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Radius from point (e.g., 100km)","title":"Radius"},"description":"Radius from point (e.g., 100km)"},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"US state abbreviation","title":"State"},"description":"US state abbreviation"},{"name":"wfo","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"NWS Weather Forecast Office ID","title":"Wfo"},"description":"NWS Weather Forecast Office ID"},{"name":"start","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Start of time range (ISO 8601)","title":"Start"},"description":"Start of time range (ISO 8601)"},{"name":"end","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End of time range (ISO 8601)","title":"End"},"description":"End of time range (ISO 8601)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Max results","default":100,"title":"Limit"},"description":"Max results"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Pagination offset","default":0,"title":"Offset"},"description":"Pagination offset"},{"name":"active","in":"query","required":false,"schema":{"type":"boolean","description":"Only active (non-expired) alerts","default":true,"title":"Active"},"description":"Only active (non-expired) alerts"},{"name":"event","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by event type","title":"Event"},"description":"Filter by event type"},{"name":"severity","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter: Extreme|Severe|Moderate|Minor","title":"Severity"},"description":"Filter: Extreme|Severe|Moderate|Minor"},{"name":"urgency","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter: Immediate|Expected|Future","title":"Urgency"},"description":"Filter: Immediate|Expected|Future"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/alerts/{alert_id}":{"get":{"tags":["Alerts"],"summary":"Get Alert By Id","description":"Get a single alert by ID.","operationId":"get_alert_by_id_api_v1_alerts__alert_id__get","parameters":[{"name":"alert_id","in":"path","required":true,"schema":{"type":"integer","title":"Alert Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/observations":{"get":{"tags":["Observations"],"summary":"Get Observations","description":"Get surface weather observations from all networks.","operationId":"get_observations_api_v1_observations_get","parameters":[{"name":"bbox","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bounding box: west,south,east,north","title":"Bbox"},"description":"Bounding box: west,south,east,north"},{"name":"point","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Center point: lat,lon","title":"Point"},"description":"Center point: lat,lon"},{"name":"radius","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Radius from point (e.g., 100km)","title":"Radius"},"description":"Radius from point (e.g., 100km)"},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"US state abbreviation","title":"State"},"description":"US state abbreviation"},{"name":"wfo","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"NWS Weather Forecast Office ID","title":"Wfo"},"description":"NWS Weather Forecast Office ID"},{"name":"start","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Start of time range (ISO 8601)","title":"Start"},"description":"Start of time range (ISO 8601)"},{"name":"end","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End of time range (ISO 8601)","title":"End"},"description":"End of time range (ISO 8601)"},{"name":"latest","in":"query","required":false,"schema":{"type":"boolean","description":"Return most recent data only","default":false,"title":"Latest"},"description":"Return most recent data only"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Max results","default":100,"title":"Limit"},"description":"Max results"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Pagination offset","default":0,"title":"Offset"},"description":"Pagination offset"},{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by network: nws|iem|synoptic","title":"Source"},"description":"Filter by network: nws|iem|synoptic"},{"name":"station","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Specific station ID","title":"Station"},"description":"Specific station ID"},{"name":"units","in":"query","required":false,"schema":{"type":"string","description":"Unit system: imperial|metric|si","default":"metric","title":"Units"},"description":"Unit system: imperial|metric|si"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/outlooks":{"get":{"tags":["Outlooks"],"summary":"Get Outlooks","description":"Get SPC convective outlooks.\n\nReturns a GeoJSON FeatureCollection of outlook polygons with risk levels,\nvalid times, and display colors in the properties.","operationId":"get_outlooks_api_v1_outlooks_get","parameters":[{"name":"bbox","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bounding box: west,south,east,north","title":"Bbox"},"description":"Bounding box: west,south,east,north"},{"name":"point","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Center point: lat,lon","title":"Point"},"description":"Center point: lat,lon"},{"name":"radius","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Radius from point (e.g., 100km)","title":"Radius"},"description":"Radius from point (e.g., 100km)"},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"US state abbreviation","title":"State"},"description":"US state abbreviation"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Max results","default":100,"title":"Limit"},"description":"Max results"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Pagination offset","default":0,"title":"Offset"},"description":"Pagination offset"},{"name":"day","in":"query","required":false,"schema":{"type":"integer","maximum":8,"minimum":1,"description":"Outlook day (1-8)","default":1,"title":"Day"},"description":"Outlook day (1-8)"},{"name":"type","in":"query","required":false,"schema":{"type":"string","description":"Type: categorical|tornado|hail|wind","default":"categorical","title":"Type"},"description":"Type: categorical|tornado|hail|wind"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/reports":{"get":{"tags":["Reports"],"summary":"Get Reports","description":"Get storm reports from SPC, mPING, and Spotter Network.","operationId":"get_reports_api_v1_reports_get","parameters":[{"name":"bbox","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bounding box: west,south,east,north","title":"Bbox"},"description":"Bounding box: west,south,east,north"},{"name":"point","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Center point: lat,lon","title":"Point"},"description":"Center point: lat,lon"},{"name":"radius","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Radius from point (e.g., 100km)","title":"Radius"},"description":"Radius from point (e.g., 100km)"},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"US state abbreviation","title":"State"},"description":"US state abbreviation"},{"name":"start","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Start of time range (ISO 8601)","title":"Start"},"description":"Start of time range (ISO 8601)"},{"name":"end","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End of time range (ISO 8601)","title":"End"},"description":"End of time range (ISO 8601)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Max results","default":100,"title":"Limit"},"description":"Max results"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Pagination offset","default":0,"title":"Offset"},"description":"Pagination offset"},{"name":"type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter: tornado|hail|wind|flood","title":"Type"},"description":"Filter: tornado|hail|wind|flood"},{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter: spc|mping|spotter_network","title":"Source"},"description":"Filter: spc|mping|spotter_network"},{"name":"min_magnitude","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Min magnitude (e.g., hail size)","title":"Min Magnitude"},"description":"Min magnitude (e.g., hail size)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/radar/tiles/{product}/{z}/{x}/{y}.png":{"get":{"tags":["Radar"],"summary":"Get Radar Tile","description":"Return a radar tile as PNG.","operationId":"get_radar_tile_api_v1_radar_tiles__product___z___x___y__png_get","parameters":[{"name":"product","in":"path","required":true,"schema":{"type":"string","description":"Radar product ID","title":"Product"},"description":"Radar product ID"},{"name":"z","in":"path","required":true,"schema":{"type":"integer","maximum":10,"minimum":0,"title":"Z"}},{"name":"x","in":"path","required":true,"schema":{"type":"integer","minimum":0,"title":"X"}},{"name":"y","in":"path","required":true,"schema":{"type":"integer","minimum":0,"title":"Y"}},{"name":"ts","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Frame timestamp YYYYMMDDHHMM; omit for latest","title":"Ts"},"description":"Frame timestamp YYYYMMDDHHMM; omit for latest"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/radar/frames":{"get":{"tags":["Radar"],"summary":"Get Radar Frames","description":"Return the list of available frame timestamps for animation.","operationId":"get_radar_frames_api_v1_radar_frames_get","parameters":[{"name":"product","in":"query","required":false,"schema":{"type":"string","default":"composite-reflectivity","title":"Product"}},{"name":"minutes","in":"query","required":false,"schema":{"type":"integer","maximum":180,"minimum":5,"default":30,"title":"Minutes"}},{"name":"interval","in":"query","required":false,"schema":{"type":"integer","maximum":15,"minimum":2,"default":2,"title":"Interval"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/radar/products":{"get":{"tags":["Radar"],"summary":"List Products","operationId":"list_products_api_v1_radar_products_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/satellite/tiles/{product}/{z}/{x}/{y}.png":{"get":{"tags":["Satellite"],"summary":"Get Satellite Tile","description":"Return a satellite tile as PNG.","operationId":"get_satellite_tile_api_v1_satellite_tiles__product___z___x___y__png_get","parameters":[{"name":"product","in":"path","required":true,"schema":{"type":"string","title":"Product"}},{"name":"z","in":"path","required":true,"schema":{"type":"integer","maximum":10,"minimum":0,"title":"Z"}},{"name":"x","in":"path","required":true,"schema":{"type":"integer","minimum":0,"title":"X"}},{"name":"y","in":"path","required":true,"schema":{"type":"integer","minimum":0,"title":"Y"}},{"name":"ts","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Frame timestamp YYYYMMDDHHMM","title":"Ts"},"description":"Frame timestamp YYYYMMDDHHMM"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/satellite/products":{"get":{"tags":["Satellite"],"summary":"List Products","operationId":"list_products_api_v1_satellite_products_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/satellite/frames":{"get":{"tags":["Satellite"],"summary":"Get Frames","description":"List animation frame timestamps for a local product.","operationId":"get_frames_api_v1_satellite_frames_get","parameters":[{"name":"product","in":"query","required":false,"schema":{"type":"string","default":"ir","title":"Product"}},{"name":"minutes","in":"query","required":false,"schema":{"type":"integer","maximum":360,"minimum":5,"default":60,"title":"Minutes"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/soundings":{"get":{"tags":["Soundings"],"summary":"List Soundings","description":"List available soundings with summary and derived parameters.\n\nDoes not return the full profile arrays — use /api/v1/soundings/{id}\nor /api/v1/soundings/{station}/latest for full profiles.","operationId":"list_soundings_api_v1_soundings_get","parameters":[{"name":"bbox","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bounding box: west,south,east,north","title":"Bbox"},"description":"Bounding box: west,south,east,north"},{"name":"point","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Center point: lat,lon","title":"Point"},"description":"Center point: lat,lon"},{"name":"radius","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Radius from point (e.g., 100km)","title":"Radius"},"description":"Radius from point (e.g., 100km)"},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"US state abbreviation","title":"State"},"description":"US state abbreviation"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Max results","default":50,"title":"Limit"},"description":"Max results"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Pagination offset","default":0,"title":"Offset"},"description":"Pagination offset"},{"name":"station","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Station ID filter (e.g., OUN, KOUN)","title":"Station"},"description":"Station ID filter (e.g., OUN, KOUN)"},{"name":"latest","in":"query","required":false,"schema":{"type":"boolean","description":"Return only latest sounding per station","default":true,"title":"Latest"},"description":"Return only latest sounding per station"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/soundings/{station}/latest":{"get":{"tags":["Soundings"],"summary":"Latest Sounding","description":"Get the latest sounding for a station with full profile.","operationId":"latest_sounding_api_v1_soundings__station__latest_get","parameters":[{"name":"station","in":"path","required":true,"schema":{"type":"string","title":"Station"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/models/hrrr/point":{"get":{"tags":["Models"],"summary":"Hrrr Point Forecast","description":"Get HRRR point forecast for severe weather parameters.\n\nReturns hourly forecasts for CAPE, CIN, lifted index, wind, and precipitation.","operationId":"hrrr_point_forecast_api_v1_models_hrrr_point_get","parameters":[{"name":"lat","in":"query","required":true,"schema":{"type":"number","maximum":90,"minimum":-90,"title":"Lat"}},{"name":"lon","in":"query","required":true,"schema":{"type":"number","maximum":180,"minimum":-180,"title":"Lon"}},{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":48,"minimum":1,"description":"Forecast hours","default":18,"title":"Hours"},"description":"Forecast hours"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/models/available":{"get":{"tags":["Models"],"summary":"List Models","description":"List available NWP models and their capabilities.","operationId":"list_models_api_v1_models_available_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/geocode/search":{"get":{"tags":["Geocoding"],"summary":"Search","description":"Forward geocode a query string to lat/lon candidates.","operationId":"search_api_v1_geocode_search_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2,"description":"City, state, ZIP, address, or place","title":"Q"},"description":"City, state, ZIP, address, or place"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":10,"minimum":1,"default":5,"title":"Limit"}},{"name":"country","in":"query","required":false,"schema":{"type":"string","description":"ISO country code (default 'us')","default":"us","title":"Country"},"description":"ISO country code (default 'us')"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/geocode/reverse":{"get":{"tags":["Geocoding"],"summary":"Reverse","description":"Reverse geocode a lat/lon to a place name.","operationId":"reverse_api_v1_geocode_reverse_get","parameters":[{"name":"lat","in":"query","required":true,"schema":{"type":"number","maximum":90,"minimum":-90,"title":"Lat"}},{"name":"lon","in":"query","required":true,"schema":{"type":"number","maximum":180,"minimum":-180,"title":"Lon"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/locations/summary":{"get":{"tags":["Locations"],"summary":"Location Summary","description":"Return a complete weather summary for a lat/lon point.","operationId":"location_summary_api_v1_locations_summary_get","parameters":[{"name":"lat","in":"query","required":true,"schema":{"type":"number","maximum":90,"minimum":-90,"title":"Lat"}},{"name":"lon","in":"query","required":true,"schema":{"type":"number","maximum":180,"minimum":-180,"title":"Lon"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/gauges":{"get":{"tags":["Gauges"],"summary":"List Gauges","description":"List USGS river/stream gauges with their latest readings.","operationId":"list_gauges_api_v1_gauges_get","parameters":[{"name":"bbox","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bounding box: west,south,east,north","title":"Bbox"},"description":"Bounding box: west,south,east,north"},{"name":"point","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Center point: lat,lon","title":"Point"},"description":"Center point: lat,lon"},{"name":"radius","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Radius from point (e.g., 100km)","title":"Radius"},"description":"Radius from point (e.g., 100km)"},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"US state abbreviation","title":"State"},"description":"US state abbreviation"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Max results","default":200,"title":"Limit"},"description":"Max results"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Pagination offset","default":0,"title":"Offset"},"description":"Pagination offset"},{"name":"above_flood","in":"query","required":false,"schema":{"type":"boolean","description":"Only gauges currently above known flood stage","default":false,"title":"Above Flood"},"description":"Only gauges currently above known flood stage"},{"name":"parameter","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to gauges reporting this parameter: streamflow|gage_height|water_temp","title":"Parameter"},"description":"Filter to gauges reporting this parameter: streamflow|gage_height|water_temp"},{"name":"recent_hours","in":"query","required":false,"schema":{"type":"integer","maximum":48,"minimum":1,"description":"Only gauges with readings in the past N hours","default":6,"title":"Recent Hours"},"description":"Only gauges with readings in the past N hours"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/lightning":{"get":{"tags":["Lightning"],"summary":"Get Lightning","description":"Recent lightning flashes from GOES-19 GLM.\n\nReturns a GeoJSON FeatureCollection of flash point geometries. Properties\ninclude flash_time (ISO 8601), age_seconds (relative to now), and optional\nenergy/area fields when the source file included them.","operationId":"get_lightning_api_v1_lightning_get","parameters":[{"name":"bbox","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bounding box: west,south,east,north","title":"Bbox"},"description":"Bounding box: west,south,east,north"},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"US state abbreviation","title":"State"},"description":"US state abbreviation"},{"name":"minutes","in":"query","required":false,"schema":{"type":"integer","maximum":180,"minimum":1,"description":"Return flashes from the last N minutes","default":15,"title":"Minutes"},"description":"Return flashes from the last N minutes"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20000,"minimum":1,"description":"Max features to return. Lightning can easily produce several thousand flashes over a 15-minute window during active storms.","default":5000,"title":"Limit"},"description":"Max features to return. Lightning can easily produce several thousand flashes over a 15-minute window during active storms."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/signup":{"post":{"tags":["Auth"],"summary":"Signup","description":"Create a new user account and issue a session cookie.","operationId":"signup_api_v1_auth_signup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/login":{"post":{"tags":["Auth"],"summary":"Login","operationId":"login_api_v1_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/logout":{"post":{"tags":["Auth"],"summary":"Logout","operationId":"logout_api_v1_auth_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/auth/me":{"get":{"tags":["Auth"],"summary":"Me","operationId":"me_api_v1_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}}}}},"/api/v1/auth/verify-email":{"post":{"tags":["Auth"],"summary":"Verify Email","operationId":"verify_email_api_v1_auth_verify_email_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyEmailRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/resend-verification":{"post":{"tags":["Auth"],"summary":"Resend Verification","operationId":"resend_verification_api_v1_auth_resend_verification_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/auth/forgot-password":{"post":{"tags":["Auth"],"summary":"Forgot Password","description":"Always returns success so we don't leak account existence.","operationId":"forgot_password_api_v1_auth_forgot_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/reset-password":{"post":{"tags":["Auth"],"summary":"Reset Password","operationId":"reset_password_api_v1_auth_reset_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/account/api-keys":{"get":{"tags":["Account"],"summary":"List Api Keys","operationId":"list_api_keys_api_v1_account_api_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/APIKeyResponse"},"type":"array","title":"Response List Api Keys Api V1 Account Api Keys Get"}}}}}},"post":{"tags":["Account"],"summary":"Create Api Key","operationId":"create_api_key_api_v1_account_api_keys_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreatedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/account/api-keys/{key_id}":{"delete":{"tags":["Account"],"summary":"Revoke Api Key","operationId":"revoke_api_key_api_v1_account_api_keys__key_id__delete","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"integer","title":"Key Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/account/locations":{"get":{"tags":["Account"],"summary":"List Locations","operationId":"list_locations_api_v1_account_locations_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/SavedLocationResponse"},"type":"array","title":"Response List Locations Api V1 Account Locations Get"}}}}}},"post":{"tags":["Account"],"summary":"Create Location","operationId":"create_location_api_v1_account_locations_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLocationRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavedLocationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/account/locations/{loc_id}":{"patch":{"tags":["Account"],"summary":"Update Location","operationId":"update_location_api_v1_account_locations__loc_id__patch","parameters":[{"name":"loc_id","in":"path","required":true,"schema":{"type":"integer","title":"Loc Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLocationRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavedLocationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Account"],"summary":"Delete Location","operationId":"delete_location_api_v1_account_locations__loc_id__delete","parameters":[{"name":"loc_id","in":"path","required":true,"schema":{"type":"integer","title":"Loc Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/stats":{"get":{"tags":["Admin"],"summary":"Get Stats","operationId":"get_stats_api_v1_admin_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminStats"}}}}}}},"/api/v1/admin/users":{"get":{"tags":["Admin"],"summary":"List Users","operationId":"list_users_api_v1_admin_users_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search email or name","title":"Q"},"description":"Search email or name"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminUserListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/users/{user_id}":{"patch":{"tags":["Admin"],"summary":"Update User","operationId":"update_user_api_v1_admin_users__user_id__patch","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminUserRow"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/ingest-health":{"get":{"tags":["Admin"],"summary":"Get Ingest Health","description":"Per-source ingest health (read from Redis, populated by scheduler).","operationId":"get_ingest_health_api_v1_admin_ingest_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Ingest Health Api V1 Admin Ingest Health Get"}}}}}}},"/api/v1/watches":{"get":{"tags":["Watches"],"summary":"Get Watches","description":"Get SPC watches (tornado and severe thunderstorm).\n\nReturns a GeoJSON FeatureCollection of watch box polygons with\nthreat parameters (max hail, max wind, PDS status).","operationId":"get_watches_api_v1_watches_get","parameters":[{"name":"bbox","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bounding box: west,south,east,north","title":"Bbox"},"description":"Bounding box: west,south,east,north"},{"name":"point","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Center point: lat,lon","title":"Point"},"description":"Center point: lat,lon"},{"name":"radius","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Radius from point (e.g., 100km)","title":"Radius"},"description":"Radius from point (e.g., 100km)"},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"US state abbreviation","title":"State"},"description":"US state abbreviation"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Max results","default":100,"title":"Limit"},"description":"Max results"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Pagination offset","default":0,"title":"Offset"},"description":"Pagination offset"},{"name":"active","in":"query","required":false,"schema":{"type":"boolean","description":"Only active (non-expired) watches","default":true,"title":"Active"},"description":"Only active (non-expired) watches"},{"name":"type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter: TOR|SVR","title":"Type"},"description":"Filter: TOR|SVR"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/discussions":{"get":{"tags":["Mesoscale Discussions"],"summary":"Get Discussions","description":"Get SPC mesoscale discussions.\n\nReturns a GeoJSON FeatureCollection of MCD polygons with watch confidence,\nthreat parameters, and discussion text.","operationId":"get_discussions_api_v1_discussions_get","parameters":[{"name":"bbox","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bounding box: west,south,east,north","title":"Bbox"},"description":"Bounding box: west,south,east,north"},{"name":"point","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Center point: lat,lon","title":"Point"},"description":"Center point: lat,lon"},{"name":"radius","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Radius from point (e.g., 100km)","title":"Radius"},"description":"Radius from point (e.g., 100km)"},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"US state abbreviation","title":"State"},"description":"US state abbreviation"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Max results","default":50,"title":"Limit"},"description":"Max results"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Pagination offset","default":0,"title":"Offset"},"description":"Pagination offset"},{"name":"active","in":"query","required":false,"schema":{"type":"boolean","description":"Only active (non-expired) MCDs","default":true,"title":"Active"},"description":"Only active (non-expired) MCDs"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/meta/health":{"get":{"tags":["Meta"],"summary":"Get Health","description":"System health, per-source ingest status, and data freshness.\n\nPublic endpoint — safe to consume from a status page.","operationId":"get_health_api_v1_meta_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/meta/sources":{"get":{"tags":["Meta"],"summary":"Get Sources","description":"List all available data sources and their capabilities.","operationId":"get_sources_api_v1_meta_sources_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"APIKeyCreatedResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"prefix":{"type":"string","title":"Prefix"},"rate_limit":{"type":"integer","title":"Rate Limit"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","title":"Created At"},"last_used_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Used At"},"key":{"type":"string","title":"Key"}},"type":"object","required":["id","name","prefix","rate_limit","is_active","created_at","last_used_at","key"],"title":"APIKeyCreatedResponse"},"APIKeyResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"prefix":{"type":"string","title":"Prefix"},"rate_limit":{"type":"integer","title":"Rate Limit"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","title":"Created At"},"last_used_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Used At"}},"type":"object","required":["id","name","prefix","rate_limit","is_active","created_at","last_used_at"],"title":"APIKeyResponse"},"AdminStats":{"properties":{"users_total":{"type":"integer","title":"Users Total"},"users_active":{"type":"integer","title":"Users Active"},"users_verified":{"type":"integer","title":"Users Verified"},"users_admin":{"type":"integer","title":"Users Admin"},"signups_last_7d":{"type":"integer","title":"Signups Last 7D"},"signups_last_30d":{"type":"integer","title":"Signups Last 30D"},"saved_locations":{"type":"integer","title":"Saved Locations"},"api_keys_active":{"type":"integer","title":"Api Keys Active"},"alerts_active":{"type":"integer","title":"Alerts Active"},"alerts_total":{"type":"integer","title":"Alerts Total"},"reports_24h":{"type":"integer","title":"Reports 24H"},"observations_total":{"type":"integer","title":"Observations Total"}},"type":"object","required":["users_total","users_active","users_verified","users_admin","signups_last_7d","signups_last_30d","saved_locations","api_keys_active","alerts_active","alerts_total","reports_24h","observations_total"],"title":"AdminStats"},"AdminUserListResponse":{"properties":{"total":{"type":"integer","title":"Total"},"rows":{"items":{"$ref":"#/components/schemas/AdminUserRow"},"type":"array","title":"Rows"}},"type":"object","required":["total","rows"],"title":"AdminUserListResponse"},"AdminUserRow":{"properties":{"id":{"type":"integer","title":"Id"},"email":{"type":"string","title":"Email"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"role":{"type":"string","title":"Role"},"is_active":{"type":"boolean","title":"Is Active"},"email_verified":{"type":"boolean","title":"Email Verified"},"saved_locations":{"type":"integer","title":"Saved Locations"},"api_keys":{"type":"integer","title":"Api Keys"},"created_at":{"type":"string","title":"Created At"},"last_login_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Login At"}},"type":"object","required":["id","email","name","role","is_active","email_verified","saved_locations","api_keys","created_at","last_login_at"],"title":"AdminUserRow"},"CreateAPIKeyRequest":{"properties":{"name":{"type":"string","maxLength":128,"minLength":1,"title":"Name"}},"type":"object","required":["name"],"title":"CreateAPIKeyRequest"},"CreateLocationRequest":{"properties":{"name":{"type":"string","maxLength":128,"minLength":1,"title":"Name"},"lat":{"type":"number","maximum":90.0,"minimum":-90.0,"title":"Lat"},"lon":{"type":"number","maximum":180.0,"minimum":-180.0,"title":"Lon"},"label":{"anyOf":[{"type":"string","maxLength":256},{"type":"null"}],"title":"Label"},"alerts_enabled":{"type":"boolean","title":"Alerts Enabled","default":true},"min_severity":{"type":"string","title":"Min Severity","default":"Severe"}},"type":"object","required":["name","lat","lon"],"title":"CreateLocationRequest"},"ForgotPasswordRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"ForgotPasswordRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"LoginRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","title":"Password"}},"type":"object","required":["email","password"],"title":"LoginRequest"},"ResetPasswordRequest":{"properties":{"token":{"type":"string","title":"Token"},"password":{"type":"string","maxLength":128,"minLength":8,"title":"Password"}},"type":"object","required":["token","password"],"title":"ResetPasswordRequest"},"SavedLocationResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"lat":{"type":"number","title":"Lat"},"lon":{"type":"number","title":"Lon"},"alerts_enabled":{"type":"boolean","title":"Alerts Enabled"},"min_severity":{"type":"string","title":"Min Severity"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","name","label","lat","lon","alerts_enabled","min_severity","created_at"],"title":"SavedLocationResponse"},"SignupRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","maxLength":128,"minLength":8,"title":"Password"},"name":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Name"}},"type":"object","required":["email","password"],"title":"SignupRequest"},"UpdateLocationRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":128,"minLength":1},{"type":"null"}],"title":"Name"},"alerts_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Alerts Enabled"},"min_severity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Min Severity"}},"type":"object","title":"UpdateLocationRequest"},"UpdateUserRequest":{"properties":{"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"role":{"anyOf":[{"type":"string","pattern":"^(user|admin)$"},{"type":"null"}],"title":"Role"}},"type":"object","title":"UpdateUserRequest"},"UserResponse":{"properties":{"id":{"type":"integer","title":"Id"},"email":{"type":"string","title":"Email"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"role":{"type":"string","title":"Role"},"email_verified":{"type":"boolean","title":"Email Verified"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","email","name","role","email_verified","created_at"],"title":"UserResponse"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VerifyEmailRequest":{"properties":{"token":{"type":"string","title":"Token"}},"type":"object","required":["token"],"title":"VerifyEmailRequest"}}}}