{
  "openapi": "3.1.1",
  "info": {
    "title": "Raindrop.Api | v1",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://raindrop.cssl.ca/"
    }
  ],
  "paths": {
    "/api/v1/capabilities": {
      "get": {
        "tags": [
          "Capabilities"
        ],
        "summary": "Get this caller's capabilities",
        "description": "Describes what the presented credential may do: which gated products it can reach and the plan each one costs, plus the request limits its tier is held to. Public — an anonymous caller gets the free-tier view rather than a 401, since a client needs the answer before anyone signs in. The answer is per-caller, so it is never cached.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CapabilitiesDto"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/stations/map/markers": {
      "get": {
        "tags": [
          "Stations"
        ],
        "summary": "Get every station's map geometry",
        "description": "A GeoJSON feature collection of every station on record, slimmed to what drawing a marker needs: the feature-level id and the point geometry. Feature properties are empty — station identity and filter criteria (name, network, present weather, declared series, current quality) come from GET /stations/map/details, whose default population is identical to this one. Takes no parameters and applies no activity filter, so the response is the same for every caller and can be fetched once and reused. Observations are GET /stations/readings, keyed by the station ids returned here.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeatureCollectionOfStationMarkerDto"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/stations/map/details": {
      "get": {
        "tags": [
          "Stations"
        ],
        "summary": "Get detail for every station on record",
        "description": "Station detail keyed by station id, for every station on record — the same population as GET /stations/map/markers, so a client can source marker identity and filter criteria from here. Each entry also carries `qualities`: the distinct base qualities that station's map series are currently reporting, worst first, from each series' latest reading in the last 12 hours. That is the one field describing what the series read rather than what they are, and it is here because it is a filter criterion — a client can hide stations by quality without fetching any observations. An empty array means the station reported none of those series in that span, which is not a fault. The optional window (e.g. window=7d or window=168h) restricts the set to stations that updated within that span of now, which is the population a staleness report can speak about; the previous always-on 7-day bound is now spelled window=7d.",
        "parameters": [
          {
            "name": "window",
            "in": "query",
            "description": "Optional recency window — a positive whole number of days or hours with a unit suffix (window=7d, window=168h). Only stations that updated within that span of now are returned. Omit for every station on record, the same population as /stations/map/markers.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "$ref": "#/components/schemas/StationDetailDto"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request"
          }
        }
      }
    },
    "/api/v1/stations/readings": {
      "get": {
        "tags": [
          "Stations"
        ],
        "summary": "Get station readings without station identity",
        "description": "Observations for a window, as {step, stations: {\"<stationId>\": {readings[]}}}. Nothing describing the station itself is repeated here — a client holds geometry from /stations/map/markers and identity from /stations/map/details, and keys this against them. `step` is a request, not a demand: the response reports the interval actually used, which is the finest one affordable for however many series the request resolved, always a whole multiple of the one asked for. A grid that is too fine is coarsened, never rejected. Stations with nothing in the window are omitted. The window is capped by the caller's tier: 7 days for anonymous and free callers, 30 days on the pro plan, uncapped for commercial (an API key or JWT plan:commercial). The window may not reach further back than that cap either.",
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "description": "Start of the UTC window to look for station activity in. Defaults to 12 hours before end.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "end",
            "in": "query",
            "description": "End of the UTC window. Defaults to current time.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "minLat",
            "in": "query",
            "description": "Minimum latitude of the viewport bounding box.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "float"
            }
          },
          {
            "name": "minLon",
            "in": "query",
            "description": "Minimum longitude of the viewport bounding box.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "float"
            }
          },
          {
            "name": "maxLat",
            "in": "query",
            "description": "Maximum latitude of the viewport bounding box.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "float"
            }
          },
          {
            "name": "maxLon",
            "in": "query",
            "description": "Maximum longitude of the viewport bounding box.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "float"
            }
          },
          {
            "name": "step",
            "in": "query",
            "description": "Optional resampling interval in minutes. When set, readings are returned on the fixed grid start, start+step, … ≤ end, plus end itself when the step does not divide the span — each cell is the latest reading at or before the grid position, carrying an 'age' field in seconds. Omit for a snapshot: the latest reading per series in the window.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "names",
            "in": "query",
            "description": "Optional standardized observation names to return, repeated (names=a&names=b) or comma-separated (names=a,b). Defaults to every map property. Asking for fewer buys proportionally more window or viewport under the cell budget.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StationReadingsResponseDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request"
          }
        }
      },
      "post": {
        "tags": [
          "Stations"
        ],
        "summary": "Get readings for named stations",
        "description": "Same response as GET /stations/readings, but the stations are named in the body rather than selected by bounding box and active window. Intended for a client keeping a pool of readings across viewport changes: it knows which stations it is missing, so it can ask for exactly those instead of re-fetching the overlap between the old viewport and the new one. Naming fewer stations resolves fewer series, so the returned step can be finer than the boxed form would give for the same window. An empty station list resolves nothing — the response is an empty stations object that still reports the resolved step.",
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "end",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "step",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "names",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StationReadingsRequestDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StationReadingsResponseDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request"
          }
        }
      }
    },
    "/api/v1/stations/{stationId}": {
      "get": {
        "tags": [
          "Stations"
        ],
        "summary": "Get detail for one station",
        "description": "The single-station form of /stations/map/details, answered by the same lookup so the two cannot disagree — including the `qualities` verdict. 404 where the id matches no station.",
        "parameters": [
          {
            "name": "stationId",
            "in": "path",
            "description": "The unique identifier (GUID) of the station.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StationDetailDto"
                }
              }
            }
          },
          "404": {
            "description": "Not Found"
          }
        }
      }
    },
    "/api/v1/alerts": {
      "get": {
        "tags": [
          "Alerts"
        ],
        "summary": "Get alerts",
        "description": "Retrieve alerts within a specified time period. If no time period is specified, all alerts will be returned.",
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "description": "The start date and time for the alert period.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "end",
            "in": "query",
            "description": "The end date and time for the alert period.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeatureCollectionOfAlertDto"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/alerts/zones": {
      "get": {
        "tags": [
          "Alerts"
        ],
        "summary": "Get alert zone geometry",
        "description": "Retrieve canonical CLC base-zone geometry for the given comma-separated zone codes (each alert area's clcCode). Unknown codes are omitted — fall back to the alert's raw polygons for those. Responses are immutable per geography package version and heavily cacheable (ETag + Cache-Control).",
        "parameters": [
          {
            "name": "codes",
            "in": "query",
            "description": "Comma-separated CLC zone codes, e.g. \"041310,041320\".",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeatureCollectionOfAlertZoneDto"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/products/{type}": {
      "get": {
        "tags": [
          "Products"
        ],
        "summary": "Get product file",
        "description": "Retrieves a raster product file (Cloud Optimized GeoTIFF) for the specified type, duration, and timestamp.",
        "parameters": [
          {
            "name": "type",
            "in": "path",
            "description": "The product type (e.g., 'mesh', 'lightning').",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "duration",
            "in": "query",
            "description": "The duration for the product (e.g., '1h', '24h', '10min').",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "timestamp",
            "in": "query",
            "description": "The UTC timestamp for the product data.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad Request"
          },
          "404": {
            "description": "Not Found"
          }
        }
      }
    },
    "/api/v1/products/{type}/exists": {
      "get": {
        "tags": [
          "Products"
        ],
        "summary": "Check product existence",
        "description": "Checks if a specific product file exists for the given type, duration, and timestamp.",
        "parameters": [
          {
            "name": "type",
            "in": "path",
            "description": "The product type (e.g., 'mesh', 'lightning').",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "duration",
            "in": "query",
            "description": "The duration for the product (e.g., '1h', '24h', '10min').",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "timestamp",
            "in": "query",
            "description": "The UTC timestamp for the product data.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad Request"
          }
        }
      }
    },
    "/api/v1/observations/series": {
      "post": {
        "tags": [
          "Observations"
        ],
        "summary": "Get observation series",
        "description": "Retrieves a time series of observations for a specific station and observation type within a given date range.",
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "description": "The start date and time for the observation series.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "end",
            "in": "query",
            "description": "The end date and time for the observation series.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "requestBody": {
          "description": "The query criteria for the observation type (e.g., Name, StationId).",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ObservationTypeQuery"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObservationSeriesDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request"
          },
          "404": {
            "description": "Not Found"
          }
        }
      }
    },
    "/api/v1/observations/units": {
      "get": {
        "tags": [
          "Observations"
        ],
        "summary": "Get canonical observation units",
        "description": "Returns the canonical unit each standardized observation's values are stored and served in (e.g. windSpeed10m is km/h). Static per deployment — fetch once and cache.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/historical/bulk": {
      "post": {
        "tags": [
          "Historical"
        ],
        "summary": "Get paginated historical observation series as CSV",
        "description": "Retrieves a cursor-paginated time series of observations as CSV. Supports single-station and all-station queries. Includes station coordinates. Bulk download is commercial-tier only: requires a Raindrop API key or a CSSL JWT with plan commercial. A free- or pro-plan JWT receives 403, never 401.\n\nRequires plan **commercial** or better (product `historical.bulk`).",
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "description": "Start of the time range (UTC).",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "end",
            "in": "query",
            "description": "End of the time range (UTC).",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "Opaque cursor for pagination.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "description": "Number of rows per page (default 200000, max 200000).",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "Historical observation filter.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaginatedRequestDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad Request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Forbidden"
          },
          "429": {
            "description": "Too Many Requests"
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "AlertAreaDto": {
        "required": [
          "description",
          "polygons"
        ],
        "type": "object",
        "properties": {
          "description": {
            "type": "string"
          },
          "kind": {
            "$ref": "#/components/schemas/AlertAreaKind"
          },
          "threatStatus": {
            "$ref": "#/components/schemas/ThreatAreaStatus"
          },
          "clcCode": {
            "type": [
              "null",
              "string"
            ]
          },
          "polygons": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/Coordinates"
              }
            }
          }
        }
      },
      "AlertAreaKind": {
        "enum": [
          "Coverage",
          "ThreatArea",
          "Unknown"
        ]
      },
      "AlertColourClass": {
        "enum": [
          "Yellow",
          "Orange",
          "Red",
          "Unknown"
        ]
      },
      "AlertConfidence": { },
      "AlertDto": {
        "required": [
          "id",
          "issuer",
          "alertHeadline",
          "alertDescription"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "issuer": {
            "type": "string"
          },
          "messageType": {
            "$ref": "#/components/schemas/AlertMessageType"
          },
          "effectiveTime": {
            "type": "string",
            "format": "date-time"
          },
          "expiryTime": {
            "type": "string",
            "format": "date-time"
          },
          "alertConfidence": {
            "$ref": "#/components/schemas/AlertConfidence"
          },
          "alertImpact": {
            "$ref": "#/components/schemas/AlertImpact"
          },
          "alertColour": {
            "$ref": "#/components/schemas/AlertColourClass"
          },
          "alertType": {
            "$ref": "#/components/schemas/AlertType"
          },
          "alertHeadline": {
            "type": "string"
          },
          "alertDescription": {
            "type": "string"
          },
          "status": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/AlertStatus"
              }
            ]
          },
          "sent": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "event": {
            "type": [
              "null",
              "string"
            ]
          },
          "previousIds": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            }
          },
          "eventEndTime": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "riskRanking": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "coverage": {
            "type": [
              "null",
              "string"
            ]
          },
          "designationCode": {
            "type": [
              "null",
              "string"
            ]
          },
          "storm": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/StormDto"
              }
            ]
          },
          "areas": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/AlertAreaDto"
            }
          }
        }
      },
      "AlertImpact": {
        "enum": [
          "Low",
          "Moderate",
          "High",
          "Extreme",
          "Unknown"
        ]
      },
      "AlertMessageType": {
        "enum": [
          "Alert",
          "Update",
          "Cancel",
          "Unknown"
        ]
      },
      "AlertStatus": {
        "enum": [
          "Active",
          "Superseded",
          "Ended",
          "Cancelled",
          "Unknown",
          null
        ]
      },
      "AlertType": {
        "enum": [
          "Statement",
          "Advisory",
          "Watch",
          "Warning",
          "Unknown"
        ]
      },
      "AlertZoneDto": {
        "required": [
          "clcCode",
          "nameEn",
          "nameFr"
        ],
        "type": "object",
        "properties": {
          "clcCode": {
            "type": "string"
          },
          "nameEn": {
            "type": "string"
          },
          "nameFr": {
            "type": "string"
          },
          "areaKm2": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "centroid": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/Coordinates"
              }
            ]
          }
        }
      },
      "BaseQualityCode": {
        "enum": [
          "Error",
          "Doubtful",
          "Inconsistent",
          "Instrumentation",
          "Good",
          "Unknown",
          "Suppressed",
          "Missing"
        ]
      },
      "CRSType": {
        "type": "integer"
      },
      "CapabilitiesDto": {
        "required": [
          "products",
          "limits"
        ],
        "type": "object",
        "properties": {
          "products": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/ProductAccessDto"
            }
          },
          "limits": {
            "type": "object",
            "additionalProperties": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "null",
                "integer",
                "string"
              ],
              "format": "int64"
            }
          }
        }
      },
      "Coordinates": {
        "required": [
          "lat",
          "lon"
        ],
        "type": "object",
        "properties": {
          "lat": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "float"
          },
          "lon": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "float"
          }
        }
      },
      "ErrorType": {
        "enum": [
          "None",
          "Missing",
          "ValueType",
          "Range",
          "Inert",
          "Change",
          "Decrease",
          "Increase",
          "Disagree",
          "GreaterThan",
          "LessThan",
          "Difference",
          "AverageInconsistent",
          "Unknown"
        ]
      },
      "FeatureCollectionOfAlertDto": {
        "type": "object",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/GeoJSONObjectType"
          },
          "features": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/FeatureOfIGeometryObjectAndAlertDto"
            }
          },
          "bbox": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "double"
            }
          },
          "crs": {
            "$ref": "#/components/schemas/ICRSObject"
          }
        }
      },
      "FeatureCollectionOfAlertZoneDto": {
        "type": "object",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/GeoJSONObjectType"
          },
          "features": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/FeatureOfIGeometryObjectAndAlertZoneDto"
            }
          },
          "bbox": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "double"
            }
          },
          "crs": {
            "$ref": "#/components/schemas/ICRSObject"
          }
        }
      },
      "FeatureCollectionOfStationMarkerDto": {
        "type": "object",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/GeoJSONObjectType"
          },
          "features": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/FeatureOfIGeometryObjectAndStationMarkerDto"
            }
          },
          "bbox": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "double"
            }
          },
          "crs": {
            "$ref": "#/components/schemas/ICRSObject"
          }
        }
      },
      "FeatureOfIGeometryObjectAndAlertDto": {
        "type": "object",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/GeoJSONObjectType"
          },
          "id": {
            "type": [
              "null",
              "string"
            ]
          },
          "geometry": {
            "$ref": "#/components/schemas/IGeometryObject"
          },
          "properties": {
            "$ref": "#/components/schemas/AlertDto"
          },
          "bbox": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "double"
            }
          },
          "crs": {
            "$ref": "#/components/schemas/ICRSObject"
          }
        }
      },
      "FeatureOfIGeometryObjectAndAlertZoneDto": {
        "type": "object",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/GeoJSONObjectType"
          },
          "id": {
            "type": [
              "null",
              "string"
            ]
          },
          "geometry": {
            "$ref": "#/components/schemas/IGeometryObject"
          },
          "properties": {
            "$ref": "#/components/schemas/AlertZoneDto"
          },
          "bbox": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "double"
            }
          },
          "crs": {
            "$ref": "#/components/schemas/ICRSObject"
          }
        }
      },
      "FeatureOfIGeometryObjectAndStationMarkerDto": {
        "type": "object",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/GeoJSONObjectType"
          },
          "id": {
            "type": [
              "null",
              "string"
            ]
          },
          "geometry": {
            "$ref": "#/components/schemas/IGeometryObject"
          },
          "properties": {
            "$ref": "#/components/schemas/StationMarkerDto"
          },
          "bbox": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "double"
            }
          },
          "crs": {
            "$ref": "#/components/schemas/ICRSObject"
          }
        }
      },
      "GeoJSONObjectType": {
        "enum": [
          "Point",
          "MultiPoint",
          "LineString",
          "MultiLineString",
          "Polygon",
          "MultiPolygon",
          "GeometryCollection",
          "Feature",
          "FeatureCollection"
        ]
      },
      "GroupedStandardizedObservationMapping": {
        "required": [
          "prettyName"
        ],
        "type": "object",
        "properties": {
          "prettyName": {
            "type": "string"
          },
          "order": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          }
        }
      },
      "ICRSObject": {
        "type": "object",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/CRSType"
          }
        }
      },
      "IGeometryObject": { },
      "ObservationDto": {
        "required": [
          "timestamp",
          "type",
          "typeId",
          "value",
          "quality"
        ],
        "type": "object",
        "properties": {
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "type": {
            "type": "string"
          },
          "typeId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "value": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "quality": {
            "$ref": "#/components/schemas/QualityReport"
          },
          "age": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          }
        }
      },
      "ObservationIntervalType": {
        "enum": [
          "Instantaneous",
          "Average",
          "Cumulative",
          "Max",
          "Min",
          "Median",
          "Unknown"
        ]
      },
      "ObservationRequestDto": {
        "type": "object",
        "properties": {
          "stationId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "name": {
            "type": [
              "null",
              "string"
            ]
          },
          "reportedUnit": {
            "type": [
              "null",
              "string"
            ]
          },
          "intervalType": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ObservationIntervalType"
              }
            ]
          },
          "intervalMinutes": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "calculated": {
            "type": [
              "null",
              "boolean"
            ]
          },
          "groupBucketName": {
            "type": [
              "null",
              "string"
            ]
          },
          "lowerValueBound": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "upperValueBound": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "qualityRange": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/QualityRange"
              }
            ]
          }
        }
      },
      "ObservationSeriesDto": {
        "required": [
          "stationId",
          "name",
          "prettyName",
          "reportedUnit",
          "intervalType",
          "intervalMinutes"
        ],
        "type": "object",
        "properties": {
          "stationId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "prettyName": {
            "type": "string"
          },
          "reportedUnit": {
            "type": "string"
          },
          "intervalType": {
            "$ref": "#/components/schemas/ObservationIntervalType"
          },
          "intervalMinutes": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "firstAppearance": {
            "type": "string",
            "format": "date-time"
          },
          "bucketMetadata": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": {
              "$ref": "#/components/schemas/GroupedStandardizedObservationMapping"
            }
          },
          "readings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ObservationSeriesItemDto"
            }
          }
        }
      },
      "ObservationSeriesItemDto": {
        "required": [
          "timestamp",
          "value",
          "quality",
          "calculated"
        ],
        "type": "object",
        "properties": {
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "value": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "quality": {
            "$ref": "#/components/schemas/QualityReport"
          },
          "calculated": {
            "type": "boolean"
          },
          "groupBucketName": {
            "type": "string"
          }
        }
      },
      "ObservationTypeDto": {
        "required": [
          "id",
          "name",
          "prettyName",
          "groupBucketName",
          "reportedUnit",
          "calculated",
          "intervalType",
          "intervalMinutes"
        ],
        "type": "object",
        "properties": {
          "id": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "name": {
            "type": "string"
          },
          "prettyName": {
            "type": "string"
          },
          "groupBucketName": {
            "type": "string"
          },
          "reportedUnit": {
            "type": "string"
          },
          "calculated": {
            "type": "boolean"
          },
          "intervalType": {
            "$ref": "#/components/schemas/ObservationIntervalType"
          },
          "intervalMinutes": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "firstAppearance": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ObservationTypeQuery": {
        "type": "object",
        "properties": {
          "stationId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "name": {
            "type": [
              "null",
              "string"
            ]
          },
          "reportedUnit": {
            "type": [
              "null",
              "string"
            ]
          },
          "intervalType": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ObservationIntervalType"
              }
            ]
          },
          "intervalMinutes": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "calculated": {
            "type": [
              "null",
              "boolean"
            ]
          },
          "groupBucketName": {
            "type": [
              "null",
              "string"
            ]
          },
          "stationIds": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string",
              "format": "uuid"
            }
          }
        }
      },
      "PaginatedRequestDto": {
        "required": [
          "stationId"
        ],
        "type": "object",
        "properties": {
          "stationId": {
            "type": "string",
            "format": "uuid"
          },
          "requests": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/ObservationRequestDto"
            }
          }
        }
      },
      "ProductAccessDto": {
        "required": [
          "allowed",
          "requires",
          "requiresStanding"
        ],
        "type": "object",
        "properties": {
          "allowed": {
            "type": "boolean"
          },
          "requires": {
            "type": "string"
          },
          "requiresStanding": {
            "type": "string"
          }
        }
      },
      "QualityRange": {
        "required": [
          "lowerBound",
          "upperBound"
        ],
        "type": "object",
        "properties": {
          "lowerBound": {
            "$ref": "#/components/schemas/QualityReport"
          },
          "upperBound": {
            "$ref": "#/components/schemas/QualityReport"
          }
        }
      },
      "QualityReport": {
        "type": "object",
        "properties": {
          "baseQuality": {
            "$ref": "#/components/schemas/BaseQualityCode"
          },
          "reasonQuality": {
            "$ref": "#/components/schemas/ErrorType"
          }
        }
      },
      "StationDetailDto": {
        "required": [
          "id",
          "network",
          "name",
          "stationType",
          "lat",
          "lon",
          "elevation"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "network": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "stationType": {
            "type": "string"
          },
          "presentWeather": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "lat": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "float"
          },
          "lon": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "float"
          },
          "coordinates": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "float"
            }
          },
          "elevation": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "float"
          },
          "updateTime": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "types": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ObservationTypeDto"
            }
          },
          "qualities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BaseQualityCode"
            }
          }
        }
      },
      "StationMarkerDto": {
        "required": [
          "id",
          "lat",
          "lon"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "lat": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "float"
          },
          "lon": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "float"
          }
        }
      },
      "StationReadingsDto": {
        "type": "object",
        "properties": {
          "readings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ObservationDto"
            }
          }
        }
      },
      "StationReadingsRequestDto": {
        "required": [
          "stationIds"
        ],
        "type": "object",
        "properties": {
          "stationIds": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string",
              "format": "uuid"
            }
          }
        }
      },
      "StationReadingsResponseDto": {
        "type": "object",
        "properties": {
          "step": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "stations": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/StationReadingsDto"
            }
          }
        }
      },
      "StormDto": {
        "type": "object",
        "properties": {
          "speedKmh": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "directionDegrees": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "point": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/Coordinates"
              }
            ]
          },
          "geometryType": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/StormGeometryType"
              }
            ]
          },
          "time": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "motionDescription": {
            "type": [
              "null",
              "string"
            ]
          },
          "positionDescription": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "StormGeometryType": {
        "enum": [
          "IsolatedCell",
          "Line",
          "Area",
          "Unknown",
          null
        ]
      },
      "ThreatAreaStatus": {
        "enum": [
          "None",
          "Issued",
          "Continued",
          "Ended",
          "Cancelled"
        ]
      }
    },
    "securitySchemes": {
      "Bearer": {
        "type": "http",
        "description": "API key or CSSL access JWT. Sent as 'Authorization: Bearer {credential}'. Browsers on *.cssl.ca may instead send the cssl_at cookie.",
        "scheme": "bearer"
      }
    }
  },
  "tags": [
    {
      "name": "Capabilities"
    },
    {
      "name": "Stations"
    },
    {
      "name": "Alerts"
    },
    {
      "name": "Products"
    },
    {
      "name": "Observations"
    },
    {
      "name": "Historical"
    }
  ]
}