openapi: 3.0.3
info:
  title: Meteo API
  description: >
    REST API for querying stored weather measurements by location, from the
    most recent measurement back to the oldest one on record. A background
    job periodically fetches current weather conditions from the Open-Meteo
    API and persists them, so this API serves as a queryable record of that
    data.
  version: 1.0.0
servers:
  - url: https://meteo-api.nicholasmeyers.be
    description: Meteo API server
tags:
  - name: meteo
    description: Retrieve stored weather measurements
paths:
  /meteo:
    get:
      tags:
        - meteo
      operationId: findMeteoInRange
      summary: List weather measurements in a time range
      description: >
        Returns the stored weather measurements within the given time range,
        ordered from most recent to oldest. Measurements are recorded roughly
        every 15 minutes, so the range itself determines how many results
        come back; it must not span more than 10 days.
      parameters:
        - $ref: "#/components/parameters/Latitude"
        - $ref: "#/components/parameters/Longitude"
        - name: from
          in: query
          required: true
          description: Only include measurements recorded at or after this timestamp (inclusive).
          schema:
            type: string
            format: date-time
          example: "2026-08-01T00:00:00+02:00"
        - name: to
          in: query
          required: true
          description: Only include measurements recorded at or before this timestamp (inclusive).
          schema:
            type: string
            format: date-time
          example: "2026-08-23T23:59:59+02:00"
      responses:
        "200":
          description: The matching weather measurements were found and returned.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/MeteoResponse"
        "400":
          description: >
            The request contains one or more invalid query parameters, or the
            span between 'from' and 'to' exceeds 10 days.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                status: 400
                message: "The range between 'from' and 'to' must not exceed 10 days."
  /meteo/latest:
    get:
      tags:
        - meteo
      operationId: findLatestMeteo
      summary: Get the most recent weather measurement
      description: Returns the single most recently recorded weather measurement.
      parameters:
        - $ref: "#/components/parameters/Latitude"
        - $ref: "#/components/parameters/Longitude"
      responses:
        "200":
          description: The most recent weather measurement was found and returned.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MeteoResponse"
        "404":
          description: No weather measurements have been recorded yet.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                status: 404
                message: "No weather measurements have been recorded yet."
components:
  parameters:
    Latitude:
      name: latitude
      in: query
      required: true
      description: Latitude of the location to retrieve weather measurements for, in decimal degrees.
      schema:
        type: number
        format: double
        minimum: -90
        maximum: 90
      example: 51.05
    Longitude:
      name: longitude
      in: query
      required: true
      description: Longitude of the location to retrieve weather measurements for, in decimal degrees.
      schema:
        type: number
        format: double
        minimum: -180
        maximum: 180
      example: 3.72
  schemas:
    MeteoResponse:
      type: object
      description: A single weather measurement recorded at a specific point in time.
      required:
        - time
        - temperature
        - temperature_unit
        - apparent_temperature
        - apparent_temperature_unit
        - precipitation
        - precipitation_unit
        - cloud_cover
        - cloud_cover_unit
        - wind_speed
        - wind_speed_unit
        - weather_code
        - weather_code_unit
        - weather_description
      properties:
        time:
          type: string
          format: date-time
          description: The date and time at which this measurement was recorded.
          example: "2026-08-23T14:00:00+02:00"
        temperature:
          type: number
          format: double
          description: The measured air temperature.
          example: 21.4
        temperature_unit:
          type: string
          description: The unit in which the temperature is expressed.
          example: "°C"
        apparent_temperature:
          type: number
          format: double
          description: The "feels like" temperature, accounting for wind and humidity.
          example: 20.8
        apparent_temperature_unit:
          type: string
          description: The unit in which the apparent temperature is expressed.
          example: "°C"
        precipitation:
          type: number
          format: double
          description: The amount of precipitation measured.
          example: 0.0
        precipitation_unit:
          type: string
          description: The unit in which precipitation is expressed.
          example: "mm"
        cloud_cover:
          type: number
          format: double
          description: The total cloud cover, as a percentage of sky covered.
          example: 40.0
        cloud_cover_unit:
          type: string
          description: The unit in which cloud cover is expressed.
          example: "%"
        wind_speed:
          type: number
          format: double
          description: The measured wind speed.
          example: 12.3
        wind_speed_unit:
          type: string
          description: The unit in which wind speed is expressed.
          example: "km/h"
        weather_code:
          type: integer
          format: int32
          description: The WMO weather interpretation code for this measurement.
          example: 1
        weather_code_unit:
          type: string
          description: The unit/scale the weather code belongs to.
          example: "wmo code"
        weather_description:
          type: string
          description: Human-readable description derived from the weather code.
          example: "Mainly clear"
    ErrorResponse:
      type: object
      description: Standard error response body.
      required:
        - status
        - message
      properties:
        status:
          type: integer
          format: int32
          description: The HTTP status code.
          example: 400
        message:
          type: string
          description: A human-readable explanation of what went wrong.
          example: "The range between 'from' and 'to' must not exceed 10 days."
