{
  "openapi": "3.0.3",
  "info": {
    "title": "Waylay Broker",
    "version": "2.18.0",
    "description": "Data is ingested into the platform by the Waylay Broker."
  },
  "servers": [
    {
      "url": "https://api.waylay.io",
      "description": "Waylay enterprise gateway"
    }
  ],
  "externalDocs": {
    "description": "Waylay Broker API documentation",
    "url": "https://docs.waylay.io/#/api/broker/"
  },
  "tags": [
    {
      "name": "Events",
      "description": "Events are the messages the broker processes and forwards to\n- The [Message Cache](#tag/Messages) which keeps (by default) the last 100 messages per resource.\n- The [Waylay Rule Engine](/openapi/html/engine.openapi.html) which triggers tasks that are\n  subscribed to the resources data stream.\n- The [Time Series Database](#tag/Series) (scalar measurements only)",
      "externalDocs": {
        "description": "Waylay Documentation",
        "url": "https://docs.waylay.io/#/api/broker/?id=data-ingestion-api"
      }
    },
    {
      "name": "Messages",
      "description": "Broker events can be stored as Messages in a message cache that contains (typically) the last \n100 messages for a resource.",
      "externalDocs": {
        "description": "Waylay Documentation",
        "url": "https://docs.waylay.io/#/api/broker/?id=message-retrieval"
      }
    },
    {
      "name": "Series",
      "description": "The top-level attributes of Broker events can be stored in a time series database.",
      "externalDocs": {
        "description": "Waylay Documentation",
        "url": "https://docs.waylay.io/#/api/broker/?id=time-series-data-retrieval"
      }
    },
    {
      "name": "About"
    }
  ],
  "paths": {
    "/data/v1/": {
      "get": {
        "summary": "Get Service Status",
        "operationId": "get_about",
        "tags": [
          "About"
        ],
        "description": "Get the status and version of the service.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/VersionResponse"
          }
        },
        "security": [
          {
            "waylayApiKeySecret": []
          }
        ]
      }
    },
    "/data/v1/events": {
      "post": {
        "summary": "Post Events",
        "operationId": "postSeries",
        "description": "Pushes events to broker.",
        "tags": [
          "Events"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Forward"
          },
          {
            "$ref": "#/components/parameters/Store"
          },
          {
            "$ref": "#/components/parameters/TTL"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/ResourceEvent"
                  },
                  {
                    "$ref": "#/components/schemas/ResourceEvents"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/PublishEventResponse"
          },
          "400": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        },
        "security": [
          {
            "waylayApiKeySecret": []
          }
        ]
      }
    },
    "/data/v1/events/{resourceId}": {
      "post": {
        "summary": "Post Events For Resource",
        "operationId": "postSeriesForResource",
        "description": "Pushes events for a given resource to broker.",
        "tags": [
          "Events"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          },
          {
            "$ref": "#/components/parameters/ResourceForward"
          },
          {
            "$ref": "#/components/parameters/Store"
          },
          {
            "$ref": "#/components/parameters/TTL"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/Event"
                  },
                  {
                    "$ref": "#/components/schemas/Events"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/PublishResourceEventResponse"
          },
          "400": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        },
        "security": [
          {
            "waylayApiKeySecret": []
          }
        ]
      },
      "get": {
        "summary": "Stream Events For Resource",
        "operationId": "streamEvents",
        "description": "Opens a data stream for the _Events_ of the given _Resource_.",
        "tags": [
          "Events"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          }
        ],
        "responses": {
          "200": {
            "description": "Event Stream",
            "content": {
              "application/x-ndjson": {
                "schema": {
                  "$ref": "#/components/schemas/TimestampedResourceEvent"
                }
              },
              "text/event-stream": {
                "schema": {
                  "$ref": "#/components/schemas/TimestampedResourceEvent"
                }
              }
            }
          },
          "406": {
            "$ref": "#/components/responses/InvalidContentTypeResponse"
          }
        },
        "security": [
          {
            "waylayApiKeySecret": []
          }
        ]
      }
    },
    "/data/v1/messages/{resourceId}": {
      "get": {
        "summary": "Retrieve Messages For Resource",
        "operationId": "getLatestMessages",
        "description": "Retrieves the last n messages for a resource.",
        "tags": [
          "Messages"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TimestampedEvent"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "waylayApiKeySecret": []
          }
        ]
      },
      "delete": {
        "summary": "Remove Messages For Resource",
        "operationId": "deleteMessages",
        "description": "Removes all messages associated with a resource.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          }
        ],
        "tags": [
          "Messages"
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/MessageSuccessResponse"
          }
        },
        "security": [
          {
            "waylayApiKeySecret": []
          }
        ]
      }
    },
    "/data/v1/messages/{resourceId}/current": {
      "get": {
        "summary": "Retrieve Latest Message",
        "operationId": "getLatestDocument",
        "description": "Retrieves the latest (i.e. most recent) message for a resource.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          }
        ],
        "tags": [
          "Messages"
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimestampedEvent"
                }
              }
            }
          },
          "404": {
            "description": "No Message Received Yet",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "waylayApiKeySecret": []
          }
        ]
      }
    },
    "/data/v1/messages/query": {
      "post": {
        "summary": "Query Messages",
        "operationId": "queryMessages",
        "description": "Executes an ad-hoc messages query.",
        "tags": [
          "Messages"
        ],
        "externalDocs": {
          "description": "Querying messages for multiple resources",
          "url": "https://docs.waylay.io/#/api/broker/?id=querying-messages-for-multiple-resources"
        },
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MessageQuery"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/MessageQueryResponse"
          },
          "400": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        },
        "security": [
          {
            "waylayApiKeySecret": []
          }
        ]
      }
    },
    "/data/v1/series/{resourceId}": {
      "get": {
        "summary": "Get Series Overview",
        "operationId": "getSeries",
        "description": "Lists the existing timeseries for the given resource.",
        "tags": [
          "Series"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          },
          {
            "$ref": "#/components/parameters/ReturnIngestionTimestamp"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "x-classname": "MetricSummary",
                    "properties": {
                      "name": {
                        "$ref": "#/components/schemas/MetricId"
                      },
                      "latest": {
                        "type": "object",
                        "x-classname": "LatestValue",
                        "properties": {
                          "timestamp": {
                            "$ref": "#/components/schemas/UnixEpochMillis"
                          },
                          "value": {
                            "$ref": "#/components/schemas/ScalarData"
                          }
                        },
                        "required": [
                          "timestamp"
                        ]
                      }
                    },
                    "required": [
                      "name"
                    ]
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "waylayApiKeySecret": []
          }
        ]
      },
      "delete": {
        "summary": "Delete Series",
        "operationId": "deleteSeries",
        "description": "Removes all timeseries associated with a resource.",
        "tags": [
          "Series"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/Until"
          },
          {
            "$ref": "#/components/parameters/MetricsToDelete"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/MessageSuccessResponse"
          },
          "400": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        },
        "security": [
          {
            "waylayApiKeySecret": []
          }
        ]
      }
    },
    "/data/v1/series/{resourceId}/{metric}": {
      "get": {
        "summary": "Query Series",
        "operationId": "getMetricSeries",
        "description": "Queries a single timeseries.\nDepending on the `grouping` query parameter, data will be aggregated (if `grouping` is specified) or not.\nIf data will be aggregated, you must specify one (through `aggregate` parameter) or more (through `aggregates`\nparameter) aggregation function(s).Optional order parameter applies sorting order to the result.",
        "externalDocs": {
          "description": "Getting time series data",
          "url": "https://docs.waylay.io/#/api/broker/?id=getting-time-series-data"
        },
        "tags": [
          "Series"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          },
          {
            "$ref": "#/components/parameters/Metric"
          },
          {
            "$ref": "#/components/parameters/SeriesQueryFrom"
          },
          {
            "$ref": "#/components/parameters/SeriesQueryUntil"
          },
          {
            "$ref": "#/components/parameters/Aggregate"
          },
          {
            "$ref": "#/components/parameters/Aggregates"
          },
          {
            "$ref": "#/components/parameters/Grouping"
          },
          {
            "$ref": "#/components/parameters/Order"
          },
          {
            "$ref": "#/components/parameters/ReturnIngestionTimestamp"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimeseriesJsonResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        },
        "security": [
          {
            "waylayApiKeySecret": []
          }
        ]
      }
    },
    "/data/v1/series/{resourceId}/{metric}/latest": {
      "get": {
        "summary": "Get Latest Value For A Series",
        "operationId": "getLastMetric",
        "description": "Retrieves the latest value of a time series.",
        "tags": [
          "Series"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          },
          {
            "$ref": "#/components/parameters/Metric"
          },
          {
            "$ref": "#/components/parameters/ReturnIngestionTimestamp"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LatestMeasurement"
                }
              }
            }
          },
          "404": {
            "description": "No Data Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "waylayApiKeySecret": []
          }
        ]
      }
    },
    "/data/v1/series/{resourceId}/{metric}/last": {
      "get": {
        "summary": "Get Last Unaggregated Values For A Series",
        "operationId": "getLastDatapointsForMetric",
        "description": "Query the time series storage for the latest n datapoints for a particular metric from a resource.",
        "tags": [
          "Series"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          },
          {
            "$ref": "#/components/parameters/Metric"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/SeriesLastUntil"
          },
          {
            "$ref": "#/components/parameters/ReturnIngestionTimestamp"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimeseriesJsonResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        },
        "security": [
          {
            "waylayApiKeySecret": []
          }
        ]
      }
    },
    "/data/v1/series/{resourceId}/{metric}/raw": {
      "get": {
        "summary": "Get Unaggregated Values For A Series",
        "operationId": "getDatapointsForMetricRaw",
        "description": "Retrieves the raw, unaggregated values for a series.\n\nWhen a request with content type `application/hal+json` leads to more datapoints in the requested interval\nthan the `limit` parameter allows, then the response contains a HAL `_links.next` url that resolves to a \nnext batch of datapoints.",
        "tags": [
          "Series"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          },
          {
            "$ref": "#/components/parameters/Metric"
          },
          {
            "$ref": "#/components/parameters/SeriesQueryFrom"
          },
          {
            "$ref": "#/components/parameters/SeriesQueryUntil"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Order"
          },
          {
            "$ref": "#/components/parameters/ReturnIngestionTimestamp"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimeseriesJsonResult"
                }
              },
              "application/hal+json": {
                "schema": {
                  "type": "object",
                  "x-classname": "RawDatapointsResponse",
                  "properties": {
                    "_links": {
                      "type": "object",
                      "x-classname": "RawDatapointsLinks",
                      "properties": {
                        "next": {
                          "$ref": "#/components/schemas/HalLink"
                        }
                      }
                    },
                    "query": {
                      "$ref": "#/components/schemas/SeriesQueryResponse"
                    },
                    "series": {
                      "type": "array",
                      "description": "Array of timestamp-value tuples",
                      "items": {
                        "$ref": "#/components/schemas/SeriesKeyValue"
                      }
                    }
                  },
                  "required": [
                    "query",
                    "series"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        },
        "security": [
          {
            "waylayApiKeySecret": []
          }
        ]
      }
    },
    "/data/v1/series/query": {
      "post": {
        "summary": "Query Series Data",
        "operationId": "queryTimeSeries",
        "description": "Executes an ad-hoc timeseries query.",
        "tags": [
          "Series"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/SeriesQueryRequest"
                  },
                  {
                    "$ref": "#/components/schemas/SeriesQueryWithoutAggregatesRequest"
                  },
                  {
                    "$ref": "#/components/schemas/MultipleSeriesQueryRequest"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "x-classname": "TimeseriesQueryResponse",
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/TimeseriesJsonResult"
                    },
                    {
                      "$ref": "#/components/schemas/MultipleTimeseriesJsonResult"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        },
        "security": [
          {
            "waylayApiKeySecret": []
          }
        ]
      }
    },
    "/data/v1/{resourceId}": {
      "delete": {
        "summary": "Remove Data",
        "operationId": "remove",
        "description": "Removes all data for a resource.",
        "tags": [
          "Events"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/Until"
          },
          {
            "$ref": "#/components/parameters/OnlyTimeseries"
          },
          {
            "$ref": "#/components/parameters/MetricsToDelete"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/MessageSuccessResponse"
          },
          "400": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        },
        "security": [
          {
            "waylayApiKeySecret": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "VersionResponse": {
        "type": "object",
        "required": [
          "version",
          "name"
        ],
        "properties": {
          "version": {
            "type": "string",
            "example": "2.10.4"
          },
          "name": {
            "type": "string",
            "example": "waylay-broker"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "PublishEventResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "content": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TimestampedResourceEvent"
              },
              {
                "$ref": "#/components/schemas/TimestampedResourceEvents"
              },
              {
                "title": "Empty",
                "type": "object",
                "description": "Marks that multiple events where published",
                "enum": [
                  {}
                ]
              }
            ]
          }
        }
      },
      "PublishResourceEventResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "content": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TimestampedEvent"
              },
              {
                "title": "Empty",
                "type": "object",
                "description": "Marks that multiple events where published",
                "enum": [
                  {}
                ]
              }
            ]
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          }
        },
        "required": [
          "error"
        ]
      },
      "ResourceId": {
        "type": "string",
        "title": "Resource Id",
        "description": "Primary identifier of a _Resource_",
        "example": "d3d823f5-f214-4de8-7c0-f2c8c4db5ee1"
      },
      "MetricId": {
        "type": "string",
        "title": "Metric Id",
        "description": "Key that identifies a single timeseries for a given _Resource_.\nCorresponds with the top-level keys of _Message Events_ \nthat are processed by the broker for that _Resource_.",
        "example": "temperature"
      },
      "Event": {
        "type": "object",
        "description": "Measurement object with optional event timestamp.",
        "properties": {
          "timestamp": {
            "description": "Event timestamp, if not specified, the _processing timestamp_\nof the broker will added as `timestamp` attribute.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/UnixEpochMillis"
              },
              {
                "$ref": "#/components/schemas/ISO8601Timestamp"
              }
            ]
          }
        },
        "additionalProperties": {
          "$ref": "#/components/schemas/Measurements"
        }
      },
      "Events": {
        "description": "Array of measurement objects with optional event timestamp.",
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/Event"
        }
      },
      "TimestampedEvent": {
        "type": "object",
        "description": "Measurement object with timestamp",
        "properties": {
          "timestamp": {
            "description": "Event timestamp",
            "allOf": [
              {
                "$ref": "#/components/schemas/UnixEpochMillis"
              }
            ]
          }
        },
        "additionalProperties": {
          "$ref": "#/components/schemas/Measurements"
        },
        "required": [
          "timestamp"
        ]
      },
      "ResourceEvent": {
        "type": "object",
        "description": "Measurement object with resource identifier and optional timestamp.",
        "example": {
          "resource": "resource-1",
          "temperature": 23.5
        },
        "properties": {
          "resource": {
            "$ref": "#/components/schemas/ResourceId"
          },
          "timestamp": {
            "description": "Event timestamp, if not specified, the _processing timestamp_\nof the broker will added as `timestamp` attribute.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/UnixEpochMillis"
              },
              {
                "$ref": "#/components/schemas/ISO8601Timestamp"
              }
            ]
          }
        },
        "additionalProperties": {
          "$ref": "#/components/schemas/Measurements"
        },
        "required": [
          "resource"
        ]
      },
      "ResourceEvents": {
        "description": "Array of measurement objects with resource identifier and optional timestamp.",
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/ResourceEvent"
        }
      },
      "TimestampedResourceEvent": {
        "type": "object",
        "description": "Measurement object with resource identifier and timestamp.",
        "properties": {
          "resource": {
            "$ref": "#/components/schemas/ResourceId"
          },
          "timestamp": {
            "description": "Event timestamp",
            "allOf": [
              {
                "$ref": "#/components/schemas/UnixEpochMillis"
              }
            ]
          }
        },
        "additionalProperties": {
          "$ref": "#/components/schemas/Measurements"
        },
        "required": [
          "resource",
          "timestamp"
        ]
      },
      "TimestampedResourceEvents": {
        "description": "Array of measurement objects with resource identifier and timestamp.",
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/TimestampedResourceEvent"
        }
      },
      "Measurements": {
        "title": "Measurements",
        "description": "Values in an _Event_ payload.\nNote that only _scalar_ data is stored in the timeseries, while\nArrays and objects are only stored in the _Message Cache_.",
        "oneOf": [
          {
            "$ref": "#/components/schemas/ScalarData"
          },
          {
            "$ref": "#/components/schemas/ObjectData"
          }
        ]
      },
      "ObjectData": {
        "title": "Object Data",
        "description": "Event data stored only in the _Message Cache_.",
        "example": {
          "timestamp": 1729869037000,
          "temperature": 23
        },
        "oneOf": [
          {
            "title": "Object",
            "type": "object"
          },
          {
            "title": "Array",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Measurements"
            }
          }
        ]
      },
      "ScalarData": {
        "title": "Scalar Data",
        "description": "Event data stored in both the _Message Cache_ and _Time Series Database_.\nKeys of these measurements become a _Metric_ for the resource.",
        "nullable": true,
        "oneOf": [
          {
            "title": "Number",
            "type": "number"
          },
          {
            "title": "String",
            "type": "string"
          },
          {
            "title": "Boolean",
            "type": "boolean"
          }
        ]
      },
      "TTLDuration": {
        "title": "TTL Duration",
        "description": "Specifies the duration of a TTL interval.",
        "oneOf": [
          {
            "$ref": "#/components/schemas/DurationSeconds"
          },
          {
            "$ref": "#/components/schemas/DurationWithUnit"
          },
          {
            "$ref": "#/components/schemas/ISO8601Duration"
          }
        ]
      },
      "DurationSeconds": {
        "type": "integer",
        "title": "Duration Seconds",
        "minimum": 0,
        "description": "Number of seconds of a time interval.",
        "example": 3600
      },
      "DurationWithUnit": {
        "type": "string",
        "pattern": "^\\d+[wdhms]$",
        "title": "Duration With Unit",
        "description": "Time interval with duration unit.",
        "example": "52w"
      },
      "UnixEpochMillis": {
        "type": "integer",
        "title": "Unix Epoch Milliseconds",
        "description": "Timestamp expressed as milliseconds since 00:00:00 UTC on 1 January 1970, \nnot counting leap seconds.",
        "example": 1663269720694
      },
      "ISO8601Duration": {
        "type": "string",
        "title": "ISO8601 duration",
        "description": "A [ISO8601 Duration](https://en.wikipedia.org/wiki/ISO_8601#Durations)\nwith day (`D`), hour (`H`), minute (`M`) and second (`S`) specifiers.",
        "pattern": "^P(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+(\\.\\d+)?S)?)?",
        "example": "PT3H2M6.213S"
      },
      "ISO8601Timestamp": {
        "title": "ISO8601 timestamp",
        "type": "string",
        "format": "date-time",
        "example": "2011-09-06T12:03:27.845Z"
      },
      "MessageQuery": {
        "type": "object",
        "title": "Message query",
        "properties": {
          "resources": {
            "description": "The list of resources to retrieve the messages for",
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/ResourceId"
            }
          },
          "limit": {
            "description": "The number of messages per resource to retrieve",
            "type": "integer",
            "minimum": 1
          },
          "from": {
            "description": "The lower bound of the time range to retrieve message from",
            "anyOf": [
              {
                "$ref": "#/components/schemas/UnixEpochMillis"
              },
              {
                "$ref": "#/components/schemas/ISO8601Timestamp"
              }
            ]
          },
          "until": {
            "description": "The upper bound of the time range to retrieve message from",
            "anyOf": [
              {
                "$ref": "#/components/schemas/UnixEpochMillis"
              },
              {
                "$ref": "#/components/schemas/ISO8601Timestamp"
              }
            ]
          },
          "window": {
            "description": "A duration expression. Will be evaluated vs `from`, `until` or the query execution date to get the actual time range",
            "anyOf": [
              {
                "$ref": "#/components/schemas/DurationWithUnit"
              },
              {
                "$ref": "#/components/schemas/ISO8601Timestamp"
              }
            ]
          }
        },
        "required": [
          "resources",
          "limit"
        ]
      },
      "MessageQueryResult": {
        "type": "object",
        "title": "Message query result",
        "properties": {
          "query": {
            "$ref": "#/components/schemas/MessageQuery"
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "x-classname": "MessageQueryResultItem",
              "properties": {
                "resource": {
                  "$ref": "#/components/schemas/ResourceId"
                },
                "messages": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TimestampedEvent"
                  }
                }
              }
            }
          }
        }
      },
      "Aggregate": {
        "title": "Aggregation function",
        "externalDocs": {
          "description": "Possible functions",
          "url": "https://docs.waylay.io/#/api/broker/?id=aggregates"
        },
        "type": "string",
        "enum": [
          "min",
          "max",
          "mean",
          "median",
          "sum",
          "count",
          "count-non-numeric",
          "count-numeric",
          "first",
          "last",
          "std",
          "diff"
        ],
        "example": "mean"
      },
      "Grouping": {
        "title": "Time grouping period",
        "externalDocs": {
          "description": "Possible groupings",
          "url": "https://docs.waylay.io/#/api/broker/?id=grouping"
        },
        "anyOf": [
          {
            "type": "string",
            "title": "auto",
            "enum": [
              "auto"
            ]
          },
          {
            "$ref": "#/components/schemas/DurationWithUnit"
          },
          {
            "$ref": "#/components/schemas/ISO8601Duration"
          }
        ]
      },
      "SeriesQueryResponse": {
        "title": "Timeseries query summary",
        "type": "object",
        "properties": {
          "from": {
            "$ref": "#/components/schemas/UnixEpochMillis"
          },
          "until": {
            "$ref": "#/components/schemas/UnixEpochMillis"
          },
          "metric": {
            "$ref": "#/components/schemas/MetricId"
          },
          "aggregates": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Aggregate"
            }
          },
          "grouping": {
            "$ref": "#/components/schemas/Grouping"
          },
          "resources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ResourceId"
            }
          },
          "filter": {
            "$ref": "#/components/schemas/TimeseriesFilter"
          },
          "limit": {
            "type": "integer",
            "minimum": 1
          }
        },
        "required": [
          "metric",
          "grouping",
          "resources"
        ]
      },
      "LatestMeasurement": {
        "type": "object",
        "description": "The latest measurement of a series.",
        "example": {
          "temperature": [
            13.6
          ],
          "timestamp": 1663269720694
        },
        "properties": {
          "timestamp": {
            "$ref": "#/components/schemas/UnixEpochMillis"
          }
        },
        "additionalProperties": {
          "description": "The latest value (in a singleton array), keyed by the metric name.",
          "type": "array",
          "items": {
            "$ref": "#/components/schemas/Measurements"
          },
          "maxItems": 1
        }
      },
      "TimeseriesFilterOperator": {
        "type": "object",
        "properties": {
          "operator": {
            "type": "string",
            "enum": [
              "gt",
              "gte",
              "lt",
              "lte",
              "eq",
              "ne",
              "between"
            ]
          }
        },
        "required": [
          "operator"
        ]
      },
      "TimeseriesFilterValueBounds": {
        "type": "object",
        "properties": {
          "lowerBound": {
            "type": "number"
          },
          "upperBound": {
            "type": "number"
          }
        },
        "required": [
          "lowerBound",
          "upperBound"
        ]
      },
      "TimeseriesFilterValueExact": {
        "type": "object",
        "properties": {
          "value": {
            "oneOf": [
              {
                "type": "number"
              },
              {
                "type": "string"
              }
            ]
          }
        },
        "required": [
          "value"
        ]
      },
      "TimeseriesFilterValue": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/TimeseriesFilterValueExact"
          },
          {
            "$ref": "#/components/schemas/TimeseriesFilterValueBounds"
          }
        ]
      },
      "TimeseriesFilter": {
        "title": "Timeseries filter",
        "description": "Filter that will be applied to datapoints *before* aggregation is performed.",
        "allOf": [
          {
            "$ref": "#/components/schemas/TimeseriesFilterOperator"
          },
          {
            "$ref": "#/components/schemas/TimeseriesFilterValue"
          }
        ]
      },
      "Order": {
        "title": "sort order",
        "description": "the order in which the data is returned",
        "type": "string",
        "default": "ascending",
        "enum": [
          "ascending",
          "descending"
        ]
      },
      "ReturnIngestionTimestamp": {
        "title": "return metric ingestion timestamp from time series database",
        "type": "boolean",
        "default": false
      },
      "SeriesQueryRequest": {
        "title": "Timeseries query request object",
        "type": "object",
        "properties": {
          "from": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/UnixEpochMillis"
              },
              {
                "$ref": "#/components/schemas/ISO8601Timestamp"
              }
            ]
          },
          "until": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/UnixEpochMillis"
              },
              {
                "$ref": "#/components/schemas/ISO8601Timestamp"
              }
            ]
          },
          "window": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DurationWithUnit"
              },
              {
                "$ref": "#/components/schemas/ISO8601Duration"
              }
            ]
          },
          "metric": {
            "$ref": "#/components/schemas/MetricId"
          },
          "aggregates": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/Aggregate"
            }
          },
          "grouping": {
            "$ref": "#/components/schemas/Grouping"
          },
          "resources": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/ResourceId"
            }
          },
          "maxResults": {
            "type": "integer",
            "minimum": 0
          },
          "filter": {
            "$ref": "#/components/schemas/TimeseriesFilter"
          },
          "order": {
            "$ref": "#/components/schemas/Order"
          },
          "returnIngestionTimestamp": {
            "$ref": "#/components/schemas/ReturnIngestionTimestamp"
          }
        },
        "required": [
          "metric",
          "aggregates",
          "resources"
        ]
      },
      "SeriesQueryWithoutAggregatesRequest": {
        "title": "Timeseries query request object without aggregates",
        "type": "object",
        "properties": {
          "from": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/UnixEpochMillis"
              },
              {
                "$ref": "#/components/schemas/ISO8601Timestamp"
              }
            ]
          },
          "until": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/UnixEpochMillis"
              },
              {
                "$ref": "#/components/schemas/ISO8601Timestamp"
              }
            ]
          },
          "window": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DurationWithUnit"
              },
              {
                "$ref": "#/components/schemas/ISO8601Duration"
              }
            ]
          },
          "metric": {
            "$ref": "#/components/schemas/MetricId"
          },
          "aggregates": {
            "type": "array",
            "minItems": 0,
            "maxItems": 0
          },
          "resources": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1,
            "items": {
              "$ref": "#/components/schemas/ResourceId"
            }
          },
          "maxResults": {
            "type": "integer",
            "minimum": 0
          },
          "filter": {
            "$ref": "#/components/schemas/TimeseriesFilter"
          },
          "order": {
            "$ref": "#/components/schemas/Order"
          },
          "returnIngestionTimestamp": {
            "$ref": "#/components/schemas/ReturnIngestionTimestamp"
          }
        },
        "required": [
          "metric",
          "resources"
        ]
      },
      "MultipleSeriesQueryRequest": {
        "title": "Array of Timeseries query requests",
        "type": "array",
        "minItems": 1,
        "items": {
          "x-classname": "SeriesQueryItem",
          "oneOf": [
            {
              "$ref": "#/components/schemas/SeriesQueryRequest"
            },
            {
              "$ref": "#/components/schemas/SeriesQueryWithoutAggregatesRequest"
            }
          ]
        }
      },
      "SeriesKeyValue": {
        "title": "Timestamp-Value pair",
        "type": "array",
        "description": "This is a timestamp-value pair. The first item MUST be an integer (unix epoch in milliseconds).\nThe second item is the value, which is a scalar value or `null`.",
        "items": {
          "x-classname": "SeriesValue",
          "nullable": true,
          "oneOf": [
            {
              "$ref": "#/components/schemas/UnixEpochMillis"
            },
            {
              "$ref": "#/components/schemas/ScalarData"
            }
          ]
        },
        "minItems": 2,
        "maxItems": 2
      },
      "TimeseriesJsonResult": {
        "title": "Timeseries response",
        "type": "object",
        "properties": {
          "query": {
            "$ref": "#/components/schemas/SeriesQueryResponse"
          },
          "series": {
            "type": "array",
            "description": "Array of timestamp-value tuples",
            "items": {
              "$ref": "#/components/schemas/SeriesKeyValue"
            }
          }
        },
        "required": [
          "query",
          "series"
        ]
      },
      "MultipleTimeseriesJsonResult": {
        "title": "Multiple Timeseries responses",
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/TimeseriesJsonResult"
        }
      },
      "HalLink": {
        "title": "Hal Link",
        "type": "object",
        "properties": {
          "href": {
            "type": "string",
            "format": "url",
            "example": "/series/test1/a/raw?from=1663269720694&until=1665833921682&order=ascending"
          },
          "name": {
            "type": "string",
            "example": "Next series"
          }
        },
        "required": [
          "href",
          "name"
        ]
      }
    },
    "responses": {
      "DefaultSuccessResponse": {
        "description": "Successful Response",
        "content": {
          "application/json": {
            "schema": {
              "type": "object"
            }
          }
        }
      },
      "MessageSuccessResponse": {
        "description": "Successful Response",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "x-classname": "MessageSuccessResult",
              "properties": {
                "message": {
                  "type": "string"
                }
              },
              "required": [
                "message"
              ]
            }
          }
        }
      },
      "VersionResponse": {
        "description": "Successful Response",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/VersionResponse"
            }
          }
        }
      },
      "PublishEventResponse": {
        "description": "Event(s) Published",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/PublishEventResponse"
            }
          }
        }
      },
      "PublishResourceEventResponse": {
        "description": "Event(s) Published",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/PublishResourceEventResponse"
            }
          }
        }
      },
      "ErrorResponse": {
        "description": "Error Response",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "InvalidContentTypeResponse": {
        "description": "Requested Content Type Not Acceptable",
        "content": {
          "default": {
            "example": "{\n   \"error\": \"Not acceptable. You requested [text/html] but we only support [text/event-stream, application/x-ndjson]\"\n}",
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "MessageQueryResponse": {
        "description": "Successful Query Result",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/MessageQueryResult"
            }
          }
        }
      }
    },
    "parameters": {
      "ResourceId": {
        "name": "resourceId",
        "in": "path",
        "required": true,
        "description": "Uniquely identifies a resource.",
        "schema": {
          "$ref": "#/components/schemas/ResourceId"
        }
      },
      "Metric": {
        "name": "metric",
        "in": "path",
        "required": true,
        "description": "Identifies the times series metric.",
        "schema": {
          "$ref": "#/components/schemas/MetricId"
        }
      },
      "Forward": {
        "name": "forward",
        "in": "query",
        "description": "If payload is a single event, _Events_ are forwarded to the [Rule Engine](/#/api/rules/) unless `forward` is explicitly set to `false`.\nIf payload has multiple events and each event is for a distinct resource, all _Events_ are forwarded to the [Rule Engine](/#/api/rules/) unless `forward` is explicitly set to `false`\nIf payload has multiple events and there are multiple events for the same resource, an error will be returned if `forward` is explicitly set to `true`.",
        "schema": {
          "type": "boolean",
          "default": true
        }
      },
      "ResourceForward": {
        "name": "forward",
        "in": "query",
        "description": "If payload is a single event, _Events_ are forwarded to the [Rule Engine](/#/api/rules/) unless `forward` is explicitly set to `false`.\nIf payload has multiple events, this parameter is ignored and _Events_ will only be stored into message cache and their scalar attributes in the timeseries database.",
        "schema": {
          "type": "boolean",
          "default": true
        }
      },
      "Store": {
        "name": "store",
        "in": "query",
        "description": "Unless explicitly set to `false`, _Events_ are stored \ninto message cache, and their scalar attributes stored in the time series database.",
        "schema": {
          "type": "boolean",
          "default": true
        }
      },
      "TTL": {
        "name": "ttl",
        "in": "query",
        "description": "Specifies how long data persists in both the message cache and time series database.",
        "schema": {
          "$ref": "#/components/schemas/TTLDuration"
        }
      },
      "From": {
        "name": "from",
        "in": "query",
        "description": "Specifies the lower bound of the time period",
        "schema": {
          "anyOf": [
            {
              "$ref": "#/components/schemas/UnixEpochMillis"
            },
            {
              "$ref": "#/components/schemas/DurationWithUnit"
            }
          ]
        }
      },
      "Until": {
        "name": "until",
        "in": "query",
        "description": "Specifies the upper bound of the time period",
        "schema": {
          "anyOf": [
            {
              "$ref": "#/components/schemas/UnixEpochMillis"
            },
            {
              "$ref": "#/components/schemas/DurationWithUnit"
            }
          ]
        }
      },
      "OnlyTimeseries": {
        "name": "onlytimeseries",
        "in": "query",
        "description": "if set to `true` will only delete timeseries data",
        "schema": {
          "type": "boolean",
          "default": false
        }
      },
      "MetricsToDelete": {
        "name": "metrics",
        "in": "query",
        "description": "If set, only these selected metrics are removed.",
        "schema": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/components/schemas/MetricId"
          }
        }
      },
      "SeriesQueryFrom": {
        "name": "from",
        "in": "query",
        "example": 1665619200000,
        "description": "Specifies the lower bound of the time period.\nIf not specified, a period of 7 days before `until` (or before the request was received) will be queried.",
        "schema": {
          "anyOf": [
            {
              "$ref": "#/components/schemas/UnixEpochMillis"
            },
            {
              "$ref": "#/components/schemas/ISO8601Timestamp"
            }
          ]
        }
      },
      "SeriesQueryUntil": {
        "name": "until",
        "in": "query",
        "example": 1665705600000,
        "description": "Specifies the upper bound of the time period.\nIf not specified, a period of 7 days after `from` (or before the request was received) will be queried",
        "schema": {
          "anyOf": [
            {
              "$ref": "#/components/schemas/UnixEpochMillis"
            },
            {
              "$ref": "#/components/schemas/ISO8601Timestamp"
            }
          ]
        }
      },
      "SeriesLastUntil": {
        "name": "until",
        "in": "query",
        "example": 1665705600000,
        "description": "Specifies the timestamp before which last values have to be retrieved.\nIf not specified, defaults to the current timestamp.",
        "schema": {
          "anyOf": [
            {
              "$ref": "#/components/schemas/UnixEpochMillis"
            },
            {
              "$ref": "#/components/schemas/ISO8601Timestamp"
            }
          ]
        }
      },
      "Aggregate": {
        "name": "aggregate",
        "in": "query",
        "description": "Specifies the aggregation function to use",
        "schema": {
          "$ref": "#/components/schemas/Aggregate"
        }
      },
      "Aggregates": {
        "name": "aggregates",
        "in": "query",
        "description": "comma-separated list of aggregation functions",
        "schema": {
          "type": "string",
          "externalDocs": {
            "description": "Possible functions",
            "url": "https://docs.waylay.io/#/api/broker/?id=aggregates"
          },
          "example": "min,max"
        }
      },
      "Grouping": {
        "name": "grouping",
        "in": "query",
        "description": "time period over which timeseries data must be aggregates",
        "schema": {
          "$ref": "#/components/schemas/Grouping"
        }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "description": "max number of values to retrieve",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "default": 1,
          "example": 100
        }
      },
      "Order": {
        "name": "order",
        "in": "query",
        "description": "sort order",
        "schema": {
          "$ref": "#/components/schemas/Order"
        }
      },
      "ReturnIngestionTimestamp": {
        "name": "returnIngestionTimestamp",
        "in": "query",
        "description": "return metric ingestion timestamp from time series database.",
        "schema": {
          "$ref": "#/components/schemas/ReturnIngestionTimestamp"
        }
      }
    },
    "securitySchemes": {
      "waylayApiKeySecret": {
        "type": "http",
        "description": "Waylay apiKey/apiSecret basic authentication. All endpoints support also Waylay JWT Bearer authentication.",
        "scheme": "basic"
      }
    }
  }
}