{
  "openapi": "3.1.0",
  "info": {
    "title": "Rain Check",
    "version": "1.0.0",
    "description": "Whether an Australian field-service job can be worked on a given day. Live forecast, daylight and public holidays, with the source and retrieval time on every answer. Verdicts come from planning thresholds, not safety limits."
  },
  "servers": [
    {
      "url": "https://rain-check-mu.vercel.app"
    }
  ],
  "paths": {
    "/v1/workability": {
      "get": {
        "operationId": "checkWorkability",
        "summary": "Can we work this job on these days?",
        "description": "Returns GO, MARGINAL or NO GO per day for a trade at a location, with the rain, wind, temperature and daylight behind each call. Weather and access are reported separately. The forecast runs 16 days; later dates come back in out_of_range with no data and must not be estimated.",
        "parameters": [
          {
            "name": "location",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Australian suburb, town or locality, for example \"Parramatta\". Resolves localities, not street addresses."
          },
          {
            "name": "latitude",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Use with longitude instead of location when you already hold coordinates."
          },
          {
            "name": "longitude",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Use with latitude instead of location."
          },
          {
            "name": "timezone",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "IANA zone for supplied coordinates, for example Australia/Brisbane."
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "NSW",
                "VIC",
                "QLD",
                "SA",
                "WA",
                "TAS",
                "NT",
                "ACT"
              ]
            },
            "description": "Australian state or territory code. Narrows an ambiguous place name and decides which public holidays apply."
          },
          {
            "name": "trade",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "roofing",
                "concreting",
                "exterior_painting",
                "excavation",
                "solar_install",
                "landscaping",
                "general_outdoor",
                "indoor"
              ]
            },
            "description": "What the crew is doing. Each trade stops for different conditions. Defaults to general_outdoor."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Start of the range as YYYY-MM-DD. Defaults to today at the site."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "End of the range as YYYY-MM-DD."
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Number of days from the start. Defaults to 7."
          },
          {
            "name": "dates",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Specific dates, comma separated, as YYYY-MM-DD."
          },
          {
            "name": "work_on_weekends",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Default false, so weekends come back as NO GO on access."
          },
          {
            "name": "work_on_holidays",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Default false."
          }
        ],
        "responses": {
          "200": {
            "description": "A verdict per day, with the numbers and thresholds behind it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be answered as asked. The body carries an error code, a plain message and a next_step saying what to do instead.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "502": {
            "description": "An upstream data source was unreachable. Retry; do not substitute a guess.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/v1/window": {
      "get": {
        "operationId": "nextWorkWindow",
        "summary": "When is the next clear run of days?",
        "description": "Finds the earliest run of consecutive workable days inside the 16-day forecast. If nothing qualifies it reports the longest clear run it did find.",
        "parameters": [
          {
            "name": "location",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Australian suburb, town or locality, for example \"Parramatta\". Resolves localities, not street addresses."
          },
          {
            "name": "latitude",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Use with longitude instead of location when you already hold coordinates."
          },
          {
            "name": "longitude",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Use with latitude instead of location."
          },
          {
            "name": "timezone",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "IANA zone for supplied coordinates, for example Australia/Brisbane."
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "NSW",
                "VIC",
                "QLD",
                "SA",
                "WA",
                "TAS",
                "NT",
                "ACT"
              ]
            },
            "description": "Australian state or territory code. Narrows an ambiguous place name and decides which public holidays apply."
          },
          {
            "name": "trade",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "roofing",
                "concreting",
                "exterior_painting",
                "excavation",
                "solar_install",
                "landscaping",
                "general_outdoor",
                "indoor"
              ]
            },
            "description": "What the crew is doing. Each trade stops for different conditions. Defaults to general_outdoor."
          },
          {
            "name": "days_needed",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Consecutive workable days required. Defaults to 1."
          },
          {
            "name": "search_days",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "How far ahead to look, up to 16."
          },
          {
            "name": "allow_marginal",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Count MARGINAL days as workable. Defaults to false."
          },
          {
            "name": "earliest_start",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Do not start before this date."
          }
        ],
        "responses": {
          "200": {
            "description": "The earliest qualifying window, or why there is not one.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be answered as asked. The body carries an error code, a plain message and a next_step saying what to do instead.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "502": {
            "description": "An upstream data source was unreachable. Retry; do not substitute a guess.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/v1/trades": {
      "get": {
        "operationId": "listTradeProfiles",
        "summary": "The thresholds behind every verdict",
        "description": "Every trade profile and the exact numbers used to judge a day. Call this to explain a verdict or before overriding thresholds. Makes no external request.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Trade profiles with their threshold bands.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be answered as asked. The body carries an error code, a plain message and a next_step saying what to do instead.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "502": {
            "description": "An upstream data source was unreachable. Retry; do not substitute a guess.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/v1/locations": {
      "get": {
        "operationId": "findLocation",
        "summary": "Resolve an Australian place name",
        "description": "Turns a suburb or town into coordinates, state and timezone. Ambiguous names, and Australia has a Richmond in five states, come back as a list rather than a guess.",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Suburb, town or locality name."
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "NSW",
                "VIC",
                "QLD",
                "SA",
                "WA",
                "TAS",
                "NT",
                "ACT"
              ]
            },
            "description": "Australian state or territory code. Narrows an ambiguous place name and decides which public holidays apply."
          }
        ],
        "responses": {
          "200": {
            "description": "The resolved place, or the candidates when it is ambiguous.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be answered as asked. The body carries an error code, a plain message and a next_step saying what to do instead.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "502": {
            "description": "An upstream data source was unreachable. Retry; do not substitute a guess.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/v1/holidays": {
      "get": {
        "operationId": "listPublicHolidays",
        "summary": "Australian public holidays",
        "description": "Public holidays for a state and year, with the official government page alongside. State level only: no regional or local show days. Verify against the official page before this touches pay rates.",
        "parameters": [
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "NSW",
                "VIC",
                "QLD",
                "SA",
                "WA",
                "TAS",
                "NT",
                "ACT"
              ]
            },
            "description": "Australian state or territory code. Narrows an ambiguous place name and decides which public holidays apply."
          },
          {
            "name": "year",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Defaults to the current year."
          }
        ],
        "responses": {
          "200": {
            "description": "Holidays, the data-quality note and the official page.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be answered as asked. The body carries an error code, a plain message and a next_step saying what to do instead.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "502": {
            "description": "An upstream data source was unreachable. Retry; do not substitute a guess.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/v1/business-days": {
      "get": {
        "operationId": "listBusinessDays",
        "summary": "Business days, skipping public holidays",
        "description": "The next N business days in a state from a start date, with what was skipped and why. Use for invoice due dates and follow-ups that should not land on a holiday.",
        "parameters": [
          {
            "name": "state",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "NSW",
                "VIC",
                "QLD",
                "SA",
                "WA",
                "TAS",
                "NT",
                "ACT"
              ]
            },
            "description": "Australian state or territory code. Narrows an ambiguous place name and decides which public holidays apply."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Start date. Defaults to today."
          },
          {
            "name": "count",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "How many business days to return, up to 120. Defaults to 10."
          },
          {
            "name": "include_saturday",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Count Saturdays as business days. Defaults to false."
          }
        ],
        "responses": {
          "200": {
            "description": "Business days and the skipped dates with reasons.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be answered as asked. The body carries an error code, a plain message and a next_step saying what to do instead.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "502": {
            "description": "An upstream data source was unreachable. Retry; do not substitute a guess.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  }
}