Cognite Time series API

A time series consists of a sequence of data points connected to a single asset. For example, a water pump asset can have a temperature time series that records a data point in units of °C every second. A single asset can have several time series. The water pump could have additional time series measuring pressure within the pump, rpm, flow volume, power consumption, and more.Time series store data points as either numbers or strings. This is controlled by the is_string flag on the time series object. Numerical data points can be aggregated before they are returned from a query (e.g., to find the average temperature for a day). String data points, on the other hand, can't be aggregated by CDF but can store arbitrary information like states (e.g., “open”/”closed”) or more complex information (JSON). Cognite stores discrete data points, but the underlying process measured by the data points can vary continuously. When interpolating between data points, we can either assume that each value stays the same until the next measurement or linearly changes between the two measurements. The `isStep` flag controls this on the time series object. For example, if we estimate the average over a time containing two data points, the average will either be close to the first (`isStep`) or close to the mean of the two (not `isStep`). A data point stores a single piece of information, a number or a string, associated with a specific time. Data points are identified by their timestamps, measured in milliseconds since the unix epoch -- 00:00:00.000, January 1st, 1970. The time series service accepts timestamps in the range from 00:00:00.000, January 1st, 1900 through 23:59:59.999, December 31st, 2099 (in other words, every millisecond in the two centuries from 1900 to but not including 2100). Negative timestamps are used to define dates before 1970. Milliseconds is the finest time resolution supported by CDF, i.e., fractional milliseconds are not supported. Leap seconds are not counted. Numerical data points can be aggregated before they are retrieved from CDF. This allows for faster queries by reducing the amount of data transferred. You can aggregate data points by specifying one or more aggregates (e.g., average, minimum, maximum) as well as the time granularity over which the aggregates should be applied (e.g., “1h” for one hour). Aggregates are aligned to the start time modulo the granularity unit. For example, if you ask for daily average temperatures since Monday afternoon last week, the first aggregated data point will contain averages for Monday, the second for Tuesday, etc. Determining aggregate alignment without considering data point timestamps allows CDF to pre-calculate aggregates (e.g., to quickly return daily average temperatures for a year). Consequently, aggregating over 60 minutes can return a different result than aggregating over 1 hour because the two queries will be aligned differently. Asset references obtained from a time series - through its asset ID - may be invalid simply by the non-transactional nature of HTTP. They are maintained in an eventually consistent manner.

OpenAPI Specification

cognite-time-series-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Cognite 3D Asset Mapping Time series API
  description: "# Introduction\nThis is the reference documentation for the Cognite API with\nan overview of all the available methods.\n\n# Postman\nSelect the **Download** button to download our OpenAPI specification to get started.\n\nTo import your data into Postman, select **Import**, and the Import modal opens.\nYou can import items by dragging or dropping files or folders. You can choose how to import your API and manage the import settings in **View Import Settings**.\n\nIn the Import Settings, set the **Folder organization** to **Tags**, select\n**Enable optional parameters** to turn off the settings, and select **Always inherit authentication** to turn on the settings. Select **Import**.\n\nSet the Authorization to **Oauth2.0**. By default, the settings are for Open Industrial Data. Navigate to [Cognite Hub](https://hub.cognite.com/open-industrial-data-211) to understand how to get the credentials for use in Postman.\n\nFor more information, see [Getting Started with Postman](https://developer.cognite.com/dev/guides/postman/).\n\n# Pagination\nMost resource types can be paginated, indicated by the field `nextCursor` in the response.\nBy passing the value of `nextCursor` as the cursor you will get the next page of `limit` results.\nNote that all parameters except `cursor` has to stay the same.\n\n# Parallel retrieval\nAs general guidance, Parallel Retrieval is a technique that should be used when due to query complexity, retrieval of data in a single request is significantly slower than it would otherwise be for a simple request.  Parallel retrieval does not act as a speed multiplier on optimally running queries.  By parallelizing such requests, data retrieval performance can be tuned to meet the client application needs. \n\nCDF supports parallel retrieval through the `partition` parameter, which has the format `m/n` where `n` is the amount of partitions you would like to split the entire data set into.\nIf you want to download the entire data set by splitting it into 10 partitions, do the following in parallel with `m` running from 1 to 10:\n  - Make a request to `/events` with `partition=m/10`.\n  - Paginate through the response by following the cursor as explained above. Note that the `partition` parameter needs to be passed to all subqueries.\n\nProcessing of parallel retrieval requests is subject to concurrency quota availability. The request returns the `429` response upon exceeding concurrency limits. See the Request throttling chapter below.\n\nTo prevent unexpected problems and to maximize read throughput, you should at most use 10 partitions. \nSome CDF resources will automatically enforce a maximum of 10 partitions.\nFor more specific and detailed information, please read the ```partition``` attribute documentation for the CDF resource you're using.  \n\n# Requests throttling\nCognite Data Fusion (CDF) returns the HTTP `429` (too many requests) response status code when project capacity exceeds the limit.\n\nThe throttling can happen:\n  - If a user or a project sends too many (more than allocated) concurrent requests.\n  - If a user or a project sends a too high (more than allocated) rate of requests in a given amount of time.\n\nCognite recommends using a retry strategy based on truncated exponential backoff to handle sessions with HTTP response codes 429.\n\nCognite recommends using a reasonable number (up to 10) of  `Parallel retrieval` partitions.\n\nFollowing these strategies lets you slow down the request frequency to maximize productivity without having to re-submit/retry failing requests.\n\nSee more [here](https://docs.cognite.com/dev/concepts/resource_throttling).\n\n# API versions\n## Version headers\nThis API uses calendar versioning, and version names follow the `YYYYMMDD` format.\nYou can find the versions currently available by using the version selector at the top of this page.\n\nTo use a specific API version, you can pass the `cdf-version: $version` header along with your requests to the API.\n\n## Beta versions\nThe beta versions provide a preview of what the stable version will look like in the future.\nBeta versions contain functionality that is reasonably mature, and highly likely to become a part of the stable API.\n\nBeta versions are indicated by a `-beta` suffix after the version name. For example, the beta version header for the\n2023-01-01 version is then `cdf-version: 20230101-beta`.\n\n## Alpha versions\nAlpha versions contain functionality that is new and experimental, and not guaranteed to ever become a part of the stable API.\nThis functionality presents no guarantee of service, so its use is subject to caution.\n\nAlpha versions are indicated by an `-alpha` suffix after the version name. For example, the alpha version header for\nthe 2023-01-01 version is then `cdf-version: 20230101-alpha`."
  version: v1
  contact:
    name: Cognite Support
    url: https://support.cognite.com
    email: support@cognite.com
servers:
- url: https://{cluster}.cognitedata.com/api/v1/projects/{project}
  description: The URL for the CDF cluster to connect to
  variables:
    cluster:
      enum:
      - api
      - az-tyo-gp-001
      - az-eastus-1
      - az-power-no-northeurope
      - westeurope-1
      - asia-northeast1-1
      - gc-dsm-gp-001
      default: api
      description: The CDF cluster to connect to
    project:
      default: publicdata
      description: The CDF project name.
security:
- oidc-token:
  - https://{cluster}.cognitedata.com/.default
- oauth2-client-credentials:
  - https://{cluster}.cognitedata.com/.default
- oauth2-open-industrial-data:
  - https://api.cognitedata.com/.default
- oauth2-auth-code:
  - https://{cluster}.cognitedata.com/.default
tags:
- name: Time series
  description: "A time series consists of a sequence of data points connected to a\nsingle asset. For example, a water pump asset can have a temperature time\nseries that records a data point in units of °C every second.\n\nA single asset can have several time series. The water pump could have additional time series\nmeasuring pressure within the pump, rpm, flow volume, power consumption, and more.Time\nseries store data points as either numbers or strings. This is controlled by the\nis_string flag on the time series object. Numerical data points can be aggregated\nbefore they are returned from a query (e.g., to find the average temperature for\na day). String data points, on the other hand, can't be aggregated by CDF but\ncan store arbitrary information like states (e.g., â\x80\x9Copenâ\x80\x9D/â\x80\x9Dclosedâ\x80\x9D) or more complex\ninformation (JSON).\n\nCognite stores discrete data points, but the underlying\nprocess measured by the data points can vary continuously. When interpolating\nbetween data points, we can either assume that each value stays the same until\nthe next measurement or linearly changes between the two measurements.\nThe `isStep` flag controls this on the time series object. For example,\nif we estimate the average over a time containing two data points, the average\nwill either be close to the first (`isStep`) or close to the mean of the two (not\n`isStep`).\n\nA data point stores a single piece of information, a number or a\nstring, associated with a specific time. Data points are identified by their timestamps,\nmeasured in milliseconds since the unix epoch -- 00:00:00.000, January 1st, 1970.\nThe time series service accepts timestamps in the range from 00:00:00.000, January 1st, 1900\nthrough 23:59:59.999, December 31st, 2099 (in other words, every millisecond in the two\ncenturies from 1900 to but not including 2100). Negative timestamps are\nused to define dates before 1970. Milliseconds is the finest time resolution supported by CDF, i.e.,\nfractional milliseconds are not supported. Leap seconds are not counted.\n\nNumerical data points can be aggregated before they are retrieved from CDF. This allows for faster queries by reducing\nthe amount of data transferred. You can aggregate data points by specifying one\nor more aggregates (e.g., average, minimum, maximum) as well as the time granularity\nover which the aggregates should be applied (e.g., â\x80\x9C1hâ\x80\x9D for one hour).\n\nAggregates are aligned to the start time modulo the granularity unit. For example, if you\nask for daily average temperatures since Monday afternoon last week, the first\naggregated data point will contain averages for Monday, the second for Tuesday,\netc. Determining aggregate alignment without considering data point timestamps\nallows CDF to pre-calculate aggregates (e.g., to quickly return daily average temperatures\nfor a year). Consequently, aggregating over 60 minutes can return a different\nresult than aggregating over 1 hour because the two queries will be aligned differently.\nAsset references obtained from a time series - through its asset ID - may be invalid simply\nby the non-transactional nature of HTTP. They are maintained in an eventually consistent\nmanner."
paths:
  /timeseries:
    get:
      tags:
      - Time series
      summary: List time series
      description: '


        > **Required capabilities:** `timeSeriesAcl:READ`


        List time series. Use `nextCursor` to paginate through the results.'
      operationId: getTimeSeries
      parameters:
      - name: limit
        in: query
        description: Limits the number of results to return. CDF returns a maximum of 1000 results even if you specify a higher limit.
        schema:
          maximum: 1000
          minimum: 1
          type: integer
          format: int32
          default: 100
      - $ref: '#/components/parameters/IncludeMetadata'
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/partition'
      - name: assetIds
        in: query
        description: Gets the time series related to the assets. The format is a list of IDs serialized as a JSON array(int64). Takes [ 1 .. 100 ] unique items.
        example: '[363848954441724, 793045462540095, 1261042166839739]'
        schema:
          $ref: '#/components/schemas/JsonArrayInt64'
      - name: rootAssetIds
        in: query
        description: Only includes time series that have a related asset in a tree rooted at any of these root `assetIds`.
        example: '[363848954441724, 793045462540095, 1261042166839739]'
        schema:
          $ref: '#/components/schemas/JsonArrayInt64'
      - in: query
        name: externalIdPrefix
        schema:
          $ref: '#/components/schemas/CogniteExternalIdPrefix'
      responses:
        '200':
          description: A list of time series in lexicographic order.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataWithCursorGetTimeSeriesMetadataDTO'
      x-capability:
      - timeSeriesAcl:READ
      x-code-samples:
      - lang: JavaScript
        label: JavaScript SDK
        source: 'const timeseries = await client.timeseries.list({ filter: { assetIds: [1, 2] }});'
      - lang: Python
        label: Python SDK
        source: "from cognite.client.data_classes.filters import Equals\nis_numeric = Equals(\"is_string\", False)\nres = client.time_series.filter(filter=is_numeric, sort=\"external_id\")\n\nfrom cognite.client.data_classes.filters import Equals\nfrom cognite.client.data_classes.time_series import TimeSeriesProperty, SortableTimeSeriesProperty\nis_numeric = Equals(TimeSeriesProperty.is_string, False)\nres = client.time_series.filter(filter=is_numeric, sort=SortableTimeSeriesProperty.external_id)\nres = client.time_series.list(limit=5)\n\nfor ts in client.time_series:\n    ts # do something with the time series\n\nfor ts_list in client.time_series(chunk_size=2500):\n    ts_list # do something with the time series\n\nfrom cognite.client.data_classes import filters\nin_timezone = filters.Prefix([\"metadata\", \"timezone\"], \"Europe\")\nres = client.time_series.list(advanced_filter=in_timezone, sort=(\"external_id\", \"asc\"))\n\nfrom cognite.client.data_classes import filters\nfrom cognite.client.data_classes.time_series import TimeSeriesProperty, SortableTimeSeriesProperty\nin_timezone = filters.Prefix(TimeSeriesProperty.metadata_key(\"timezone\"), \"Europe\")\nres = client.time_series.list(\n    advanced_filter=in_timezone,\n    sort=(SortableTimeSeriesProperty.external_id, \"asc\"))\n\nfrom cognite.client.data_classes import filters\nnot_instrument_lvl5 = filters.And(\n   filters.ContainsAny(\"labels\", [\"Level5\"]),\n   filters.Not(filters.ContainsAny(\"labels\", [\"Instrument\"]))\n)\nres = client.time_series.list(asset_subtree_ids=[123456], advanced_filter=not_instrument_lvl5)\n"
    post:
      tags:
      - Time series
      summary: Create time series
      description: '


        > **Required capabilities:** `timeSeriesAcl:WRITE`


        Creates one or more time series.'
      operationId: postTimeSeries
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TimeSeriesCreateRequest'
        required: true
      responses:
        '201':
          description: Response with the created time series.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataGetTimeSeriesMetadataDTO'
        '400':
          $ref: '#/components/responses/MissingField'
        '409':
          description: Time series with the specified externalIds already exists. Retry request, with the existing externalIds removed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalIdsAlreadyExistResponse'
        '422':
          description: Duplicated externalIds found. Retry request, keeping only one instance of each duplicated externalId.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DuplicatedIdsInRequestResponse'
      x-capability:
      - timeSeriesAcl:WRITE
      x-code-samples:
      - lang: JavaScript
        label: JavaScript SDK
        source: "const timeseries = [\n  { name: 'Pressure sensor', assetId: 123 },\n  { name: 'Temprature sensor', description: 'Pump abc', unit: 'C' },\n];\nconst createdTimeseries = await client.timeseries.create(timeseries);"
      - lang: Python
        label: Python SDK
        source: 'from cognite.client.data_classes import TimeSeriesWrite

          ts = client.time_series.create(TimeSeriesWrite(name="my_ts", data_set_id=123, external_id="foo"))

          '
      - lang: Java
        label: Java SDK
        source: "List<TimeseriesMetadata> upsertTimeseriesList = List.of(TimeseriesMetadata.newBuilder() \n   .setExternalId(\"10\") \n   .setName(\"test_ts\") \n   .setIsString(false) \n   .setIsStep(false) \n   .setDescription(\"Description\") \n   .setUnit(\"TestUnits\") \n   .putMetadata(\"type\", \"sdk-data-generator\") \n   .putMetadata(\"sdk-data-generator\", \"sdk-data-generator\") \n .build()); \n\nclient.timeseries().upsert(upsertTimeseriesList); \n\n"
  /timeseries/byids:
    post:
      tags:
      - Time series
      summary: Retrieve time series
      description: '


        > **Required capabilities:** `timeSeriesAcl:READ`


        Retrieves one or more time series by ID or external ID. The response returns the time series in the same order as in the request.'
      operationId: getTimeSeriesByIds
      requestBody:
        description: List of the IDs of the time series to retrieve.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TimeSeriesLookupById'
        required: true
      responses:
        '200':
          description: Response with a list of time series matching the IDs.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataGetTimeSeriesMetadataDTO'
        '400':
          description: IDs not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotFoundResponse'
        '422':
          description: Duplicate IDs found. Retry request, keeping only one instance of each duplicated ID.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DuplicatedIdsInRequestResponse'
      x-capability:
      - timeSeriesAcl:READ
      x-code-samples:
      - lang: JavaScript
        label: JavaScript SDK
        source: "const timeseries = await client.timeseries.retrieve([\n  { id: 123 },\n  { externalId: 'abc' }\n]);"
      - lang: Python
        label: Python SDK
        source: 'res = client.time_series.retrieve(id=1)


          res = client.time_series.retrieve(external_id="1")

          res = client.time_series.retrieve_multiple(ids=[1, 2, 3])


          res = client.time_series.retrieve_multiple(external_ids=["abc", "def"])

          '
      - lang: Java
        label: Java SDK
        source: "List<Item> byExternalIds = List.of(Item.newBuilder().setExternalId(\"10\").build()); \nList<TimeseriesMetadata> retrievedAssets = client.timeseries().retrieve(byExternalIds);// by list of items \nList<TimeseriesMetadata> retrievedAssets = client.timeseries().retrieve(\"10\", \"20\");// by varargs of String \n\nList<Item> byInternalIds = List.of(Item.newBuilder().setId(10).build()); \nList<TimeseriesMetadata> retrievedAssets = client.timeseries().retrieve(byInternalIds);// by list of items \nList<TimeseriesMetadata> retrievedAssets = client.timeseries().retrieve(10, 20);// by varargs of Long \n\n"
  /timeseries/list:
    post:
      tags:
      - Time series
      summary: Filter time series
      description: "\n\n> **Required capabilities:** `timeSeriesAcl:READ`\n\n<details>\n<summary>\nRetrieves a list of time series that match the given criteria.\n</summary>\n\n### Advanced filtering\n\nThe `advancedFilter`\nfield lets you create complex filtering expressions that combine simple operations,\nsuch as `equals`, `prefix`, and `exists`, by using the Boolean operators `and`, `or`, and `not`.\nFiltering applies to basic fields as well as metadata. See the `advancedFilter` syntax in the request example.\n\n\n\n#### Supported leaf filters\n\n| Leaf filter    | Supported fields       | Description and example                                                                                                                                                            |\n|----------------|------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `containsAll`  | Array type fields      | Only includes results which contain all of the specified values. <br /> `{\"containsAll\": {\"property\": [\"property\"], \"values\": [1, 2, 3]}}`                                         |\n| `containsAny`  | Array type fields      | Only includes results which contain at least one of the specified values. <br /> `{\"containsAny\": {\"property\": [\"property\"], \"values\": [1, 2, 3]}}`                                |\n| `equals`       | Non-array type fields  | Only includes results that are equal to the specified value. <br /> `{\"equals\": {\"property\": [\"property\"], \"value\": \"example\"}}`                                                   |\n| `exists`       | All fields             | Only includes results where the specified property exists (has a value). <br /> `{\"exists\": {\"property\": [\"property\"]}}`                                                           |\n| `in`           | Non-array type fields  | Only includes results that are equal to one of the specified values. <br /> `{\"in\": {\"property\": [\"property\"], \"values\": [1, 2, 3]}}`                                              |\n| `prefix`       | String type fields     | Only includes results which start with the specified text. <br /> `{\"prefix\": {\"property\": [\"property\"], \"value\": \"example\"}}`                                                     |\n| `range`        | Non-array type fields  | Only includes results that fall within the specified range. <br /> `{\"range\": {\"property\": [\"property\"], \"gt\": 1, \"lte\": 5}}` <br /> Supported operators: `gt`, `lt`, `gte`, `lte` |\n | `search`       | `[\"name\"]` and `[\"description\"]` | Introduced to provide functional parity with the /timeseries/search endpoint. <br /> `{\"search\": {\"property\": [\"property\"], \"value\": \"example\"}}`                        |\n\n#### Supported properties\n\n| Property                          | Type               |\n|-----------------------------------|--------------------|\n| `[\"description\"]`                 | string             |\n| `[\"externalId\"]`                  | string             |\n| `[\"metadata\", \"<someCustomKey>\"]` | string             |\n| `[\"name\"]`                        | string             |\n| `[\"unit\"]`                         | string              |\n| `[\"unitExternalId\"]`               | string              |\n| `[\"unitQuantity\"]`                 | string              |\n| `[\"instanceId\", \"space\"]`          | string              |\n| `[\"instanceId\", \"externalId\"]`     | string              |\n| `[\"assetId\"]`                      | number              |\n| `[\"assetRootId\"]`                  | number              |\n| `[\"createdTime\"]`                  | number              |\n| `[\"dataSetId\"]`                    | number              |\n| `[\"id\"]`                           | number              |\n| `[\"lastUpdatedTime\"]`              | number              |\n| `[\"isStep\"]`                       | Boolean             |\n| `[\"isString\"]`                     | Boolean             |\n| `[\"type\"]`                         | string              |\n| `[\"securityCategories\"]`           | array of numbers    |\n\n#### Limits\n\n- Filter query max depth: 10.\n- Filter query max number of clauses: 100.\n- `and` and `or` clauses must have at least one element (and at most 99, since each element counts\n  towards the total clause limit, and so does the `and`/`or` clause itself).\n- The `property` array of each leaf filter has the following limitations:\n  - Number of elements in the array is 1 or 2.\n  - Elements must not be null or blank.\n  - Each element max length is 256 characters.\n  - The `property` array must match one of the existing properties (static top-level property or dynamic metadata property).\n- `containsAll`, `containsAny`, and `in` filter `values` array size must be in the range [1, 100].\n- `containsAll`, `containsAny`, and `in` filter `values` array must contain elements of number or string type (matching the type of the given property).\n- `range` filter must have at lest one of `gt`, `gte`, `lt`, `lte` attributes.\n  But `gt` is mutually exclusive to `gte`, while `lt` is mutually exclusive to `lte`.\n- `gt`, `gte`, `lt`, `lte` in the `range` filter must be of number or string type (matching the type of the given property).\n- `search` filter `value` must not be blank, and the length must be in the range [1, 128], and there\n  may be at most two `search` filters in the entire filter query.\n- The maximum length of the `value` of a leaf filter that is applied to a string property is 256.\n\n### Sorting\n\nBy default, time series are sorted by their creation time in ascending order.\nSorting by another property or by several other properties can be explicitly requested via the\n`sort` field, which must contain a list\nof one or more sort specifications. Each sort specification indicates the `property` to sort on\nand, optionally, the `order` in which to sort (defaults to `asc`). If multiple sort specifications are\nsupplied, the results are sorted on the first property, and those with the same value for the first\nproperty are sorted on the second property, and so on.  \nPartitioning is done independently of sorting; there is no guarantee of sort order between elements from different partitions.\n\n#### Null values\n\nIn case the `nulls` field has the `auto` value, or the field isn't specified, null (missing) values\nare considered bigger than any other values. They are placed last when sorting in the `asc`\norder and first in the `desc` order. Otherwise, missing values are placed according to\nthe `nulls` field (`last` or `first`), and their placement won't depend on the `order`\nfield. Note that the number zero, empty strings, and empty lists are all considered\n_not_ null.\n\n#### Example\n\n```json\n{\n  \"sort\": [\n    {\n      \"property\" : [\"createdTime\"],\n      \"order\": \"desc\",\n      \"nulls\": \"last\"\n    },\n    {\n      \"property\" : [\"metadata\", \"<someCustomKey>\"]\n    }\n  ]\n}\n```\n\n\n#### Properties\n\nYou can sort on the following properties:\n\n| Property                          |\n|-----------------------------------|\n| `[\"assetId\"]`                     |\n| `[\"createdTime\"]`                 |\n| `[\"dataSetId\"]`                   |\n| `[\"description\"]`                 |\n| `[\"externalId\"]`                  |\n| `[\"lastUpdatedTime\"]`             |\n| `[\"metadata\", \"<someCustomKey>\"]` |\n| `[\"name\"]`                        |\n| `[\"instanceId\", \"space\"]`         |\n| `[\"instanceId\", \"externalId\"]`    |\n\n#### Limits\n\nThe `sort` array must contain 1 to 2 elements.\n</details>\n"
      operationId: listTimeSeries
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TimeSeriesListDTO'
      responses:
        '200':
          description: Response with a list of time series matching the specified criteria.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataWithCursorGetTimeSeriesMetadataDTO'
      x-capability:
      - timeSeriesAcl:READ
      x-code-samples:
      - lang: Python
        label: Python SDK
        source: "from cognite.client.data_classes.filters import Equals\nis_numeric = Equals(\"is_string\", False)\nres = client.time_series.filter(filter=is_numeric, sort=\"external_id\")\n\nfrom cognite.client.data_classes.filters import Equals\nfrom cognite.client.data_classes.time_series import TimeSeriesProperty, SortableTimeSeriesProperty\nis_numeric = Equals(TimeSeriesProperty.is_string, False)\nres = client.time_series.filter(filter=is_numeric, sort=SortableTimeSeriesProperty.external_id)\nres = client.time_series.list(limit=5)\n\nfor ts in client.time_series:\n    ts # do something with the time series\n\nfor ts_list in client.time_series(chunk_size=2500):\n    ts_list # do something with the time series\n\nfrom cognite.client.data_classes import filters\nin_timezone = filters.Prefix([\"metadata\", \"timezone\"], \"Europe\")\nres = client.time_series.list(advanced_filter=in_timezone, sort=(\"external_id\", \"asc\"))\n\nfrom cognite.client.data_classes import filters\nfrom cognite.client.data_classes.time_series import TimeSeriesProperty, SortableTimeSeriesProperty\nin_timezone = filters.Prefix(TimeSeriesProperty.metadata_key(\"timezone\"), \"Europe\")\nres = client.time_series.list(\n    advanced_filter=in_timezone,\n    sort=(SortableTimeSeriesProperty.external_id, \"asc\"))\n\nfrom cognite.client.data_classes import filters\nnot_instrument_lvl5 = filters.And(\n   filters.ContainsAny(\"labels\", [\"Level5\"]),\n   filters.Not(filters.ContainsAny(\"labels\", [\"Instrument\"]))\n)\nres = client.time_series.list(asset_subtree_ids=[123456], advanced_filter=not_instrument_lvl5)\n"
      - lang: Java
        label: Java SDK
        source: "List<TimeseriesMetadata> listTimeseriesResults = new ArrayList<>(); \nclient.timeseries() \n .list() \n .forEachRemaining(timeseries -> listTimeseriesResults.addAll(timeseries)); \n\nList<TimeseriesMetadata> listTimeseriesResults = new ArrayList<>(); \nclient.timeseries() \n .list(Request.create() \n .withFilterMetadataParameter(\"source\", \"source\")) \n .forEachRemaining(timeseries -> listTimeseriesResults.addAll(timeseries)); \n\n"
  /timeseries/aggregate:
    post:
      tags:
      - Time series
      summary: Aggregate time series
      operationId: aggregateTimeSeries
      x-capability:
      - timeSeriesAcl:READ
      description: "\n\n> **Required capabilities:** `timeSeriesAcl:READ`\n\nThe aggregation API allows you to compute aggregated results from a set of time series, such as\r\ngetting the number of time series in a project or checking what assets the different time series\r\nin your project are associated with (along with the number of time series for each asset).\r\nBy specifying `filter` and/or `advancedFilter`, the aggregation will take place only over those\r\ntime series that match the filters. `filter` and `advancedFilter` behave the same way as in the\r\n`list` endpoint.\r\n\r\n<details>\r\n<summary>\r\nThe default behavior, when the <code>aggregate</code> field is not specified the request body, is to return the\r\nnumber of time series that match the filters (if any), which is the same behavior as when the\r\n<code>aggregate</code> field is set to <code>count</code>.\r\n</summary>\r\n\r\nThe following requests will both return the total number of\r\ntime series whose `name` begins with `pump`:\r\n\r\n```\r\n{\r\n  \"advancedFilter\": {\"prefix\": {\"property\": [\"name\"], \"value\": \"pump\"}}\r\n}\r\n```\r\n\r\nand\r\n\r\n```\r\n{\r\n  \"aggregate\": \"count\",\r\n  \"advancedFilter\": {\"prefix\": {\"property\": [\"name\"], \"value\": \"pump\"}}\r\n}\r\n```\r\n\r\nThe response might be:\r\n\r\n```\r\n{\"items\": [{\"count\": 42}]}\r\n```\r\n</details>\r\n\r\n<details>\r\n<summary>\r\nSetting <code>aggregate</code> to <code>uniqueValues</code> and specifying a property in <code>properties</code> (this field is an array, but currently only supports one property) will\r\nreturn all unique values (up to a maximum of 1000) that are taken on by that property\r\nacross all the time series that match the filters, as well as the number of time series that\r\nhave each of those property values.\r\n</summary>\r\n\r\nThis example request finds all the unique asset ids that are\r\nreferenced by the time series in your project whose `name` begins with `pump`:\r\n\r\n```\r\n{\r\n  \"aggregate\": \"uniqueValues\",\r\n  \"properties\": [{\"property\": [\"assetId\"]}],\r\n  \"advancedFilter\": {\"prefix\": {\"property\": [\"name\"], \"value\": \"pump\"}}\r\n}\r\n```\r\n\r\nThe response might be the following, saying that 23 time series are associated with asset 18\r\nand 107 time series are associated with asset 76:\r\n\r\n```\r\n{\r\n  \"items\": [\r\n    {\"values\": [\"18\"], \"count\": 23},\r\n    {\"values\": [\"76\"], \"count\": 107}\r\n  ]\r\n}\r\n```\r\n</details>\r\n\r\n<details>\r\n<summary>\r\nSetting <code>aggregate</code> to <code>cardinalityValues</code> will instead return the approximate number of\r\ndistinct values that are taken on by the given property among the matching time series.\r\n</summary>\r\n\r\nExample request:\r\n\r\n```\r\n{\r\n  \"aggregate\": \"cardinalityValues\",\r\n  \"properties\": [{\"property\": [\"assetId\"]}],\r\n  \"advancedFilter\": {\"prefix\": {\"property\": [\"name\"], \"value\": \"pump\"}}\r\n}\r\n```\r\n\r\nThe result is likely exact when the set of unique values is small. In this example, there are likely two distinct asset ids among the matching time series:\r\n\r\n```\r\n{\"items\": [{\"count\": 2}]}\r\n```\r\n</details>\r\n\r\n<details>\r\n<summary>\r\nSetting <code>aggregate</code> to <code>uniqueProperties</code> will return the set of unique properties whose property\r\npath begins with <code>path</code> (which can currently only be <code>[\"metadata\"]</code>) that are contained in the time series that match the filters.\r\n</summary>\r\n\r\nExample request:\r\n\r\n```\r\n{\r\n  \"aggregate\": \"uniqueProperties\",\r\n  \"path\": [\"metadata\"],\r\n  \"advancedFilter\": {\"prefix\": {\"property\": [\"name\"], \"value\": \"pump\"}}\r\n}\r\n```\r\n\r\nThe result contains all the unique metadata keys in the time series whose `name` begins with\r\n`pump`, and the number of time series that contains each metadata key:\r\n\r\n```\r\n{\r\n  \"items\": [\r\n    {\"values\": [{\"property\": [\"metadata\", \"tag\"]}], \"count\": 43},\r\n    {\"values\": [{\"property\": [\"metadata\", \"installationDate\"]}], \"count\": 97}\r\n  ]\r\n}\r\n```\r\n</details>\r\n\r\n<details>\r\n<summary>\r\nSetting <code>aggregate</code> to <code>cardinalityProperties</code> will instead return the approximate

# --- truncated at 32 KB (159 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/cognite/refs/heads/main/openapi/cognite-time-series-api-openapi.yml