blissgarden.

API documentation

The same frost dates, hardiness zones, and planting windows behind every BlissGarden page, served as JSON under /api/v1. Free and keyless, daily-cached, attribution requested. For a machine-readable version of this page, see /llms.txt.

Base URL & conventions
https://blissgarden.com/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.

Response shape
{
  "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
  }
}
{
  "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).

Response shape
{
  "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
  }
}
{
  "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.

Response shape
{
  "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
    }
  ]
}
{
  "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 — grab a copy-paste snippet on the tools page.

Place-page anchors

Every place page (/{state}/{city}) carries stable section anchors for deep links and citation:

  • #frost-probabilityFrost probability table
  • #plant-nowWhat to plant now
  • #calendarFull-year planting calendar
  • #faqPlanting FAQ
  • #stationsNearby weather stations

Data sources & attribution

  • 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).

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 methods: /methodology.

Every place page also offers a per-place CSV export of its frost-probability table and planting windows — no API needed.
See a place page →