{
  "openapi": "3.1.0",
  "info": {
    "title": "LocalSky API read profile",
    "version": "2.4.0",
    "description": "Selected read endpoints for dashboards, automation, and AI connectors. Additional response fields are allowed. This profile does not grant read-only credentials: LocalSky bearer tokens can authorize writes outside this profile.",
    "license": {
      "name": "Apache-2.0",
      "identifier": "Apache-2.0"
    }
  },
  "servers": [
    {
      "url": "http://localhost:8090/api/v1",
      "description": "Replace with your reachable LocalSky instance, including /api/v1."
    }
  ],
  "security": [
    {
      "LocalSkyToken": []
    }
  ],
  "paths": {
    "/info": {
      "get": {
        "operationId": "getLocalSkyInfo",
        "summary": "Identify the server and API version",
        "description": "Identify the server and API version",
        "responses": {
          "200": {
            "description": "Successful read; inspect data freshness, nulls, and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Info"
                }
              }
            }
          },
          "default": {
            "description": "Request failure. Errors can also be generated by a proxy.",
            "headers": {
              "X-LocalSky-Request-Id": {
                "schema": {
                  "type": "string"
                },
                "description": "Request correlation ID when supplied by LocalSky."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/snapshot": {
      "get": {
        "operationId": "getCurrentWeather",
        "summary": "Read current weather with validity context",
        "description": "Read current weather with validity context",
        "responses": {
          "200": {
            "description": "Successful read; inspect data freshness, nulls, and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WeatherSnapshot"
                }
              }
            }
          },
          "default": {
            "description": "Request failure. Errors can also be generated by a proxy.",
            "headers": {
              "X-LocalSky-Request-Id": {
                "schema": {
                  "type": "string"
                },
                "description": "Request correlation ID when supplied by LocalSky."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/forecast/snapshot": {
      "get": {
        "operationId": "getSelectedForecast",
        "summary": "Read the selected daily and hourly forecast",
        "description": "Read the selected daily and hourly forecast",
        "responses": {
          "200": {
            "description": "Successful read; inspect data freshness, nulls, and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForecastSnapshot"
                }
              }
            }
          },
          "default": {
            "description": "Request failure. Errors can also be generated by a proxy.",
            "headers": {
              "X-LocalSky-Request-Id": {
                "schema": {
                  "type": "string"
                },
                "description": "Request correlation ID when supplied by LocalSky."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/forecast/window": {
      "get": {
        "operationId": "getForecastWindow",
        "summary": "Read a forecast interval",
        "description": "At most 48 hours between bounds. Each selected hourly timestamp starts an interval of one hour. Check age_s, complete, and required summary values. API 2.3.0+.",
        "responses": {
          "200": {
            "description": "Successful read; inspect data freshness, nulls, and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForecastWindow"
                }
              }
            }
          },
          "default": {
            "description": "Request failure. Errors can also be generated by a proxy.",
            "headers": {
              "X-LocalSky-Request-Id": {
                "schema": {
                  "type": "string"
                },
                "description": "Request correlation ID when supplied by LocalSky."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "track",
            "in": "query",
            "required": false,
            "description": "merged or a configured extra model ID.",
            "schema": {
              "type": "string",
              "default": "merged"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "description": "First UTC epoch, inclusive.",
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "description": "Last UTC epoch, inclusive.",
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          }
        ]
      }
    },
    "/forecast/tracks": {
      "get": {
        "operationId": "listForecastTracks",
        "summary": "List configured extra forecast models",
        "description": "Returns track identity, age, serving state, and errors. Extra tracks do not drive irrigation. API 2.3.0+.",
        "responses": {
          "200": {
            "description": "Successful read; inspect data freshness, nulls, and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {},
                    "additionalProperties": true
                  }
                }
              }
            }
          },
          "default": {
            "description": "Request failure. Errors can also be generated by a proxy.",
            "headers": {
              "X-LocalSky-Request-Id": {
                "schema": {
                  "type": "string"
                },
                "description": "Request correlation ID when supplied by LocalSky."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/forecast/archive": {
      "get": {
        "operationId": "getForecastArchive",
        "summary": "Read recorded forecast issuances",
        "description": "Inclusive target-hour range up to 400 days. Keep forecasts separate from measured rain. This profile uses JSON. API 2.3.0+.",
        "responses": {
          "200": {
            "description": "Successful read; inspect data freshness, nulls, and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArchivePage"
                }
              }
            }
          },
          "default": {
            "description": "Request failure. Errors can also be generated by a proxy.",
            "headers": {
              "X-LocalSky-Request-Id": {
                "schema": {
                  "type": "string"
                },
                "description": "Request correlation ID when supplied by LocalSky."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "track",
            "in": "query",
            "required": false,
            "description": "merged or a configured extra model ID.",
            "schema": {
              "type": "string",
              "default": "merged"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "description": "First UTC epoch, inclusive.",
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "description": "Last UTC epoch, inclusive.",
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "lead_h",
            "in": "query",
            "required": false,
            "description": "Optional forecast lead hour.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 47
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum rows in this page.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 5000,
              "default": 1000
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Returned next_cursor; retain the other query parameters.",
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/irrigation/snapshot": {
      "get": {
        "operationId": "getIrrigationState",
        "summary": "Read zones, current decisions, and projected water plans",
        "description": "Read zones, current decisions, and projected water plans",
        "responses": {
          "200": {
            "description": "Successful read; inspect data freshness, nulls, and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IrrigationSnapshot"
                }
              }
            }
          },
          "default": {
            "description": "Request failure. Errors can also be generated by a proxy.",
            "headers": {
              "X-LocalSky-Request-Id": {
                "schema": {
                  "type": "string"
                },
                "description": "Request correlation ID when supplied by LocalSky."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/irrigation/history": {
      "get": {
        "operationId": "getWateringHistory",
        "summary": "Read recorded runs and daily decisions",
        "description": "Read recorded runs and daily decisions",
        "responses": {
          "200": {
            "description": "Successful read; inspect data freshness, nulls, and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HistoryWindow"
                }
              }
            }
          },
          "default": {
            "description": "Request failure. Errors can also be generated by a proxy.",
            "headers": {
              "X-LocalSky-Request-Id": {
                "schema": {
                  "type": "string"
                },
                "description": "Request correlation ID when supplied by LocalSky."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "Days of history; 0 requests all retained records.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 36500,
              "default": 30
            }
          }
        ]
      }
    },
    "/health": {
      "get": {
        "operationId": "getLocalSkyHealth",
        "summary": "Read liveness and available health detail",
        "description": "Anonymous callers receive reduced liveness. Send bearer credentials for full source diagnostics. A successful HTTP status alone does not establish healthy sources.",
        "responses": {
          "200": {
            "description": "Successful read; inspect data freshness, nulls, and coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true
                }
              }
            }
          },
          "default": {
            "description": "Request failure. Errors can also be generated by a proxy.",
            "headers": {
              "X-LocalSky-Request-Id": {
                "schema": {
                  "type": "string"
                },
                "description": "Request correlation ID when supplied by LocalSky."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "LocalSkyToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "API token from Settings > Account. Store as a secret. No native read-only scope."
      }
    },
    "schemas": {
      "Info": {
        "type": "object",
        "properties": {
          "service": {
            "type": "string"
          },
          "service_version": {
            "type": "string"
          },
          "build_revision": {
            "type": "string"
          },
          "api_version": {
            "type": "string"
          },
          "api_prefix": {
            "type": "string"
          },
          "license": {
            "type": "string"
          },
          "repository": {
            "type": "string"
          },
          "dry_run": {
            "type": "boolean"
          },
          "demo": {
            "type": "boolean"
          },
          "auth_required": {
            "type": "boolean"
          },
          "has_irrigation": {
            "type": "boolean"
          },
          "nerd_mode_default": {
            "type": "boolean"
          },
          "location_configured": {
            "type": "boolean"
          },
          "uuid": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "additionalProperties": true,
        "required": [
          "service",
          "service_version",
          "api_version",
          "api_prefix",
          "auth_required"
        ]
      },
      "CurrentWeatherSample": {
        "type": "object",
        "properties": {
          "value": {
            "type": "number"
          },
          "source_id": {
            "type": "string"
          },
          "observed_epoch": {
            "type": "integer",
            "format": "int64"
          },
          "max_age_s": {
            "type": "integer",
            "format": "int64"
          },
          "measured": {
            "type": "boolean"
          },
          "selection_reason": {
            "type": "string"
          }
        },
        "additionalProperties": true,
        "required": [
          "value",
          "source_id",
          "observed_epoch",
          "max_age_s",
          "measured",
          "selection_reason"
        ]
      },
      "WeatherSnapshot": {
        "type": "object",
        "properties": {
          "air_temp_f": {
            "type": "number"
          },
          "rh_pct": {
            "type": "number"
          },
          "wind_avg_mph": {
            "type": "number"
          },
          "wind_gust_mph": {
            "type": "number"
          },
          "rain_in_today": {
            "type": "number"
          },
          "rain_intensity_in_hr": {
            "type": "number"
          },
          "last_packet_epoch": {
            "type": "integer",
            "format": "int64"
          },
          "air_temp_live_epoch": {
            "type": "integer",
            "format": "int64"
          },
          "wind_live_epoch": {
            "type": "integer",
            "format": "int64"
          },
          "rh_live_epoch": {
            "type": "integer",
            "format": "int64"
          },
          "rain_live_epoch": {
            "type": "integer",
            "format": "int64"
          },
          "source_label": {
            "type": "string"
          },
          "has_live_station": {
            "type": "boolean"
          }
        },
        "additionalProperties": true,
        "description": "Selected legacy weather fields. Numeric values require their field-specific observation/validity context; zero alone is not evidence of a measurement. Additional fields are retained."
      },
      "WindowHour": {
        "type": "object",
        "properties": {
          "time_epoch": {
            "type": "integer",
            "format": "int64"
          },
          "temp_f": {
            "type": [
              "number",
              "null"
            ]
          },
          "precip_in": {
            "type": [
              "number",
              "null"
            ]
          },
          "precip_probability": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 100
          }
        },
        "additionalProperties": true,
        "required": [
          "time_epoch",
          "temp_f",
          "precip_in",
          "precip_probability"
        ]
      },
      "ForecastWindow": {
        "type": "object",
        "properties": {
          "track": {
            "type": "string"
          },
          "model": {
            "type": [
              "string",
              "null"
            ]
          },
          "provider_label": {
            "type": "string"
          },
          "fetched_at": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64"
          },
          "age_s": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64"
          },
          "from": {
            "type": "integer",
            "format": "int64"
          },
          "to": {
            "type": "integer",
            "format": "int64"
          },
          "complete": {
            "type": "boolean"
          },
          "hourly": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WindowHour"
            }
          },
          "hours": {
            "type": "integer",
            "minimum": 0
          },
          "expected_hours": {
            "type": "integer",
            "minimum": 0
          },
          "precipitation_hours": {
            "type": "integer",
            "minimum": 0
          },
          "probability_hours": {
            "type": "integer",
            "minimum": 0
          },
          "temperature_hours": {
            "type": "integer",
            "minimum": 0
          },
          "precip_max_in": {
            "type": [
              "number",
              "null"
            ]
          },
          "precip_sum_in": {
            "type": [
              "number",
              "null"
            ]
          },
          "temp_max_f": {
            "type": [
              "number",
              "null"
            ]
          },
          "temp_min_f": {
            "type": [
              "number",
              "null"
            ]
          },
          "pop_max_pct": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 100
          }
        },
        "additionalProperties": true,
        "description": "Inclusive hour-start query. Complete checks timestamps; also check required nullable measurements and age_s. Rain uses inches; temperature uses Fahrenheit.",
        "required": [
          "track",
          "model",
          "provider_label",
          "fetched_at",
          "age_s",
          "from",
          "to",
          "complete",
          "hourly",
          "hours",
          "expected_hours",
          "precipitation_hours",
          "probability_hours",
          "temperature_hours",
          "precip_max_in",
          "precip_sum_in",
          "temp_max_f",
          "temp_min_f",
          "pop_max_pct"
        ]
      },
      "ForecastSnapshot": {
        "type": "object",
        "properties": {
          "last_refresh_epoch": {
            "type": "integer",
            "format": "int64"
          },
          "source_reachable": {
            "type": "boolean"
          },
          "source_label": {
            "type": "string"
          },
          "source_is_backup": {
            "type": "boolean"
          },
          "timezone": {
            "type": "string"
          },
          "daily": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {},
              "additionalProperties": true
            }
          },
          "past_daily": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {},
              "additionalProperties": true
            }
          },
          "hourly": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WindowHour"
            }
          }
        },
        "additionalProperties": true,
        "description": "Selected forecast. Hourly objects contain additional fields beyond the read profile; daily entries are intentionally open objects. Use forecast/window for a compact typed interval.",
        "required": [
          "last_refresh_epoch",
          "source_reachable",
          "source_label",
          "source_is_backup",
          "timezone",
          "daily",
          "past_daily",
          "hourly"
        ]
      },
      "Zone": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "running": {
            "type": "boolean"
          },
          "running_known": {
            "type": "boolean"
          },
          "running_observed_epoch": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64"
          },
          "ledger_running": {
            "type": "boolean"
          },
          "controller_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "planned_run_seconds": {
            "type": "integer",
            "format": "int64"
          },
          "bucket_mm": {
            "type": [
              "number",
              "null"
            ]
          }
        },
        "additionalProperties": true,
        "description": "Read running together with running_known. A planned runtime is not delivered water.",
        "required": [
          "name",
          "slug",
          "running",
          "running_known"
        ]
      },
      "WaterPlanZone": {
        "type": "object",
        "properties": {
          "zone": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "reason": {
            "type": "string"
          },
          "reason_code": {
            "type": "string"
          },
          "water_need": {
            "type": "string"
          },
          "demand_source": {
            "type": "string"
          },
          "model": {
            "type": "string"
          },
          "planned_seconds": {
            "type": "integer",
            "format": "int64"
          },
          "depletion_mm": {
            "type": [
              "number",
              "null"
            ]
          },
          "trigger_mm": {
            "type": [
              "number",
              "null"
            ]
          },
          "capacity_mm": {
            "type": [
              "number",
              "null"
            ]
          },
          "demand_mm": {
            "type": "number"
          },
          "session_capped": {
            "type": "boolean"
          },
          "depletion_range_mm": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "number"
            },
            "minItems": 2,
            "maxItems": 2
          }
        },
        "additionalProperties": true,
        "required": [
          "zone",
          "name",
          "reason",
          "reason_code",
          "water_need",
          "demand_source",
          "model",
          "planned_seconds",
          "depletion_mm",
          "trigger_mm",
          "capacity_mm",
          "demand_mm",
          "session_capped",
          "depletion_range_mm"
        ]
      },
      "WaterPlanDay": {
        "type": "object",
        "properties": {
          "date_local": {
            "type": "string"
          },
          "day_offset": {
            "type": "integer",
            "format": "int64"
          },
          "time_epoch": {
            "type": "integer",
            "format": "int64"
          },
          "start_epoch": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64"
          },
          "finish_epoch": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64"
          },
          "forecast_rain_mm": {
            "type": [
              "number",
              "null"
            ]
          },
          "expected_rain_mm": {
            "type": [
              "number",
              "null"
            ]
          },
          "rain_probability_pct": {
            "type": [
              "integer",
              "null"
            ]
          },
          "evidence_complete": {
            "type": "boolean"
          },
          "zones": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WaterPlanZone"
            }
          }
        },
        "additionalProperties": true,
        "description": "Future scenario, not a dispatched command or a record of applied water.",
        "required": [
          "date_local",
          "day_offset",
          "time_epoch",
          "start_epoch",
          "finish_epoch",
          "forecast_rain_mm",
          "expected_rain_mm",
          "rain_probability_pct",
          "evidence_complete",
          "zones"
        ]
      },
      "IrrigationSnapshot": {
        "type": "object",
        "properties": {
          "last_refresh_epoch": {
            "type": "integer",
            "format": "int64"
          },
          "timezone": {
            "type": "string"
          },
          "restart_required": {
            "type": "boolean"
          },
          "restart_reasons": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "next_run_epoch": {
            "type": "integer",
            "format": "int64"
          },
          "next_run_state": {
            "type": "string",
            "enum": [
              "at",
              "no_water_planned",
              "no_legal_day",
              "no_sunrise",
              "no_location"
            ]
          },
          "zones": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Zone"
            }
          },
          "water_plan": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WaterPlanDay"
            }
          },
          "decision_trace": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          },
          "current_weather": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": {
              "$ref": "#/components/schemas/CurrentWeatherSample"
            }
          }
        },
        "additionalProperties": true,
        "description": "Selected fields from the full irrigation snapshot. Read observation ages independently of snapshot age.",
        "required": [
          "last_refresh_epoch",
          "zones"
        ]
      },
      "RunRecord": {
        "type": "object",
        "properties": {
          "session_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "zone": {
            "type": "string"
          },
          "start_epoch": {
            "type": "integer",
            "format": "int64"
          },
          "duration_s": {
            "type": "integer",
            "format": "int64"
          },
          "skip_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "source": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "controller_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "applied_mm": {
            "type": [
              "number",
              "null"
            ]
          },
          "volume_gal": {
            "type": [
              "number",
              "null"
            ]
          },
          "note": {
            "type": [
              "string",
              "null"
            ]
          },
          "cycle_index": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64"
          },
          "cycle_count": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64"
          }
        },
        "additionalProperties": true,
        "description": "Use session identity and union of valve-open intervals to avoid double-counting. Dry-run and skip records are not applied water.",
        "required": [
          "zone",
          "start_epoch",
          "duration_s",
          "skip_reason"
        ]
      },
      "DailyZone": {
        "type": "object",
        "properties": {
          "zone": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "reason_code": {
            "type": "string"
          },
          "reason": {
            "type": "string"
          },
          "water_need": {
            "type": "string"
          },
          "planned_seconds": {
            "type": "integer",
            "format": "int64"
          }
        },
        "additionalProperties": true,
        "required": [
          "zone",
          "name",
          "reason_code",
          "reason",
          "water_need",
          "planned_seconds"
        ]
      },
      "DailyDecision": {
        "type": "object",
        "properties": {
          "date_local": {
            "type": "string"
          },
          "epoch": {
            "type": "integer",
            "format": "int64"
          },
          "kind": {
            "type": "string"
          },
          "zones": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DailyZone"
            }
          }
        },
        "additionalProperties": true,
        "required": [
          "date_local",
          "epoch",
          "kind",
          "zones"
        ]
      },
      "HistoryWindow": {
        "type": "object",
        "properties": {
          "from_epoch": {
            "type": "integer",
            "format": "int64"
          },
          "to_epoch": {
            "type": "integer",
            "format": "int64"
          },
          "runs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RunRecord"
            }
          },
          "daily": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DailyDecision"
            }
          }
        },
        "additionalProperties": true,
        "required": [
          "from_epoch",
          "to_epoch",
          "runs",
          "daily"
        ]
      },
      "ArchiveRow": {
        "type": "object",
        "properties": {
          "track": {
            "type": "string"
          },
          "provider": {
            "type": "string"
          },
          "model": {
            "type": [
              "string",
              "null"
            ]
          },
          "target_epoch": {
            "type": "integer",
            "format": "int64"
          },
          "lead_h": {
            "type": "integer",
            "format": "int64"
          },
          "pop_pct": {
            "type": [
              "integer",
              "null"
            ]
          },
          "precip_in": {
            "type": [
              "number",
              "null"
            ]
          },
          "fetched_at": {
            "type": "integer",
            "format": "int64"
          }
        },
        "additionalProperties": true,
        "required": [
          "track",
          "provider",
          "model",
          "target_epoch",
          "lead_h",
          "pop_pct",
          "precip_in",
          "fetched_at"
        ]
      },
      "ArchivePage": {
        "type": "object",
        "properties": {
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ArchiveRow"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "additionalProperties": true,
        "required": [
          "rows",
          "next_cursor"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "diagnostic": {
            "type": "object",
            "properties": {},
            "additionalProperties": true
          },
          "request": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "method": {
                "type": "string"
              },
              "route": {
                "type": "string"
              }
            },
            "additionalProperties": true
          }
        },
        "additionalProperties": true,
        "description": "Error fields vary by endpoint. Preserve HTTP status and X-LocalSky-Request-Id. Diagnostic evidence is optional."
      }
    }
  }
}
