# SkyNow property & casualty data catalog

Research date: **2026-10-10**. This is an implementation plan, not a promise of service availability. API versions, rate limits and data coverage must be rechecked before scheduled ingestion. No paid calls or private keys are used by the prototype.

## What is implemented

- **Property brief:** NWS point discovery, active point alerts, hourly forecast and one station observation; FEMA NFHL point attributes; USGS Water Data v1 nearby latest stage readings.
- **Portfolio scenario:** local CSV and explicitly hypothetical circular footprint/damage/retention/limit calculations. No external hazard model or loss estimate is hidden behind it.
- **Evidence timeline:** dated USGS earthquake radius search and overlapping OpenFEMA declaration incidents by state; current NWS records can be copied from the brief. Analyst notes remain unverified. JSON includes query, retrieval time, original response text and SHA-256 where Web Crypto is available.
- **Catalog only:** additional grid variables, historical station archive ingestion, Storm Events/SWDI, coastal levels, NHC, drought, NFIP aggregates and NRI. These are not yet live charts or a populated database.

## 1. NWS discovery, alerts, forecast grids and observations

**Primary sources:** [API documentation](https://www.weather.gov/documentation/services-web-api), [official OpenAPI](https://api.weather.gov/openapi.json), [grid fields](https://github.com/weather-gov/api/blob/master/gridpoints.md).

```text
GET https://api.weather.gov/points/26.962,-82.3526
GET https://api.weather.gov/alerts/active?point=26.962,-82.3526
GET {properties.forecastGridData from /points}
GET {properties.forecastHourly from /points}
GET {properties.observationStations from /points}
GET https://api.weather.gov/stations/{station}/observations/latest
GET https://api.weather.gov/stations/{station}/observations?start={RFC3339}&end={RFC3339}&limit=100
```

NWS is free/open, with unpublished reasonable rate limits. A descriptive User-Agent with a maintained contact is appropriate for a future backend; browsers cannot reliably set it themselves. Honor caching and Retry-After. Discover grid URLs instead of assuming a permanent office/cell mapping. Quantities include units and nulls. Grid `validTime` intervals must be preserved; issued, valid, observed and retrieved time differ. Active alerts are not a historical archive. Alert geometry may be null: keep affected zones and original CAP identifiers. Station values describe that station, not a property's roof.

**Proposed P&C use:** preparedness, freeze/wind/rain context and a retained contemporaneous alert record. Add `quantitativePrecipitation`, `snowfallAmount`, `iceAccumulation`, `windGust`, `minTemperature` and `maxTemperature` from the grid where present; do not derive hail impact from reflectivity alone. SkyNow already uses temperature, humidity, precipitation probability, wind/gust and sky cover.

**Ingestion plan:** resolve points daily or on mapping change; alerts every 2–5 minutes only for subscribed regions; grids every 30–60 minutes subject to cache; station observations 10–15 minutes. These cadences are proposed product choices, not upstream SLAs. Keys: alert ID + sent/revision; office/x/y + issue time + field + valid interval; station ID + observed time + field. Cache shared cells once across a portfolio.

## 2. FEMA National Flood Hazard Layer (NFHL)

**Primary sources:** [live service metadata](https://hazards.fema.gov/arcgis/rest/services/public/NFHL/MapServer), [layer 28 schema](https://hazards.fema.gov/arcgis/rest/services/public/NFHL/MapServer/28), [official map center](https://msc.fema.gov/portal/home), [NFHL guidance](https://www.fema.gov/sites/default/files/2020-02/NFHL_Guidance_Feb_2019.pdf).

```text
GET https://hazards.fema.gov/arcgis/rest/services/public/NFHL/MapServer/28/query?geometry=-82.3526,26.962&geometryType=esriGeometryPoint&inSR=4326&spatialRel=esriSpatialRelIntersects&outFields=OBJECTID,DFIRM_ID,FLD_AR_ID,FLD_ZONE,ZONE_SUBTY,SFHA_TF,STATIC_BFE,V_DATUM,LEN_UNIT,SOURCE_CIT,GlobalID&returnGeometry=false&f=json
```

The public service worked without a key. Layer 28 identifies flood-hazard zones; the inspected service has a 2,000-record maximum and native NAD83 / EPSG:4269 geometry. Use explicit input/output CRS and record transformations. SFHA is an attribute, not a coverage decision. Retain map version/citation, zone, datum and units. Missing polygons do not mean no flood risk; check availability, amendments and official map products. Boundary/parcel decisions need parcel geometry, positional uncertainty and professional review.

**Plan:** daily change checks for saved locations and release-based bulk versions. Store `GlobalID` when present plus release/hash; OBJECTID alone is not a durable cross-release key. Preserve every intersecting polygon. For portfolio ingestion page through object IDs or provider pagination and inspect `exceededTransferLimit`. No blanket production quota or SLA was verified.

## 3. OpenFEMA declarations and NFIP research

**Primary sources:** [official machine-readable API definition](https://www.fema.gov/api/open/metadata/v3.0/OpenApi.json), [official samples](https://github.com/FEMA/openfema-samples), [API documentation](https://www.fema.gov/about/openfema/api), [terms](https://www.fema.gov/about/openfema/terms-conditions).

```text
GET https://www.fema.gov/api/open/v2/DisasterDeclarationsSummaries?$filter=state%20eq%20%27FL%27&$top=100&$orderby=declarationDate%20desc
GET https://www.fema.gov/api/open/v3/NfipClaims?$top=1
```

Official metadata currently lists **v3/NfipClaims** and legacy **v2/FimaNfipClaims**; discover the current dictionary before building a claims adapter. This prototype only requests declarations. OpenAPI defines `$top` default 1,000 and maximum 10,000; use `$skip`, a deterministic order and reconciliation. Public reads need no API key in the inspected spec. Exact throttle ceilings were not established. FEMA attribution/terms apply; no endorsement is implied.

**Plan:** declarations hourly during an incident, daily otherwise; NFIP only on published refresh with incremental reconciliation. Keep `id`, `hash`/`lastRefresh` where provided, declaration date, incident interval, designation and full FIPS strings. One disaster has many area records; never count rows as separate disasters. Null incident end is unknown, not evidence that the incident continues. Such records are matched only when their start is inside the requested window. NFIP is for deidentified aggregate research; never infer an individual property's claims from generalized coordinates. No private policy or customer data is fetched. Suggested joins are county/tract and event/time windows with documented precision, not a guessed address match. FEMA site HTML access was blocked during research, but API metadata and bounded declaration calls succeeded.

## 4. NOAA NCEI Storm Events

**Primary sources:** [modernized database](https://www.ncei.noaa.gov/access/storm-events-database/), [bulk files](https://www.ncei.noaa.gov/pub/data/swdi/stormevents/csvfiles/), [bulk format](https://www.ncei.noaa.gov/pub/data/swdi/stormevents/csvfiles/Storm-Data-Bulk-csv-Format.pdf).

```text
GET https://www.ncei.noaa.gov/pub/data/swdi/stormevents/csvfiles/
# Discover the actual dated filenames; never guess the creation suffix.
# StormEvents_details-ftp_v1.0_dYYYY_cYYYYMMDD.csv.gz
# Matching locations and fatalities tables use event_id.
```

Significant-weather reports are published after review and can be revised; coverage and reporting practices vary across periods. The catalog page currently extends through June 2026, so it is not a live-alert feed. Use annual compressed files for backfill. `event_id` joins the tables; locations have `location_index`, while `episode_id` groups events. Keep `CZ_TIMEZONE` with original local event times before UTC conversion. Damage strings need explicit K/M/B parsing with unknown distinct from zero. Point/path/county reports do not establish parcel damage. Certified reports require NCEI's separate certification process.

**Plan:** monthly manifest checks, checksummed annual versions, latest two years reprocessed after updates. Public downloads require no key; paid certification is out of scope. Store event ID + file hash/version, event type, magnitude/unit, source, narrative, time precision and geometry provenance.

## 5. NOAA Severe Weather Data Inventory (SWDI)

**Primary sources:** [SWDI source descriptions and caveats](https://www.ncei.noaa.gov/maps/swdi/), [bulk archive](https://www.ncei.noaa.gov/pub/data/swdi/).

```text
GET https://www.ncei.noaa.gov/swdiws/json/nx3hail/20240501:20240502?bbox=-98,32,-96,34
```

The bounded example returned radar-derived hail records on 2026-10-10. Response records are under `result`; fields included `ZTIME`, `WSR_ID`, `CELL_ID`, `MAXSIZE`, `PROB`, `SEVPROB` and WKT `SHAPE`. Radar signatures are probable conditions, not confirmed ground impacts. Incomplete spatial/temporal coverage makes an empty response inconclusive. Provider quality checks are not strengthened by the inventory. Not all included data has identical licensing: exclude restricted lightning data unless terms are separately reviewed.

**Plan:** one-day/limited-bbox partitions; archive source bytes and query bounds; deduplicate by dataset/radar/cell/time plus payload hash. A probe adding `limit=1` still returned multiple records, so the implementation must not assume that parameter bounds a response. Historical backfills should use bulk archives and server-side streaming/size limits. Numeric hail units and column definitions must be pinned from dataset metadata before normalized use. No automatic SWDI calls in the browser prototype; this avoids an unbounded archival download.

## 6. USGS Water Data v1

**Primary sources:** [OGC API guide](https://api.waterdata.usgs.gov/docs/ogcapi/), [key/rate headers](https://api.waterdata.usgs.gov/docs/ogcapi/keys/), [v1 release and migration](https://waterdata.usgs.gov/blog/api-v1-release/), [live queryables](https://api.waterdata.usgs.gov/ogcapi/v1/collections/latest-continuous/queryables?f=json).

```text
GET https://api.waterdata.usgs.gov/ogcapi/v1/collections/monitoring-locations/items?f=json&bbox=-82.7,26.7,-82,27.2&limit=25
GET https://api.waterdata.usgs.gov/ogcapi/v1/collections/latest-continuous/items?f=json&bbox=-82.7,26.7,-82,27.2&parameter_code=00065&limit=25
GET https://api.waterdata.usgs.gov/ogcapi/v1/collections/continuous/items?f=json&monitoring_location_id=USGS-02299230&parameter_code=00065&datetime=2026-10-01T00:00:00Z/2026-10-02T00:00:00Z&limit=100
```

Use v1 for new work; USGS states legacy WaterServices is planned to retire in early 2027. Optional API keys raise limits; inspect `X-RateLimit-Limit/Remaining` and 429 responses instead of assuming an allowance. Unauthenticated bounded calls succeeded. Follow returned `rel=next`, not invented offsets. Latest can include discontinued years-old measurements: a live probe returned a 2013 record. Preserve parameter (00065 stage, 00060 discharge), statistic, unit, qualifier and approval status. Stage is relative to a gauge datum, not ground elevation or property flood depth.

**Plan:** 15-minute retrieval for selected active gauges; weekly metadata; historical backfill in small time windows. Store `time_series_id` + time + revision/last_modified and raw item ID. Select hydrologically relevant gauges; geographic proximity alone cannot establish upstream/downstream relevance. Stale/discontinued gauges remain distinguishable.

## 7. USGS earthquake catalog and ShakeMap

**Primary source:** [catalog API](https://earthquake.usgs.gov/fdsnws/event/1/).

```text
GET https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2026-10-01&endtime=2026-10-08&latitude=26.962&longitude=-82.3526&maxradiuskm=100&minmagnitude=2.5&limit=200
GET https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson
```

Catalog supports a 20,000-result service ceiling; prototype caps at 200 and labels possible truncation. GeoJSON coordinates are longitude, latitude, depth-km; times are epoch milliseconds. Retain event ID, update time, review status, magnitude type and uncertainty. A magnitude/radius match is contextual evidence, not local shaking or damage. For future intensity work discover each event's ShakeMap products and versions. USGS recommends real-time feeds for automated current displays.

**Plan:** event feed every 5 minutes subject to cache, with revision reconciliation; bounded historical searches on demand. No key required for public catalog. Store event ID + updated and product revision. Query radius is not a shaking footprint.

## 8. NOAA coastal observations

**Primary sources:** [CO-OPS API](https://api.tidesandcurrents.noaa.gov/api/prod/), [response fields](https://api.tidesandcurrents.noaa.gov/api/prod/responseHelp.html), [metadata API](https://api.tidesandcurrents.noaa.gov/mdapi/prod/).

```text
GET https://api.tidesandcurrents.noaa.gov/api/prod/datagetter?station=8726520&product=water_level&date=recent&datum=MLLW&time_zone=gmt&units=metric&format=json&application=LevitizedLifeLabs
GET https://api.tidesandcurrents.noaa.gov/mdapi/prod/webapi/stations/8726520.json?expand=details,datums
```

Water levels require a datum; retain station, product, datum, unit, time basis, quality and flags. Preliminary observations and verified data differ. Six-minute requests are bounded to about one month; use product-specific limits. Predicted tides are not storm-surge forecasts. Never subtract a building elevation in NAVD88 from an MLLW water level without a valid local datum transformation. No key is required by the documented public calls; throttle and bounded windows still apply.

**Plan:** 6–15-minute observations; monthly recheck for verified replacements. Key station/product/time/datum + revision/hash. Coastal context can support loss investigation, never prove inundation of a parcel by itself.

## 9. Hurricane tracks, drought and community risk

- **NHC:** [archive and HURDAT2](https://www.nhc.noaa.gov/data/), [status JSON reference](https://www.nhc.noaa.gov/productexamples/NHC_Tropical_Cyclone_Status_JSON_File_Reference.pdf). Discover `https://www.nhc.noaa.gov/CurrentStorms.json` and linked products. Retain storm ID, advisory number, issue/valid time, product type and run. HURDAT2/post-analysis is distinct from operational forecast and preliminary best track. A forecast cone is not the wind-impact boundary. Poll metadata 15–30 minutes during storms; archive only changed products. No paid calls; large files belong in object storage.
- **U.S. Drought Monitor:** [official REST documentation](https://www.droughtmonitor.unl.edu/DmData/DataDownload/WebServiceInfo.aspx), [metadata](https://droughtmonitor.unl.edu/DmData/Metadata.aspx). Example: `https://usdmdataservices.unl.edu/api/CountyStatistics/GetDroughtSeverityStatisticsByAreaPercent?aoi=12115&startdate=9/1/2026&enddate=10/10/2026&statisticsType=2`. Request `Accept: application/json`. Keep categorical versus cumulative statistics separate; do not sum cumulative drought percentages. County/HUC geography is not parcel soil moisture. Weekly release ingestion and required NDMC/NOAA/USDA attribution; review reuse terms for redistribution.
- **FEMA National Risk Index:** [technical documentation](https://www.fema.gov/sites/default/files/documents/fema_national-risk-index_technical-documentation.pdf), [download portal](https://hazards.fema.gov/nri/data-resources). Versioned tract/county baseline and expected annual loss can contextualize a portfolio. Those aggregated model outputs cannot be assigned as a property's predicted loss or policy price. Ingest by release, store geography vintage and model version; discover current download URL from the official portal, not a guessed permanent asset. Use hazard/exposure fields separately from social vulnerability; no individual underwriting decisions are implemented.

## Database and ingestion contract (proposed, not running)

`api-registry.json` provides machine-readable source IDs, examples and priorities. `schema.sql` targets **SQLite / Cloudflare D1** to align with SkyNow; geospatial joins at scale may later warrant PostGIS. Store normalized lon/lat plus explicit GeoJSON, CRS and spatial precision. D1 has no built-in robust polygon overlay in this proposal: materialize validated joins outside the browser, or use PostGIS after a separate migration decision.

The offline `import-bundle.mjs` handoff now validates original export hashes and prepares source-registry/ingest-run rows only; see `README.md` for commands, exact source aliases, limits and replay behavior. Hourly forecast periods and station discovery each have a distinct registry entry, bringing the registry to 17. The importer makes no requests and does not implement the normalized geospatial model or create a cloud database.

1. Capture request URL without secrets, headers relevant to caching/version, response status, fetched time, raw-object key and SHA-256. Keep unavailable, empty, partial and successful separate.
2. Validate schema, spatial extent, units, dates and record count before promoting a run. Store parse errors separately; never turn null into zero. A checksum establishes identity, not source authenticity or legal certification.
3. Normalize immutable observations/events, keeping original source values and revisions. Set observed/issue/valid/received times separately. Dates without times stay dates; uncertain timezone conversion is a quality flag.
4. Upsert a current view by source record key, retaining old revisions. Use overlap backfill and periodic reconciliation to catch amended/deleted records. A cursor is not a permanent event identity.
5. Intersect exposures using the proper geography: parcel/polygon for flood mapping, geographic/meteorological footprints for weather, basin connectivity for river gauges. Record join method/version and uncertainty. Never join generalized claims to exact addresses.
6. Keep scenario assumptions in separate tables from official records. Track input hashes, model/algorithm version and output units. There is no coverage/pricing engine here.
7. Separate protected customer exposure data from public hazard tables. The prototype sends no portfolio CSV off-device. Before a server upload feature, add ownership/authentication, retention/deletion and export controls.

## Suggested build order

**First return session:** choose one workflow; provision no new database until its ownership and data retention are chosen. Adopt NWS provenance, NFHL versioning and USGS freshness checks. Add a source health view and 429 backoff with jitter. Cache at shared-cell/gauge level and enforce per-source request budgets.

**Second:** backfill Storm Events and SWDI partitions; retain exact source files; implement claim evidence manifests. Do not substitute active alerts for historical warnings.

**Third:** coastal datum-safe context, NHC advisories and aggregate NFIP/NRI research. Calibrate and validate a hazard/vulnerability model independently before offering any probabilistic loss output.

## Verification recorded 2026-10-10

Live bounded calls returned valid data for NFHL point attributes, OpenFEMA declarations, USGS Water v1, USGS earthquakes and SWDI hail archive. Service schemas were inspected for NFHL fields, USGS v1 queryables and OpenFEMA endpoints/page limits. Successful terminal requests do **not** establish browser CORS or production uptime; browser verification is recorded separately in README. No continuous ingestion or database population occurred.
