# SPDX-FileCopyrightText: NOI Techpark <digital@noi.bz.it>
#
# SPDX-License-Identifier: CC0-1.0

openapi: 3.0.1
info:
  title: Open Data Hub Timeseries / Mobility API
  description: >
    ## ⚠️ Notices

     - **Deprecated feature:** The **Events** data type is deprecated and scheduled for **removal in May 2027**. Data previously available here has been migrated to the [Content API](https://databrowser.opendatahub.com/dataset-overview/33923d9c-d2ce-4592-8cfe-1fa927cd5fb6)
     - **Deprecated feature:** The **station metadata history** endpoint is deprecated and scheduled for **removal in May 2027**
     - **Deprecated field:** The field `savailable` is deprecated and scheduled for **removal in May 2027**
     - **Domain change:** The `mobility.api.opendatahub.bz.it` domain will be dismissed soon. Use `mobility.api.opendatahub.com` exclusively.

    ## About this API

    This API exposes both historical and up to date time series data in a common format.

    [Datasets available on the Open Data Hub](https://opendatahub.com/datasets/)

    ## Data model

    Time series data are a series of **measurements** of a common **type**, measured by a **station**

    ### Station

    A station represents a location or device where measurements are taken.
     - `stype`: e.g. `ParkingStation`, `MeteoStation`
     - `sactive`: whether the station is still being updated. Filter for `sactive.eq.false` if you want up to date information
     - `scode`: an identifier unique for this station type
     - `sname`: full text name of the station
     - `scoordinate`: where is this station located
     - `sorigin`: who provided this data
     - `smetadata`: A JSON object with additional information, depending on the provider

     ### Type

    Every measurement has a type, e.g. `temperature` or `free` to indicate the number of available parking spaces
     - `tname`: unique identifier of the type `temperature`
     - `t...`: additional information about the type

     ### Measurement
      - `mvalidtime`: timestamp of the measurement
      - `mvalue`: the measured value. Number, string or json object
      - `mperiod`: update frequency of this timeseries in seconds. Depending on the dataset this might be an approximation

    ### Others
     - `pr...` provenance: technical information about the data collection
     - `p...` parent: Some stations have a parent station

    ### Representation

    You choose whether you want the response flattened as an array (`flat`) or as a hierarchical structure (`tree`).
    The data is the same, just structured differently.

    ## Additional Documentation
     - [Mobility Datasets](https://docs.opendatahub.com/en/latest/datasets.html#datasets-in-the-mobility-domain)
     - [Getting Started](https://docs.opendatahub.com/en/latest/howto/mobility/getstarted.html)
     - [General Howtos](https://docs.opendatahub.com/en/latest/howto.html)
     - [Source Code](https://github.com/noi-techpark/opendatahub-timeseries-api)


  termsOfService: https://docs.opendatahub.com/en/latest/licenses.html#apis-terms-of-service
  contact:
    name: Open Data Hub
    url: https://opendatahub.com
    email: help@opendatahub.com
  license:
    name: API License
    url: https://docs.opendatahub.com/en/latest/licenses.html
  version: V2
servers:
  - url: https://mobility.api.opendatahub.com
tags:
  - name: General
    description: Entry points to discover data
  - name: Timeseries
    description: Time series measurements at stations
  - name: Edges
    description: Edge data connecting two stations
  - name: Events
    description: "**Deprecated** — Events are slated for removal in May 2027"
paths:
  # V2 ----------------------------------------------------------------------------------------
  /v2/:
    get:
      tags:
        - General
      summary: List entry points to the Open Data Hub Timeseries
      security:
        - OAuth2: []
      parameters:
        - $ref: "#/components/parameters/origin"
      responses:
        200:
          description: Successful response
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    description:
                      type: string
                      nullable: true
                    self:
                      type: string
              example:
                - id: "flat,node"
                  description: "Retrieve stations, data types and measurements in a flattened form"
                  self: "https://mobility.api.opendatahub.com/v2/flat,node"
                - id: "tree,node"
                  description: "Retrieve stations, data types and measurements in a hierarchical form"
                  self: "https://mobility.api.opendatahub.com/v2/tree,node"
                - id: "flat,edge"
                  description: "Retrieve edges in a flattened form"
                  self: "https://mobility.api.opendatahub.com/v2/flat,edge"
                - id: "tree,edge"
                  description: "Retrieve edges in a hierarchical form"
                  self: "https://mobility.api.opendatahub.com/v2/tree,edge"
        401:
          description: Unauthorized
          content: {}
        403:
          description: Forbidden
          content: {}
        404:
          description: Not Found
          content: {}
  /v2/{representation}:
    get:
      tags:
        - Timeseries
      summary: List all station types
      security:
        - OAuth2: []
      parameters:
        - $ref: "#/components/parameters/representation"
        - $ref: "#/components/parameters/origin"
      responses:
        200:
          description: Successful response
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    description:
                      type: string
                      nullable: true
                    self.stations:
                      type: string
                    self.stations+datatypes:
                      type: string
                    self.stations+datatypes+measurements:
                      type: string
              example:
                - id: "ParkingStation"
                  description: null
                  "self.stations": "https://mobility.api.opendatahub.com/v2/flat/ParkingStation"
                  "self.stations+datatypes": "https://mobility.api.opendatahub.com/v2/flat/ParkingStation/*"
                  "self.stations+datatypes+measurements": "https://mobility.api.opendatahub.com/v2/flat/ParkingStation/*/latest"
                - id: "MeteoStation"
                  description: null
                  "self.stations": "https://mobility.api.opendatahub.com/v2/flat/MeteoStation"
                  "self.stations+datatypes": "https://mobility.api.opendatahub.com/v2/flat/MeteoStation/*"
                  "self.stations+datatypes+measurements": "https://mobility.api.opendatahub.com/v2/flat/MeteoStation/*/latest"
        401:
          description: Unauthorized
          content: {}
        403:
          description: Forbidden
          content: {}
        404:
          description: Not Found
          content: {}
  /v2/{representation},edge:
    get:
      tags:
        - Edges
      summary: List all edge types
      security:
        - OAuth2: []
      parameters:
        - $ref: "#/components/parameters/representationedge"
        - $ref: "#/components/parameters/origin"
      responses:
        200:
          description: Successful response
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    description:
                      type: string
                      nullable: true
                    self.edges:
                      type: string
              example:
                - id: "LinkStation"
                  description: null
                  "self.edges": "https://mobility.api.opendatahub.com/v2/flat,edge/LinkStation"
                - id: "TrafficStreetFactor"
                  description: null
                  "self.edges": "https://mobility.api.opendatahub.com/v2/flat,edge/TrafficStreetFactor"
        401:
          description: Unauthorized
          content: {}
        403:
          description: Forbidden
          content: {}
        404:
          description: Not Found
          content: {}
  /v2/{representation},event:
    get:
      tags:
        - Events
      deprecated: true
      summary: List all event origins
      description: "**Deprecated:** Events are scheduled for removal in May 2027."
      security:
        - OAuth2: []
      parameters:
        - $ref: "#/components/parameters/representationevent"
        - $ref: "#/components/parameters/origin"
      responses:
        200:
          description: Successful response
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
        401:
          description: Unauthorized
          content: {}
        403:
          description: Forbidden
          content: {}
        404:
          description: Not Found
          content: {}
  /v2/{representation}/{stationTypes}:
    get:
      tags:
        - Timeseries
      summary: Stations for given station type(s)
      security:
        - OAuth2: []
      parameters:
        - $ref: "#/components/parameters/representation"
        - $ref: "#/components/parameters/stationTypes"
        - $ref: "#/components/parameters/where"
        - $ref: "#/components/parameters/select"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/distinct"
        - $ref: "#/components/parameters/shownull"
        - $ref: "#/components/parameters/origin"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Response"
              examples:
                flat:
                  summary: Flat list of stations
                  value:
                    offset: 0
                    limit: 200
                    data:
                      - sactive: true
                        savailable: true
                        scode: "103"
                        scoordinate:
                          x: 11.355115
                          y: 46.497805
                          srid: 4326
                        smetadata:
                          capacity: 403
                          municipality: "Bolzano - Bozen"
                        sname: "P03 - Piazza Walther"
                        sorigin: "FAMAS"
                        stype: "ParkingStation"
                tree:
                  summary: Tree of stations grouped by type and code
                  value:
                    offset: 0
                    limit: 200
                    data:
                      ParkingStation:
                        stations:
                          "103":
                            sactive: true
                            savailable: true
                            scode: "103"
                            scoordinate:
                              x: 11.355115
                              y: 46.497805
                              srid: 4326
                            smetadata:
                              capacity: 403
                              municipality: "Bolzano - Bozen"
                            sname: "P03 - Piazza Walther"
                            sorigin: "FAMAS"
                            stype: "ParkingStation"
        401:
          description: Unauthorized
          content: {}
        403:
          description: Forbidden
          content: {}
        404:
          description: Not Found
          content: {}
  /v2/{representation},edge/{edgeTypes}:
    get:
      tags:
        - Edges
      summary: Edge details for given edge types
      description: Multiple edge types supported as comma-separated values. Response fields prefixed with `e` (edge), `sb` (start station) and `se` (end station).
      security:
        - OAuth2: []
      parameters:
        - $ref: "#/components/parameters/representationedge"
        - $ref: "#/components/parameters/edgeTypes"
        - $ref: "#/components/parameters/where"
        - $ref: "#/components/parameters/select"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/distinct"
        - $ref: "#/components/parameters/shownull"
        - $ref: "#/components/parameters/origin"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Response"
        401:
          description: Unauthorized
          content: {}
        403:
          description: Forbidden
          content: {}
        404:
          description: Not Found
          content: {}
  /v2/{representation},event/{eventorigins}:
    get:
      tags:
        - Events
      deprecated: true
      summary: Events for given origins
      description: "**Deprecated:** Events are scheduled for removal in May 2027. Multiple origins supported as comma-separated values. Response fields prefixed with `ev` (event), `evl` (location) and `pr` (provenance)."
      security:
        - OAuth2: []
      parameters:
        - $ref: "#/components/parameters/representationevent"
        - $ref: "#/components/parameters/eventorigins"
        - $ref: "#/components/parameters/where"
        - $ref: "#/components/parameters/select"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/distinct"
        - $ref: "#/components/parameters/shownull"
        - $ref: "#/components/parameters/origin"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Response"
        401:
          description: Unauthorized
          content: {}
        403:
          description: Forbidden
          content: {}
        404:
          description: Not Found
          content: {}
  /v2/{representation},event/{eventorigins}/latest:
    get:
      tags:
        - Events
      deprecated: true
      summary: Latest events per origin and series UUID
      description: "**Deprecated:** Events are scheduled for removal in May 2027. Multiple origins supported as comma-separated values. Response fields prefixed with `ev` (event), `evl` (location) and `pr` (provenance)."
      security:
        - OAuth2: []
      parameters:
        - $ref: "#/components/parameters/representationevent"
        - $ref: "#/components/parameters/eventorigins"
        - $ref: "#/components/parameters/where"
        - $ref: "#/components/parameters/select"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/distinct"
        - $ref: "#/components/parameters/shownull"
        - $ref: "#/components/parameters/origin"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Response"
        401:
          description: Unauthorized
          content: {}
        403:
          description: Forbidden
          content: {}
        404:
          description: Not Found
          content: {}
  /v2/{representation},event/{eventorigins}/{timepoint}:
    get:
      tags:
        - Events
      deprecated: true
      summary: Events active at a given point in time
      description: "**Deprecated:** Events are scheduled for removal in May 2027. Multiple origins supported as comma-separated values. Response fields prefixed with `ev` (event), `evl` (location) and `pr` (provenance)."
      security:
        - OAuth2: []
      parameters:
        - $ref: "#/components/parameters/representationevent"
        - $ref: "#/components/parameters/eventorigins"
        - $ref: "#/components/parameters/timepoint"
        - $ref: "#/components/parameters/where"
        - $ref: "#/components/parameters/select"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/distinct"
        - $ref: "#/components/parameters/shownull"
        - $ref: "#/components/parameters/origin"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Response"
        401:
          description: Unauthorized
          content: {}
        403:
          description: Forbidden
          content: {}
        404:
          description: Not Found
          content: {}
  /v2/{representation},event/{eventorigins}/{from}/{to}:
    get:
      tags:
        - Events
      deprecated: true
      summary: Events active within a time interval
      description: "**Deprecated:** Events are scheduled for removal in May 2027. Multiple origins supported as comma-separated values. Response fields prefixed with `ev` (event), `evl` (location) and `pr` (provenance)."
      security:
        - OAuth2: []
      parameters:
        - $ref: "#/components/parameters/representationevent"
        - $ref: "#/components/parameters/eventorigins"
        - $ref: "#/components/parameters/from"
        - $ref: "#/components/parameters/to"
        - $ref: "#/components/parameters/where"
        - $ref: "#/components/parameters/select"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/distinct"
        - $ref: "#/components/parameters/shownull"
        - $ref: "#/components/parameters/origin"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Response"
        401:
          description: Unauthorized
          content: {}
        403:
          description: Forbidden
          content: {}
        404:
          description: Not Found
          content: {}
  /v2/{representation}/{stationTypes}/{dataTypes}:
    get:
      tags:
        - Timeseries
      security:
        - OAuth2: []
      summary: Stations with available data types
      parameters:
        - $ref: "#/components/parameters/representation"
        - $ref: "#/components/parameters/stationTypes"
        - $ref: "#/components/parameters/dataTypes"
        - $ref: "#/components/parameters/where"
        - $ref: "#/components/parameters/select"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/distinct"
        - $ref: "#/components/parameters/shownull"
        - $ref: "#/components/parameters/origin"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Response"
              examples:
                flat:
                  summary: Flat list of stations with their data types
                  value:
                    offset: 0
                    limit: 200
                    data:
                      - sactive: true
                        savailable: true
                        scode: "103"
                        scoordinate:
                          x: 11.355115
                          y: 46.497805
                          srid: 4326
                        smetadata:
                          capacity: 403
                          municipality: "Bolzano - Bozen"
                        sname: "P03 - Piazza Walther"
                        sorigin: "FAMAS"
                        stype: "ParkingStation"
                        tdescription: "free"
                        tmetadata: {}
                        tname: "free"
                        ttype: "Instantaneous"
                        tunit: ""
                tree:
                  summary: Tree of stations with nested data types
                  value:
                    offset: 0
                    limit: 200
                    data:
                      ParkingStation:
                        stations:
                          "103":
                            sactive: true
                            savailable: true
                            scode: "103"
                            scoordinate:
                              x: 11.355115
                              y: 46.497805
                              srid: 4326
                            smetadata:
                              capacity: 403
                              municipality: "Bolzano - Bozen"
                            sname: "P03 - Piazza Walther"
                            sorigin: "FAMAS"
                            stype: "ParkingStation"
                            sdatatypes:
                              free:
                                tdescription: "free"
                                tmetadata: {}
                                tname: "free"
                                ttype: "Instantaneous"
                                tunit: ""
        401:
          description: Unauthorized
          content: {}
        403:
          description: Forbidden
          content: {}
        404:
          description: Not Found
          content: {}
  /v2/{representation}/{stationTypes}/{dataTypes}/latest:
    get:
      tags:
        - Timeseries
      security:
        - OAuth2: []
      summary: Latest measurements for given station and data types
      parameters:
        - $ref: "#/components/parameters/representation"
        - $ref: "#/components/parameters/stationTypes"
        - $ref: "#/components/parameters/dataTypes"
        - $ref: "#/components/parameters/where"
        - $ref: "#/components/parameters/select"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/distinct"
        - $ref: "#/components/parameters/shownull"
        - $ref: "#/components/parameters/timezone"
        - $ref: "#/components/parameters/origin"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Response"
              examples:
                flat:
                  summary: Flat list of latest measurements
                  value:
                    offset: 0
                    limit: 200
                    data:
                      - _timestamp: "2026-04-24 10:25:00.000+0000"
                        mperiod: 300
                        mtransactiontime: "2020-12-07 10:12:32.580+0000"
                        mvalidtime: "2026-04-24 10:25:00.000+0000"
                        mvalue: 192
                        prlineage: "el-parking-free-slot-calculation"
                        prname: "el-parking-free-slot-calculation"
                        prversion: "f4f0f6386998f35cc657d2e34a7a791e9c454897"
                        sactive: true
                        savailable: true
                        scode: "103"
                        scoordinate:
                          x: 11.355115
                          y: 46.497805
                          srid: 4326
                        smetadata:
                          capacity: 403
                          municipality: "Bolzano - Bozen"
                        sname: "P03 - Piazza Walther"
                        sorigin: "FAMAS"
                        stype: "ParkingStation"
                        tdescription: "free"
                        tmetadata: {}
                        tname: "free"
                        ttype: "Instantaneous"
                        tunit: ""
                tree:
                  summary: Tree of latest measurements by station type, code, and data type
                  value:
                    offset: 0
                    limit: 200
                    data:
                      ParkingStation:
                        stations:
                          "103":
                            sactive: true
                            savailable: true
                            scode: "103"
                            scoordinate:
                              x: 11.355115
                              y: 46.497805
                              srid: 4326
                            smetadata:
                              capacity: 403
                              municipality: "Bolzano - Bozen"
                            sname: "P03 - Piazza Walther"
                            sorigin: "FAMAS"
                            stype: "ParkingStation"
                            sdatatypes:
                              free:
                                tdescription: "free"
                                tmetadata: {}
                                tname: "free"
                                ttype: "Instantaneous"
                                tunit: ""
                                tmeasurements:
                                  - mperiod: 300
                                    mprovenance:
                                      prlineage: "el-parking-free-slot-calculation"
                                      prname: "el-parking-free-slot-calculation"
                                      prversion: "f4f0f6386998f35cc657d2e34a7a791e9c454897"
                                    mtransactiontime: "2020-12-07 10:12:32.580+0000"
                                    mvalidtime: "2026-04-24 10:25:00.000+0000"
                                    mvalue: 192
        401:
          description: Unauthorized
          content: {}
        403:
          description: Forbidden
          content: {}
        404:
          description: Not Found
          content: {}
  /v2/{representation}/{stationTypes}/{dataTypes}/{from}/{to}:
    get:
      tags:
        - Timeseries
      summary: Historical measurements for given station and data types
      security:
        - OAuth2: []
      parameters:
        - $ref: "#/components/parameters/representation"
        - $ref: "#/components/parameters/stationTypes"
        - $ref: "#/components/parameters/dataTypes"
        - $ref: "#/components/parameters/from"
        - $ref: "#/components/parameters/to"
        - $ref: "#/components/parameters/where"
        - $ref: "#/components/parameters/select"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/distinct"
        - $ref: "#/components/parameters/shownull"
        - $ref: "#/components/parameters/timezone"
        - $ref: "#/components/parameters/origin"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Response"
              examples:
                flat:
                  summary: Flat list of historical measurements
                  value:
                    offset: 0
                    limit: 200
                    data:
                      - _timestamp: "2023-12-31 22:00:02.000+0000"
                        mperiod: 300
                        mtransactiontime: "2023-12-31 22:04:32.114+0000"
                        mvalidtime: "2023-12-31 22:00:02.000+0000"
                        mvalue: 109
                        prlineage: "NOI"
                        prname: "odh-mobility-el-parking-free-slot-calculation"
                        prversion: "c9f95b82331e2524b2921fb13cfadd1d75a59db2"
                        sactive: true
                        savailable: true
                        scode: "103"
                        scoordinate:
                          x: 11.355115
                          y: 46.497805
                          srid: 4326
                        smetadata:
                          capacity: 403
                          municipality: "Bolzano - Bozen"
                        sname: "P03 - Piazza Walther"
                        sorigin: "FAMAS"
                        stype: "ParkingStation"
                        tdescription: "free"
                        tmetadata: {}
                        tname: "free"
                        ttype: "Instantaneous"
                        tunit: ""
                      - _timestamp: "2023-12-31 22:05:03.000+0000"
                        mperiod: 300
                        mtransactiontime: "2023-12-31 22:09:33.714+0000"
                        mvalidtime: "2023-12-31 22:04:25.000+0000"
                        mvalue: 109
                        prlineage: "NOI"
                        prname: "odh-mobility-el-parking-free-slot-calculation"
                        prversion: "c9f95b82331e2524b2921fb13cfadd1d75a59db2"
                        sactive: true
                        savailable: true
                        scode: "103"
                        scoordinate:
                          x: 11.355115
                          y: 46.497805
                          srid: 4326
                        smetadata:
                          capacity: 403
                          municipality: "Bolzano - Bozen"
                        sname: "P03 - Piazza Walther"
                        sorigin: "FAMAS"
                        stype: "ParkingStation"
                        tdescription: "free"
                        tmetadata: {}
                        tname: "free"
                        ttype: "Instantaneous"
                        tunit: ""
                tree:
                  summary: Tree of historical measurements by station type, code, and data type
                  value:
                    offset: 0
                    limit: 200
                    data:
                      ParkingStation:
                        stations:
                          "103":
                            sactive: true
                            savailable: true
                            scode: "103"
                            scoordinate:
                              x: 11.355115
                              y: 46.497805
                              srid: 4326
                            smetadata:
                              capacity: 403
                              municipality: "Bolzano - Bozen"
                            sname: "P03 - Piazza Walther"
                            sorigin: "FAMAS"
                            stype: "ParkingStation"
                            sdatatypes:
                              free:
                                tdescription: "free"
                                tmetadata: {}
                                tname: "free"
                                ttype: "Instantaneous"
                                tunit: ""
                                tmeasurements:
                                  - mperiod: 300
                                    mprovenance:
                                      prlineage: "NOI"
                                      prname: "odh-mobility-el-parking-free-slot-calculation"
                                      prversion: "c9f95b82331e2524b2921fb13cfadd1d75a59db2"
                                    mtransactiontime: "2023-12-31 22:04:32.114+0000"
                                    mvalidtime: "2023-12-31 22:00:02.000+0000"
                                    mvalue: 109
                                  - mperiod: 300
                                    mprovenance:
                                      prlineage: "NOI"
                                      prname: "odh-mobility-el-parking-free-slot-calculation"
                                      prversion: "c9f95b82331e2524b2921fb13cfadd1d75a59db2"
                                    mtransactiontime: "2023-12-31 22:09:33.714+0000"
                                    mvalidtime: "2023-12-31 22:04:25.000+0000"
                                    mvalue: 109
        401:
          description: Unauthorized
          content: {}
        403:
          description: Forbidden
          content: {}
        404:
          description: Not Found
          content: {}
  /v2/{representation}/{stationTypes}/metadata/{from}/{to}:
    get:
      tags:
        - Timeseries
      deprecated: true
      summary: Metadata history for given station types
      description: "**Deprecated:** This endpoint is scheduled for removal in May 2027."
      security:
        - OAuth2: []
      parameters:
        - $ref: "#/components/parameters/representation"
        - $ref: "#/components/parameters/stationTypes"
        - $ref: "#/components/parameters/from"
        - $ref: "#/components/parameters/to"
        - $ref: "#/components/parameters/where"
        - $ref: "#/components/parameters/select"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/distinct"
        - $ref: "#/components/parameters/shownull"
        - $ref: "#/components/parameters/timezone"
        - $ref: "#/components/parameters/origin"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Response"
        401:
          description: Unauthorized
          content: {}
        403:
          description: Forbidden
          content: {}
        404:
          description: Not Found
          content: {}

components:
  parameters:
    # V2 PARAMETERS -----------------------------------------------------------------------------
    representation:
      name: representation
      in: path
      description: |
        Output structure: `flat` (array) or `tree` (hierarchical).
        Same as `flat,node`, `tree,node`.
        See **Representation** in the introduction.
      required: true
      schema:
        type: string
        default: flat
      example: flat
    representationedge:
      name: representation
      in: path
      description: |
        Output structure including type: `flat,edge` or `tree,edge`.
        See **Representation** in the introduction.
      required: true
      schema:
        type: string
        default: flat,edge
      example: flat,edge
    representationevent:
      name: representation
      in: path
      description: |
        Output structure including type: `flat,event` or `tree,event`.
        See **Representation** in the introduction.
      required: true
      schema:
        type: string
        default: flat,event
    stationTypes:
      name: stationTypes
      in: path
      description: Station types as comma-separated values. Use `*` for all.
      required: true
      schema:
        type: string
        default: "*"
      example: ParkingStation
    edgeTypes:
      name: edgeTypes
      in: path
      description: Edge types as comma-separated values. Use `*` for all.
      required: true
      schema:
        type: string
        default: "*"
    dataTypes:
      name: dataTypes
      in: path
      description: Data types as comma-separated values. Use `*` for all.
      required: true
      schema:
        type: string
        default: "*"
      example: free
    eventorigins:
      name: eventorigins
      in: path
      description: Event origins (source names) as comma-separated values. Use `*` for all.
      required: true
      schema:
        type: string
        default: "*"
    timepoint:
      name: timepoint
      in: path
      description: "Point in time. Format: `yyyy-MM-dd[T[HH][:mm][:ss][.SSS]][Z]` (e.g. `2024-01-15T10:30:00+0200`). If no zone/offset is given, UTC is assumed."
      required: true
      schema:
        type: string
    from:
      name: from
      in: path
      description: "Start of a half-open interval [from, to). Format: `yyyy-MM-dd[T[HH][:mm][:ss][.SSS]][Z]`. If no zone/offset is given, UTC is assumed."
      required: true
      schema:
        type: string
      example: "2024-01-01T00:00:00+0200"
    to:
      name: to
      in: path
      description: "End of a half-open interval [from, to). Format: `yyyy-MM-dd[T[HH][:mm][:ss][.SSS]][Z]`. If no zone/offset is given, UTC is assumed."
      required: true
      schema:
        type: string
      example: "2024-01-02T00:00:00+0200"
    where:
      name: where
      in: query
      description: |
        Filter results with one or more conditions in the form `field.operator.value`.
        Multiple conditions separated by commas are interpreted as `and`.

        ### Operators
         -   `eq`: Equal
         -   `neq`: Not Equal
         -   `lt`: Less Than
         -   `gt`: Greater Than
         -   `lteq`: Less Than Or Equal
         -   `gteq`: Greater Than Or Equal
         -   `re`: Regular Expression
         -   `ire`: Insensitive Regular Expression
         -   `nre`: Negated Regular Expression
         -   `nire`: Negated case-insensitive Regular Expression
         -   `bbi`: Bounding box intersecting objects.  
             Syntax: left-x, left-y, right-x, right-y, SRID (optional, default 4326)  
             `coordinate.bbi.(11,46,12,47,4326)`  
         -   `bbc`: Bounding box containing objects. Same syntax as `bbi`.
         -   `dlt`: Within distance in meters from a point.  
             Syntax: distance, point-x, point-y, SRID (optional, default 4326)  
             e.g. `coordinate.dlt.(5000,11.2,46.7,4326)`
         -   `in`: Value found in list. Example: `name.in.(Peter,Patrick,Rudi)`
         -   `nin`: Value not found in list. Example: `name.nin.(Peter,Patrick,Rudi)`

        Numbers are auto-cast to numeric type.  

        Values matching the date/time format `yyyy-MM-dd[T[HH][:mm][:ss][.SSS]][Z]` are auto-cast to timestamps with the missing precision being set as `00:00:00`. Values without an explicit zone/offset are interpreted as UTC.  

        ### Logical operators
        - `,`: multiple conditions separeted by comma are interpreted as `and`
        - `and`: `and(cond,cond,...)`
        - `or`: `or(cond,cond,...)`

        nestable, e.g. `or(scode.eq."A",scode.eq."B")`

        ### Examples
        - `sactive.eq.true` only active stations
        - `scode.eq."200"` station with code "200" (quoted to force string match)
        - `sorigin.eq."Neogy"` stations from the Neogy data provider
        - `smetadata.city.eq."Bolzano"` drill into nested JSON metadata
        - `description.eq.null` field is not set
        - `mtransactiontime.gt.2024-01-01` records changed after Jan 1st, 2024 (UTC)

      schema:
        type: string
    select:
      name: select
      in: query
      description: |
        Comma-separated list of fields to include in the response.
        Field names must match exactly as they appear in the output, including nested JSON paths.
        Example: `sname,scode,smetadata.city.cap`
      schema:
        type: string
    limit:
      name: limit
      in: query
      description: Max number of results. Set to -1 to disable.
      schema:
        type: integer
        format: int64
        default: 200
    offset:
      name: offset
      in: query
      description: Pagination offset, used together with `limit`.
      schema:
        type: integer
        format: int64
        default: 0
    distinct:
      name: distinct
      in: query
      description: Remove duplicate entries.
      schema:
        type: boolean
        default: true
    shownull:
      name: shownull
      in: query
      description: Include JSON keys with null values in the response.
      schema:
        type: boolean
        default: false
    timezone:
      name: timezone
      in: query
      description: Timezone for response timestamps (java.time.ZoneId format).
      schema:
        type: string
        default: UTC
    origin:
      name: origin
      in: query
      description: Identify your application to us. Don't confuse with `sorigin`
      schema:
        type: string
        default: ""

  schemas:
    coordinate:
      description: |
        Coordinates: Latitude and longitude
        <br /><br />
        *Important: Coordinates cannot be accessed directly. For example, `coordinate.x` is not possible at the moment.*
      properties:
        x:
          type: number
        y:
          type: number
        srid:
          type: integer
          default: 4326
    provenance:
      description: |
        ```
        Prefix: pr
        ```
        Provenance: Which data collector inserted or updated this information?
      properties:
        prname:
          format: text
          type: string
          description: Name of the data collector, elaboration tool, or manual data manipulation
        prversion:
          format: text
          type: string
          description: Version of the data collector, elaboration tool, or manual data manipulation
          example: 2299032843ef73db1811d615be8d8061e7d76322 (<-- a git sha)
          nullable: true
        prlineage:
          format: text
          type: string
    measurement:
      description: |
        ```
        Prefix: m
        ```
        Measurements: Stations have sensors that measure a certain type of data. This is the outcome...
        <br /><br />
        *Important: Nested objects are not available when you use `flat` as representation, refer to them directly instead.*
      properties:
        mvalue:
          description: "The measured value: a number, a plain string, or a free-form JSON object"
          oneOf:
            - type: number
            - type: string
            - type: object
        mvalidtime:
          type: string
          format: date-time
          description: When has this value been measured?
        mtransactiontime:
          type: string
          format: date-time
          description: When has this value been written to the Open Data Hub?
        mperiod:
          type: integer
          description: Distance in seconds between two measurements
        mprovenance:
          $ref: "#/components/schemas/provenance"
    datatype:
      description: |
        ```
        Prefix: t
        ```
        Datatype: The data type of a measurement, for example temperature in °C.
        <br /><br />
        *Important: Nested objects are not available when you use `flat` as representation, refer to them directly instead.*
      properties:
        tname:
          type: string
        tunit:
          type: string
        ttype:
          type: string
        tdescription:
          type: string
          nullable: true
        tmetadata:
          type: object
        tmeasurements:
          type: array
          items:
            $ref: "#/components/schemas/measurement"
    parent:
      description: |
        ```
        Prefix: p
        ```
        Parent: The parent station of a measurement station, for example the echarging station that contains echarging plugs
      properties:
        pname:
          type: string
          description: Name of the parent station
        ptype:
          type: string
          description: Type of the parent station
        pcode:
          type: string
          description: Unique ID of this parent station (inside this `ptype`)
        porigin:
          type: string
          description: Where did we get this station information from?
        pactive:
          type: boolean
          description: Is this station still used? Has it had updates recently?
        pavailable:
          type: boolean
          description: Should this station be visible to API consumers? (Do not use this, it will be removed. Only available stations are visible)
          deprecated: true
        pcoordinate:
          $ref: "#/components/schemas/coordinate"
        pmetadata:
          type: object
          description: free-form JSON object
    station:
      description: |
        ```
        Prefix: s
        ```
        Station: A measurement station.
        <br /><br />
        *Important: Nested objects are not available when you use `flat` as representation, refer to them directly instead.*
      properties:
        sname:
          type: string
          description: Name of the station
        stype:
          type: string
          description: Type of the station
        scode:
          type: string
          description: Unique ID of this station (for this `stype`)
        sorigin:
          type: string
          description: Where did we get this station information from?
        sactive:
          type: boolean
          description: Is this station still used? Has it had updates recently?
        savailable:
          type: boolean
          description: This field is deprecated and will be removed in May 2027
          deprecated: true
        scoordinate:
          $ref: "#/components/schemas/coordinate"
        smetadata:
          type: object
          description: free-form JSON object
        sparent:
          $ref: "#/components/schemas/parent"
        sdatatypes:
          type: object
          description: "Keys: data type name (tname)"
          additionalProperties:
            $ref: "#/components/schemas/datatype"
    stationbegin:
      description: |
        ```
        Prefix: sb
        ```
        Stationbegin: The starting station that is connected to another station with an edge
      properties:
        sbname:
          type: string
          description: Name of the starting measurement station
        sbtype:
          type: string
          description: Type of the starting measurement station
        sbcode:
          type: string
          description: Unique ID of this measurement station (inside this `ptype`)
        sborigin:
          type: string
          description: Where did we get this station information from?
        sbactive:
          type: boolean
          description: Is this station still used? Has it had updates recently?
        sbavailable:
          type: boolean
          description: Should this station be visible to API consumers? (Do not use this, it will be removed. Only available stations are visible)
          deprecated: true
        sbcoordinate:
          $ref: "#/components/schemas/coordinate"
    stationend:
      description: |
        ```
        Prefix: se
        ```
        Stationend: The ending station that is connected to another station with an edge
      properties:
        sename:
          type: string
          description: Name of the ending measurement station
        setype:
          type: string
          description: Type of the ending measurement station
        secode:
          type: string
          description: Unique ID of this measurement station (inside this `ptype`)
        seorigin:
          type: string
          description: Where did we get this station information from?
        seactive:
          type: boolean
          description: Is this station still used? Has it had updates recently?
        seavailable:
          type: boolean
          description: Should this station be visible to API consumers? (Do not use this, it will be removed. Only available stations are visible)
          deprecated: true
        secoordinate:
          $ref: "#/components/schemas/coordinate"
    edge:
      description: |
        ```
        Prefix: e
        ```
        Edge: The edge that connects two stations.
        <br /><br />
        *Important: Nested objects are not available when you use `flat` as representation, refer to them directly instead.*
      properties:
        ename:
          type: string
          description: Name of the edge
        etype:
          type: string
          description: Type of the edge
        ecode:
          type: string
          description: Unique ID of this edge (inside this `etype`)
        eorigin:
          type: string
          description: Where did we get this edge information from?
        eactive:
          type: boolean
          description: Is this edge still used? Has it had updates recently?
        eavailable:
          type: boolean
          description: Should this edge be visible to API consumers? (Do not use this, it will be removed. Only available edges are visible)
          deprecated: true
        edirected:
          type: boolean
        egeometry:
          type: object
        ebegin:
          $ref: "#/components/schemas/stationbegin"
        eend:
          $ref: "#/components/schemas/stationend"
    location:
      description: |
        ```
        Prefix: evl
        ```
        Location: The location of a traffic event
      properties:
        evldescription:
          type: string
        evlgeometry:
          type: object
    event:
      description: |
        ```
        Prefix: ev
        ```
        Event: A traffic event.
        <br /><br />
        *Important: Nested objects are not available when you use `flat` as representation, refer to them directly instead.*
      properties:
        evcategory:
          type: string
        evseriesuuid:
          type: string
        evtransactiontime:
          type: string
        evdescription:
          type: string
        evstart:
          type: string
        evend:
          type: string
        evorigin:
          type: string
        evuuid:
          type: string
        evname:
          type: string
        evmetadata:
          type: string
        evlocation:
          $ref: "#/components/schemas/location"
        evprovenance:
          $ref: "#/components/schemas/provenance"
    measurement-flat:
      type: object
      properties:
        mvalue:
          description: "The measured value: a number, a plain string, or a free-form JSON object"
          oneOf:
            - type: number
            - type: string
            - type: object
        mvalidtime:
          type: string
          format: date-time
          description: When has this value been measured?
        mtransactiontime:
          type: string
          format: date-time
          description: When has this value been written to the Open Data Hub?
        mperiod:
          type: integer
          description: Distance in seconds between two measurements
    datatype-flat:
      type: object
      properties:
        tname:
          type: string
        tunit:
          type: string
        ttype:
          type: string
        tdescription:
          type: string
          nullable: true
        tmetadata:
          type: object
    station-flat:
      type: object
      properties:
        sname:
          type: string
        stype:
          type: string
        scode:
          type: string
        sorigin:
          type: string
        sactive:
          type: boolean
        savailable:
          type: boolean
          deprecated: true
          description: This field is deprecated and will be removed in May 2027
        scoordinate:
          $ref: "#/components/schemas/coordinate"
        smetadata:
          type: object
    FlatData:
      type: array
      items:
        description: "All entity fields (s*, p*, t*, m*, pr*) at the same level"
        allOf:
          - $ref: "#/components/schemas/station-flat"
          - $ref: "#/components/schemas/parent"
          - $ref: "#/components/schemas/datatype-flat"
          - $ref: "#/components/schemas/measurement-flat"
          - $ref: "#/components/schemas/provenance"
          - type: object
            properties:
              _timestamp:
                type: string
                format: date-time
    TreeData:
      type: object
      description: "Keys: station type (stype)"
      additionalProperties:
        type: object
        properties:
          stations:
            type: object
            description: "Keys: station code (scode)"
            additionalProperties:
              $ref: "#/components/schemas/station"
    Response:
      type: object
      properties:
        offset:
          type: integer
        limit:
          type: integer
        data:
          oneOf:
            - $ref: "#/components/schemas/FlatData"
            - $ref: "#/components/schemas/TreeData"
  securitySchemes:
    OAuth2:
      type: oauth2
      description: |-
        This API uses OAuth2 with either 'Authorization Code' (for frontends) or 'Client Credentials' (for machine-to-machine) flows.

        - Authorization Code: use `client_id = opendatahub-swagger`, leave client_secret empty
        - Client Credentials: use the client_id and client_secret provided by the Open Data Hub team

      flows:
        authorizationCode:
          authorizationUrl: https://auth.opendatahub.com/auth/realms/noi/protocol/openid-connect/auth
          tokenUrl: https://auth.opendatahub.com/auth/realms/noi/protocol/openid-connect/token
        clientCredentials:
          tokenUrl: https://auth.opendatahub.com/auth/realms/noi/protocol/openid-connect/token
