{
  "openapi": "3.1.1",
  "info": {
    "title": "Sowing and Planting Calendar API",
    "version": "1.0.0",
    "summary": "When to sow indoors, plant out, sow outside and harvest, from your own frost dates.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://hearthsowingcalendar.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "When to sow indoors, plant out, sow outside and harvest, from your own frost dates.",
        "description": "Turns your last spring and first autumn frost dates into a sowing and planting calendar for up to 40 vegetables and herbs: indoor sowing, planting out, sowing outside with successive sowings, autumn planting and the harvest window, plus a calendar file with every date.\n\nMethodology:\n- Crop timings come from our crop table (40 vegetables and herbs, each cited to its RHS “Grow your own” page): weeks to sow indoors and to plant out or sow outside, counted from your last spring frost; garlic is planted around the first autumn frost.\n- Tender crops (tomato, beans, courgette …) go out only after the last frost; half-hardy crops take a light frost; hardy crops (peas, broad beans, onions, carrots, cabbage) are sown or planted weeks before it.\n- Successive sowings repeat every 2–3 weeks while the crop still ripens before frost: the last sowing is the first autumn frost minus the days to harvest, minus 14 more days for tender crops and plus 14 for hardy ones.\n- Harvest starts at the first planting plus the days to harvest. Long-cropping plants (tomatoes, courgettes, kale, herbs …) are picked until the first autumn frost (tender), two weeks later (half-hardy) or six weeks later (hardy); others for three to six weeks after ripening.\n- Calendar file: one all-day event per window start and per sowing, named after the task.\n\nTimings are rules of thumb for temperate gardens. Soil temperature, variety and the weather of the year matter more than any calendar.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "hearth_sowing_calendar",
        "x-owner-app": "hearth",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HearthSowingCalendarInput"
              },
              "examples": {
                "example1": {
                  "summary": "Berlin, typical frost dates, five crops",
                  "value": {
                    "crops": [
                      "tomato",
                      "lettuce",
                      "carrot",
                      "bush-bean",
                      "garlic"
                    ],
                    "lastFrost": "04-08",
                    "firstFrost": "11-02",
                    "year": 2027
                  }
                },
                "example2": {
                  "summary": "Munich, cautious dates, salad and brassicas",
                  "value": {
                    "crops": [
                      "lettuce",
                      "radish",
                      "kohlrabi",
                      "broccoli",
                      "spinach",
                      "rocket"
                    ],
                    "lastFrost": "05-06",
                    "firstFrost": "10-06",
                    "year": 2027
                  }
                },
                "example3": {
                  "summary": "New York, summer crops",
                  "value": {
                    "crops": [
                      "tomato",
                      "pepper",
                      "zucchini",
                      "cucumber",
                      "basil",
                      "sweetcorn"
                    ],
                    "lastFrost": "04-09",
                    "firstFrost": "11-06",
                    "year": 2027
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HearthSowingCalendarResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "HearthSowingCalendarInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "crops": {
            "title": "Crops",
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "tomato",
                "pepper",
                "eggplant",
                "potato",
                "cucumber",
                "zucchini",
                "squash",
                "melon",
                "sweetcorn",
                "bush-bean",
                "pole-bean",
                "pea",
                "broad-bean",
                "lettuce",
                "spinach",
                "chard",
                "beet",
                "carrot",
                "parsnip",
                "radish",
                "turnip",
                "onion",
                "spring-onion",
                "garlic",
                "leek",
                "cabbage",
                "broccoli",
                "cauliflower",
                "kale",
                "brussels-sprouts",
                "kohlrabi",
                "pak-choi",
                "rocket",
                "celery",
                "fennel",
                "parsley",
                "basil",
                "dill",
                "coriander",
                "chives"
              ]
            },
            "default": [
              "tomato",
              "lettuce",
              "carrot",
              "bush-bean",
              "garlic"
            ]
          },
          "lastFrost": {
            "title": "Last spring frost (MM-DD)",
            "description": "Month and day, for example 04-20. The Frost Dates Finder gives it for Germany and the United States.",
            "type": "string",
            "maxLength": 5,
            "default": "04-20"
          },
          "firstFrost": {
            "title": "First autumn frost (MM-DD)",
            "type": "string",
            "maxLength": 5,
            "default": "10-15"
          },
          "year": {
            "title": "Season (year of the spring frost)",
            "type": "integer",
            "minimum": 2000,
            "maximum": 2100,
            "default": 2027
          }
        },
        "required": [
          "lastFrost",
          "firstFrost"
        ]
      },
      "HearthSowingCalendarResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "year",
              "lastFrost",
              "firstFrost",
              "frostFreeDays",
              "crops",
              "events",
              "tooLong",
              "ics"
            ],
            "properties": {
              "year": {
                "type": "integer"
              },
              "lastFrost": {
                "type": "string"
              },
              "firstFrost": {
                "type": "string"
              },
              "frostFreeDays": {
                "type": "integer"
              },
              "crops": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "crop",
                    "name",
                    "frost",
                    "daysToHarvest",
                    "tasks",
                    "sowings",
                    "lastSowing",
                    "fits",
                    "source"
                  ],
                  "properties": {
                    "crop": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "frost": {
                      "enum": [
                        "tender",
                        "half-hardy",
                        "hardy"
                      ]
                    },
                    "daysToHarvest": {
                      "type": "integer"
                    },
                    "tasks": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "task",
                          "from",
                          "to"
                        ],
                        "properties": {
                          "task": {
                            "enum": [
                              "indoor",
                              "out",
                              "direct",
                              "autumn",
                              "harvest"
                            ]
                          },
                          "from": {
                            "type": "string"
                          },
                          "to": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "sowings": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "lastSowing": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "fits": {
                      "type": "boolean"
                    },
                    "source": {
                      "type": "string"
                    }
                  }
                }
              },
              "events": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "date",
                    "crop",
                    "task",
                    "until"
                  ],
                  "properties": {
                    "date": {
                      "type": "string"
                    },
                    "crop": {
                      "type": "string"
                    },
                    "task": {
                      "type": "string"
                    },
                    "until": {
                      "type": "string"
                    }
                  }
                }
              },
              "tooLong": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "ics": {
                "type": "string"
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}