# BlissGarden — U.S. frost dates, USDA hardiness zones & planting calendars # https://blissgarden.com ## What this is BlissGarden turns two local frost dates — the average last spring frost and first fall frost — into a month-by-month planting calendar for any U.S. city. Every place page carries station-attributed 1991–2020 NOAA freeze normals, the USDA hardiness zone, and per-crop start-indoors / transplant / direct-sow / fall-sow windows. The same data is available as JSON under /api/v1 — free and keyless. ## Page URL patterns https://blissgarden.com/ Home: ZIP lookup + featured states and crops https://blissgarden.com/{state} State hub — city list and state-wide frost spread (e.g. /georgia) https://blissgarden.com/{state}/{city} Place page — frost dates, zone, planting calendar (e.g. /georgia/atlanta) https://blissgarden.com/{state}/{city}/frost-data.csv Per-place CSV — frost-probability table + planting windows https://blissgarden.com/plants/{slug} Crop guide with ZIP personalization (e.g. /plants/tomato) https://blissgarden.com/plants/{slug}/{state} When to plant a crop in a state, by city (e.g. /plants/garlic/texas) https://blissgarden.com/calendar/{state} State planting calendar by city and month (e.g. /calendar/georgia) https://blissgarden.com/tools/frost-dates ZIP → frost dates lookup https://blissgarden.com/tools/seed-starting-calculator ZIP + crop → planting date list https://blissgarden.com/methodology Data sources, station join, and attribution https://blissgarden.com/api-docs Human-readable API documentation https://blissgarden.com/reports/frost-shift Data report: 1981–2010 vs 1991–2020 frost-date shift by city and state {state} and {city} are lowercase, hyphenated slugs; {slug} is a crop slug. Only cities with an assigned zone, a NOAA station within 50 km, complete 32°F normals, and population ≥ 10,000 are published, so not every place has a page. ## API — /api/v1 Every response uses the envelope { "data": ... }. Errors return a JSON body { "error": "..." } with HTTP 400 (malformed or missing ZIP) or 404 (well-formed but unknown ZIP). Responses are cacheable for one day (Cache-Control: public, max-age=86400) and are regenerated daily. Free and keyless — no API key or auth is required. Please rate-limit politely. ### GET /api/v1/zones/{zip} The ZIP's USDA hardiness zone plus the nearest publishable place page. { "data": { "zip": string, // the 5-digit ZIP you requested "zone": string | null, // the ZIP's USDA hardiness zone, e.g. "8a" "nearestPlace": { // nearest publishable place page, or null if none within ~200 km "name": string, "slug": string, "state_slug": string, "state_abbrev": string, "zone": string | null, "url": string, // path to the place page, e.g. "/georgia/atlanta" "km": number // distance from the ZIP centroid, in km } | null } } Example — GET https://blissgarden.com/api/v1/zones/30303 { "data": { "zip": "30303", "zone": "8a", "nearestPlace": { "name": "Atlanta", "slug": "atlanta", "state_slug": "georgia", "state_abbrev": "GA", "zone": "8a", "url": "/georgia/atlanta", "km": 3.201738205913127 } } } ### GET /api/v1/frost-dates?zip={zip} The ZIP's zone, 32°F frost dates at the 10/50/90% probabilities, frost-free season length, the NOAA station used, and the nearest place page to link back to. For remote or effectively frost-free ZIPs with no station in range, "frostFree" is true, the frost fields are null, and the status is still 200 (not an error). { "data": { "zip": string, "zone": string | null, // the ZIP's USDA hardiness zone "frostFree": boolean, // true => no NOAA freeze station in range; frost fields are null "station": { // the NOAA station the dates come from, or null "id": string, "name": string | null, "km": number // distance from the ZIP centroid to the station, in km } | null, "lastSpringFrost": { // 32°F, 50/10/90% ISO dates carrying the current year; null when frostFree "p10": string, "p50": string, "p90": string } | null, "firstFallFrost": { // 32°F; same shape; null when frostFree "p10": string, "p50": string, "p90": string } | null, "growingSeasonDays": number | null, // frost-free days between the 32°F p50 anchors; null when frostFree "nearestPlace": { … same shape as /zones nearestPlace … } | null } } Example — GET https://blissgarden.com/api/v1/frost-dates?zip=30303 { "data": { "zip": "30303", "zone": "8a", "frostFree": false, "station": { "id": "USW00003888", "name": "ATLANTA FULTON CO AP", "km": 12.474559807084498 }, "lastSpringFrost": { "p10": "2026-04-10", "p50": "2026-03-24", "p90": "2026-03-02" }, "firstFallFrost": { "p10": "2026-10-27", "p50": "2026-11-08", "p90": "2026-11-26" }, "growingSeasonDays": 229, "nearestPlace": { "name": "Atlanta", "slug": "atlanta", "state_slug": "georgia", "state_abbrev": "GA", "zone": "8a", "url": "/georgia/atlanta", "km": 3.201738205913127 } } } ### GET /api/v1/crops Every crop with its planting offsets, name-ordered. { "data": [ { "slug": string, "name": string, "type": string | null, // "vegetable" | "herb" "hardiness": string | null, // "tender" | "half-hardy" | "hardy" | "very-hardy" "days_to_maturity": [min, max] | null, // days from transplant (or direct sow) // Week-range offsets from the local frost dates (50% probability, 32°F). null = action N/A. "start_indoors_weeks_before_last_frost": [min, max] | null, // weeks BEFORE last spring frost "transplant_weeks_relative_to_last_frost": [min, max] | null, // relative to last frost; negative = before "direct_sow_weeks_relative_to_last_frost": [min, max] | null, // relative to last frost; negative = before "fall_sow_weeks_before_first_frost": [min, max] | null // weeks BEFORE first fall frost } ] } Example — GET https://blissgarden.com/api/v1/crops (The full "data" array holds all 156 crops; one element shown.) { "data": [ { "slug": "acorn-squash", "name": "Acorn Squash", "type": "vegetable", "hardiness": "tender", "days_to_maturity": [ 80, 100 ], "start_indoors_weeks_before_last_frost": null, "transplant_weeks_relative_to_last_frost": null, "direct_sow_weeks_relative_to_last_frost": [ 1, 3 ], "fall_sow_weeks_before_first_frost": null } ] } ## Per-place CSV export Every place page offers a CSV export: its full frost-probability table (every temperature threshold × every ingested probability, ISO dates) followed by its per-crop planting-window dates — two labeled sections in one file. Same 1991–2020 NOAA normals as the page; regenerated daily. https://blissgarden.com/{state}/{city}/frost-data.csv Example: https://blissgarden.com/georgia/atlanta/frost-data.csv ## Calendar (.ics) export An iCalendar (.ics) download of the requested crops' planting windows at a ZIP's frost dates — one all-day event per open-able window (start-indoors, transplant, direct-sow, fall-sow), with stable UIDs (zip+crop+action+year). A malformed ZIP, empty/unknown crops return 400; an unknown ZIP 404; an effectively frost-free ZIP 422. https://blissgarden.com/api/v1/calendar.ics?zip={zip}&crops={slug,slug} Example: https://blissgarden.com/api/v1/calendar.ics?zip=30303&crops=tomato,kale,garlic ## Embeddable widget A self-contained, iframe-embeddable frost-dates card (place name, USDA zone, last-spring / first-fall frost, growing-season days) that links back to the city's place page. This route sets Content-Security-Policy: frame-ancestors * so it can be framed anywhere; the rest of the site is unaffected. Cached one day. A copy-paste iframe snippet generator lives at /tools. https://blissgarden.com/embed/frost-dates?zip={zip} Example: https://blissgarden.com/embed/frost-dates?zip=30303 ## Place-page anchors Each place page (https://blissgarden.com/{state}/{city}) carries stable section anchors, for deep links and citation: #frost-probability Frost probability table #plant-now What to plant now #calendar Full-year planting calendar #faq Planting FAQ #stations Nearby weather stations ## Data sources & update cadence - USDA Plant Hardiness Zone Map, 2023 revision (based on 1991–2020 normals) — PRISM Climate Group, Oregon State University. Powers "zone". - NOAA NCEI U.S. Climate Normals 1991–2020 — per-station last-spring / first-fall freeze probabilities (U.S. government work, public domain). Powers every frost date. NOAA issues a new 30-year normals product about once a decade; the current basis is 1991–2020. - U.S. Census Gazetteer, 2025 vintage — place and ZIP (ZCTA) centroids; ACS 5-year 2024 — place population. These decide which cities publish and how a ZIP joins to a city. - Crop planting windows — committed in-repo, derived from university-extension guidance (all frost references are the 50% probability, 32°F normals). The underlying climate data changes only when these upstream datasets are revised; pages and API responses are regenerated daily. ## Attribution Free and keyless — no API key or auth is required. Please rate-limit politely. If you surface frost dates from this API, please link back to the relevant place page (the "nearestPlace.url" in the response) and credit USDA-ARS + Oregon State University / PRISM (hardiness zones), NOAA NCEI (freeze normals), and the U.S. Census Bureau (place and ZIP geography). Full attribution and methodology: https://blissgarden.com/methodology