Changed
- Daily endpoints (
/api/pollen?city=, /api/map-data, /api/city-type-matrix, /api/pollen-range?aggregate=day, and /api/available-dates) are served from a per-day summary that the ingest job maintains, instead of aggregating hourly rows on every request. Values are unchanged. aggregate=day now returns every whole UTC day that overlaps [from, to); a timestamp bound inside a day no longer produces a partial-day average.
Added
GET /api/health reports database reachability and the freshness of the daily ingest, pollen observations, and weather rows. It returns 200 when every check passes and 503 otherwise, for uptime monitors and agents.
Added
- Six cities that previously shared a slug are now distinct:
columbus-ga, kansas-city-ks, arlington-va, aurora-il, glendale-ca, and springfield-ma. The larger city of each pair keeps its original slug.
Changed
- City names for the disambiguated pairs now include the state, for example
Columbus, OH. - Weather ingestion stores air-quality rows even when the OpenWeather daily summary is unavailable, and records the summary failure.
Removed
honolulu is no longer a supported city; the provider has never returned pollen data for it.
Fixed
- On-demand forecast refreshes now release the scheduled-ingest quota reserve after the daily Ambee ingestion has completed.
Added
- Daily city rows now include peak category and total values plus peak risk labels alongside the existing daily averages.
- Sentry captures client, server, edge, and global application errors when
NEXT_PUBLIC_SENTRY_DSN is configured.
Changed
- The website now uses a latest-only map with bottom-anchored category controls and a compact layer menu on mobile.
- City pages now show the latest day in detail followed by a table containing the complete captured daily history.
- Hourly observations and forecasts remain available through the public API and MCP tools but are no longer rendered on city pages.
Fixed
- Forecast refresh failures now fall back to existing cached rows with
stale: true. - The map control panel now groups controls and instructions clearly without stray separator bullets.
Added
- Interactive Swagger UI for safe live read-only requests.
- Full OpenAPI response examples and curl, JavaScript, and Python samples for every operation.
- Explicit MCP output schemas with validated structured content.
- Expanded agent workflow and response guidance in
/llms.txt. - Redocly OpenAPI validation in local tooling and CI.
Fixed
- Exact forecast rows and complete map feature properties are now reflected in OpenAPI.
Added
- Wildcard CORS on public read-only REST routes.
- Explicit daily-category-maximum metadata and labeling for map values.
- Five-minute shared edge caching with stale-while-revalidate.
Changed
- Invalid, zero, negative, fractional, and oversized
limit values now return 400.
Fixed
- Malformed and impossible date parameters now return
400 before querying the database. - Database connection and query failures are distinguished in private logs, while public errors no longer expose configuration hints.
Breaking changes
- Daily pollen rows now use
tree, grass, weed, and total instead of avg_* names. - Pollen-range hourly and daily modes now return one flat row shape.
Added
- One documented
404 UNSUPPORTED_CITY response across all city-aware REST operations, with the same actionable error message from MCP tools. - Hosted MCP discovery metadata in OpenAPI.
- Complete pollen data in the initial server-rendered city page HTML.
September 20, 2025
1.0.0
Initial public pollen, forecast, weather, map, OpenAPI, and discovery endpoints.