The shared spine under every crop bot: what this exact spot has done, what is coming to it, and where the plant is on its heat clock. One platform, many finite verticals.
…
| Endpoint | What it answers |
|---|---|
/api/locality?lat=&lon= | Frost dates this point actually recorded, season heat, annual rain, coldest night, and the direction weather arrives from. Ten years of daily history by default, not a zone map. |
/api/weather/backlog?lat=&lon=&start=&end= | The track log: every day's high, low, rain and sunshine, with degree days accumulating across the window and the longest dry run. |
/api/weather/ahead?lat=&lon= | Seven days out, plus the upstream point on the current flow and what is over it now. Weather comes from somewhere; this says where and what. |
/api/stage?crop=&planted=&lat=&lon= | Seed to fruit on the heat clock: degree days since planting, the stage that accumulation puts the plant in, and the days to the next one at the forecast rate. |
/api/crops · /api/crop/<slug> | The registry: every finite vertical, stated, labeled and listed, with its stage table and sources. |
/api/vision/contract | How a vertical asks the vision lane to read a photo, and what comes back. The contract is fixed; the models behind it are not. |
crops.json with its slug, its heat base and cap, and a stage table whose every threshold cites where it came from. Drop a page under public/crops/ if it wants its own face. The wildcard already resolves, so no new record is needed. No platform change. A crop with no sourced stage table gets an empty one and still receives locality, frost, backlog and forecast — an empty table is honest, an invented one is not.