Cognite Records API

Records are mutable or immutable data objects (depending on the stream template) stored in a stream. Records are created by ingesting data into a stream. Records are shaped similarly to instances in the Data Modeling service, and their schema is defined by the containers referenced as sources. Each record is associated with a space. Space-based access control applies to records. This section specifies the `records` resource and uses the following Data Modeling concepts: - [Spaces](https://docs.cognite.com/cdf/dm/dm_concepts/dm_spaces_instances#space) - [Containers](https://docs.cognite.com/cdf/dm/dm_concepts/dm_containers_views_datamodels#containers) **Note:** Every `record` has a required top-level `externalId` property, which can be used in some queries to retrieve or aggregate records (for filtering or sorting). For mutable records, `externalId` (together with `space`) uniquely identifies a record for write operations (create, upsert, delete). For immutable records, the records API does not enforce uniqueness of the `space` + `externalId` pair, so multiple records may share the same identifier. ## Rate and concurrency limits Both the rate of requests (denoted as requests per second, or ‘**rps**’) and the number of concurrent (parallel) requests are governed by limits for all CDF API endpoints. If a request exceeds a limit, it will be throttled with a `429: Too Many Requests` response. See [Resource throttling](https://docs.cognite.com/dev/concepts/resource_throttling) for limit types and how to avoid throttling. Limits apply to the API endpoints for this service. Some request types consume more resources (compute, storage I/O) than others. For example, ingest requests are less resource-intensive than analytical requests (Aggregate, Retrieve). Limits for query endpoints (Sync, Retrieve, Aggregate) are hierarchical: - All query endpoints share a common **Query request budget** (shown in the tables below) - The Retrieve endpoint has an **additional** dedicated budget that is checked first - The Aggregate endpoint has an **additional** dedicated budget that is checked first The Sync endpoint only checks the Query request budget. The Retrieve and Aggregate endpoints must pass both their dedicated budget check AND the Query request budget check. For example, with mutable streams you can make up to 40 rps total across all query endpoints (Query budget limit), but only up to 20 of those can be Retrieve requests (Retrieve budget limit) and only up to 15 can be Aggregate requests (Aggregate budget limit). That means you could send 20 Retrieve + 15 Aggregate + 5 Sync = 40 total RPS. Query performance and rate limits vary between mutable and immutable streams because of their different storage characteristics. Mutable streams provide consistent high-performance queries and higher rate limits (see "mutable streams" limits in the tables below). Immutable streams are optimized for ingesting very large amounts of data, which results in lower query performance and stricter rate limits than mutable streams (see "immutable streams" limits in the tables below). When designing data access patterns, use mutable streams for high-performance queries and higher rate limits, or immutable streams when the priority is high-volume ingestion and long-term storage. The amount of data returned in responses from query endpoints (Sync, Retrieve, Aggregate) is also limited. Prefer reading only the data you need: use an appropriate `filter` and limit which `sources` are retrieved, rather than retrieving large result sets that you will not use. The version limits for the records endpoints are shown in the tables below. These limits are subject to change, pending review of consumption patterns and resource availability over time: Ingest request budget Overall Per ID Requests per second 40 30 Concurrent requests 20 15 Query request budget Overall Per ID Requests per second: mutable streams 40 30 Concurrent requests: mutable streams 30 22 Requests per second: immutable streams 10 7 Concurrent requests: immutable streams 10 7 Response MB per second 4 3 Additional dedicated budgets for Retrieve and Aggregate endpoints: The Retrieve and Aggregate endpoints have dedicated budgets that are checked in addition to the Query request budget shown above. A request to these endpoints must pass both budget checks. Retrieve request budget Overall Per ID Requests per second: mutable streams 20 15 Concurrent requests: mutable streams 20 15 Requests per second: immutable streams 10 7 Concurrent requests: immutable streams 10 7 Note: Retrieve endpoint requests are checked against both this budget and the Query request budget above. Aggregate request budget Overall Per ID Requests per second: mutable streams 15 12 Concurrent requests: mutable streams 10 7 Requests per second: immutable streams 5 4 Concurrent requests: immutable streams 5 4 Note: Aggregate endpoint requests are checked against both this budget and the Query request budget above. Summary: Sync endpoint: Only limited by Query request budget Retrieve endpoint: Limited by Retrieve request budget AND Query request budget Aggregate endpoint: Limited by Aggregate request budget AND Query request budget

OpenAPI Specification

cognite-records-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Cognite 3D Asset Mapping Records 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: Records
  description: "Records are mutable or immutable data objects (depending on the stream template) stored in a stream. Records are created by ingesting data into a stream.\nRecords are shaped similarly to instances in the Data Modeling service, and their schema is defined by the containers referenced as sources.\nEach record is associated with a space. Space-based access control applies to records.\nThis section specifies the `records` resource and uses the following Data Modeling concepts:\n  - [Spaces](https://docs.cognite.com/cdf/dm/dm_concepts/dm_spaces_instances#space)\n  - [Containers](https://docs.cognite.com/cdf/dm/dm_concepts/dm_containers_views_datamodels#containers)\n\n**Note:** Every `record` has a required top-level `externalId` property, which can be used\nin some queries to retrieve or aggregate records (for filtering or sorting).\nFor mutable records, `externalId` (together with `space`) uniquely identifies a record for write operations (create, upsert, delete).\nFor immutable records, the records API does not enforce uniqueness of the `space` + `externalId` pair, so multiple records may share the same identifier.\n\n## Rate and concurrency limits\n\nBoth the rate of requests (denoted as requests per second, or â\x80\x98**rps**â\x80\x99) and the number of concurrent (parallel)\nrequests are governed by limits for all CDF API endpoints. If a request exceeds a limit,\nit will be throttled with a `429: Too Many Requests` response. See [Resource throttling](https://docs.cognite.com/dev/concepts/resource_throttling) for limit types and how to avoid throttling.\n\nLimits apply to the API endpoints for this service.\nSome request types consume more resources (compute, storage I/O) than others. For example, ingest requests\nare less resource-intensive than analytical requests (Aggregate, Retrieve).\n\nLimits for query endpoints (Sync, Retrieve, Aggregate) are hierarchical:\n- All query endpoints share a common **Query request budget** (shown in the tables below)\n- The Retrieve endpoint has an **additional** dedicated budget that is checked first\n- The Aggregate endpoint has an **additional** dedicated budget that is checked first\n\nThe Sync endpoint only checks the Query request budget. The Retrieve and Aggregate endpoints\nmust pass both their dedicated budget check AND the Query request budget check.\n\nFor example, with mutable streams you can make up to 40 rps total across all query endpoints\n(Query budget limit), but only up to 20 of those can be Retrieve requests (Retrieve budget limit)\nand only up to 15 can be Aggregate requests (Aggregate budget limit).\nThat means you could send 20 Retrieve + 15 Aggregate + 5 Sync = 40 total RPS.\n\nQuery performance and rate limits vary between mutable and immutable streams because of\ntheir different storage characteristics.\n\nMutable streams provide consistent high-performance queries and higher rate limits\n(see \"mutable streams\" limits in the tables below).\n\nImmutable streams are optimized for ingesting very large amounts of data,\nwhich results in lower query performance and stricter rate limits than mutable streams\n(see \"immutable streams\" limits in the tables below).\n\nWhen designing data access patterns, use mutable streams for high-performance queries and higher rate limits, or immutable streams when the priority\nis high-volume ingestion and long-term storage.\n\nThe amount of data returned in responses from query endpoints (Sync, Retrieve, Aggregate)\nis also limited. Prefer reading only the data you need: use an appropriate `filter` and limit which `sources` are retrieved, rather than\nretrieving large result sets that you will not use.\n\nThe version limits for the records endpoints are shown in the tables below.\nThese limits are subject to change, pending review of consumption patterns and resource availability over time:\n\n  <table >\n    <thead>\n      <tr>\n        <th colspan=\"3\" style=\"text-align: center; background-color: #e0e0e0; padding: 10px; font-weight: bold;\">Ingest request budget</th>\n      </tr>\n      <tr>\n        <th></th>\n        <th style=\"text-align: center;\">Overall</th>\n        <th style=\"text-align: center;\">Per ID</th>\n      </tr>\n    </thead>\n    <tbody>\n      <tr>\n        <td><strong>Requests per second</strong></td>\n        <td style=\"text-align: center;\">40</td>\n        <td style=\"text-align: center;\">30</td>\n      </tr>\n      <tr>\n        <td><strong>Concurrent requests</strong></td>\n        <td style=\"text-align: center;\">20</td>\n        <td style=\"text-align: center;\">15</td>\n      </tr>\n    </tbody>\n  </table>\n\n  <table >\n    <thead>\n      <tr>\n        <th colspan=\"3\" style=\"text-align: center; background-color: #e0e0e0; padding: 10px; font-weight: bold;\">Query request budget</th>\n      </tr>\n      <tr>\n        <th></th>\n        <th style=\"text-align: center;\">Overall</th>\n        <th style=\"text-align: center;\">Per ID</th>\n      </tr>\n    </thead>\n    <tbody>\n      <tr>\n        <td><strong>Requests per second: mutable streams</strong></td>\n        <td style=\"text-align: center;\">40</td>\n        <td style=\"text-align: center;\">30</td>\n      </tr>\n      <tr>\n        <td><strong>Concurrent requests: mutable streams</strong></td>\n        <td style=\"text-align: center;\">30</td>\n        <td style=\"text-align: center;\">22</td>\n      </tr>\n      <tr>\n        <td><strong>Requests per second: immutable streams</strong></td>\n        <td style=\"text-align: center;\">10</td>\n        <td style=\"text-align: center;\">7</td>\n      </tr>\n      <tr>\n        <td><strong>Concurrent requests: immutable streams</strong></td>\n        <td style=\"text-align: center;\">10</td>\n        <td style=\"text-align: center;\">7</td>\n      </tr>\n      <tr>\n        <td><strong>Response MB per second</strong></td>\n        <td style=\"text-align: center;\">4</td>\n        <td style=\"text-align: center;\">3</td>\n      </tr>\n    </tbody>\n  </table>\n\n<p style=\"margin-top: 20px;\">\n  <strong>Additional dedicated budgets for Retrieve and Aggregate endpoints:</strong>\n</p>\n\n<p style=\"margin-top: 10px;\">\n  The Retrieve and Aggregate endpoints have dedicated budgets that are checked <em>in addition to</em>\n  the Query request budget shown above. A request to these endpoints must pass both budget checks.\n</p>\n\n  <table >\n    <thead>\n      <tr>\n        <th colspan=\"3\" style=\"text-align: center; background-color: #e0e0e0; padding: 10px; font-weight: bold;\">Retrieve request budget</th>\n      </tr>\n      <tr>\n        <th></th>\n        <th style=\"text-align: center;\">Overall</th>\n        <th style=\"text-align: center;\">Per ID</th>\n      </tr>\n    </thead>\n    <tbody>\n      <tr>\n        <td><strong>Requests per second: mutable streams</strong></td>\n        <td style=\"text-align: center;\">20</td>\n        <td style=\"text-align: center;\">15</td>\n      </tr>\n      <tr>\n        <td><strong>Concurrent requests: mutable streams</strong></td>\n        <td style=\"text-align: center;\">20</td>\n        <td style=\"text-align: center;\">15</td>\n      </tr>\n      <tr>\n        <td><strong>Requests per second: immutable streams</strong></td>\n        <td style=\"text-align: center;\">10</td>\n        <td style=\"text-align: center;\">7</td>\n      </tr>\n      <tr>\n        <td><strong>Concurrent requests: immutable streams</strong></td>\n        <td style=\"text-align: center;\">10</td>\n        <td style=\"text-align: center;\">7</td>\n      </tr>\n    </tbody>\n  </table>\n\n<p style=\"margin-top: 10px; font-style: italic; font-size: 0.9em;\">\n  Note: Retrieve endpoint requests are checked against both this budget and the Query request budget above.\n</p>\n\n  <table >\n    <thead>\n      <tr>\n        <th colspan=\"3\" style=\"text-align: center; background-color: #e0e0e0; padding: 10px; font-weight: bold;\">Aggregate request budget</th>\n      </tr>\n      <tr>\n        <th></th>\n        <th style=\"text-align: center;\">Overall</th>\n        <th style=\"text-align: center;\">Per ID</th>\n      </tr>\n    </thead>\n    <tbody>\n      <tr>\n        <td><strong>Requests per second: mutable streams</strong></td>\n        <td style=\"text-align: center;\">15</td>\n        <td style=\"text-align: center;\">12</td>\n      </tr>\n      <tr>\n        <td><strong>Concurrent requests: mutable streams</strong></td>\n        <td style=\"text-align: center;\">10</td>\n        <td style=\"text-align: center;\">7</td>\n      </tr>\n      <tr>\n        <td><strong>Requests per second: immutable streams</strong></td>\n        <td style=\"text-align: center;\">5</td>\n        <td style=\"text-align: center;\">4</td>\n      </tr>\n      <tr>\n        <td><strong>Concurrent requests: immutable streams</strong></td>\n        <td style=\"text-align: center;\">5</td>\n        <td style=\"text-align: center;\">4</td>\n      </tr>\n    </tbody>\n  </table>\n\n<p style=\"margin-top: 10px; font-style: italic; font-size: 0.9em;\">\n  Note: Aggregate endpoint requests are checked against both this budget and the Query request budget above.\n</p>\n\n<p style=\"margin-top: 20px;\">\n  <strong>Summary:</strong>\n</p>\n<ul style=\"margin-top: 10px;\">\n  <li><strong>Sync endpoint:</strong> Only limited by Query request budget</li>\n  <li><strong>Retrieve endpoint:</strong> Limited by Retrieve request budget AND Query request budget</li>\n  <li><strong>Aggregate endpoint:</strong> Limited by Aggregate request budget AND Query request budget</li>\n</ul>"
paths:
  /streams/{streamId}/records:
    post:
      tags:
      - Records
      summary: Ingest records into a stream
      description: '


        > **Required capabilities:** `streamRecordsAcl:WRITE` `dataModelsAcl:READ`


        Before a user can add records, all referenced schema elements (Spaces, Containers, Properties) must be defined/created in [Data Modeling](https://docs.cognite.com/cdf/dm)


        To add records, the user must have capabilities to access (read) the referenced containers as well as capabilities to access (write) the referenced record ```space```.


        Batches of records are ingested into a ```stream```.


        Under normal ingestion operation, and where the data ```stream``` does not contain any duplicated records,

        the record will be created, and the properties defined in each of the containers in the ```sources``` array will be populated.


        For immutable streams a duplicate record is defined as one which is being written to the same ```space```,

        which uses the same container definitions in the ```sources``` array,

        and all the properties (names and values) are the same.


        For immutable streams under most circumstances, when duplicate records are encountered during ingestion, the duplicate is discarded.

        However there are rare occasions when certain internal database operations occur, a duplicate may be stored.


        For mutable streams duplicated record identifiers (```space``` + ```externalId```) are not allowed

        and a request which tries to create a record with existing identifier will be rejected.


        **Note:** The maximum total request size is 10MB.

        '
      operationId: ingestRecords
      parameters:
      - $ref: '#/components/parameters/StreamId'
      requestBody:
        description: 'Records to ingest into a stream.

          '
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IngestRecordsRequest'
        required: true
      x-capability:
      - streamRecordsAcl:WRITE
      - dataModelsAcl:READ
      responses:
        '202':
          $ref: '#/components/responses/RecordsIngestResponse'
        '400':
          $ref: '#/components/responses/ErrorResponse'
        '409':
          description: 'Some mutable records with the specified `space` and `externalId` already exist in the stream.

            But some records might have been created successfully.

            Which records were successfully created and which were rejected with a conflict can be understood from the response content.


            **Note:** the error may appear due to some HTTP request retries (in intermediate components like SDK, Load balancers, Application Gateway, etc),

            so better to check which records are in the stream when you receive this error.

            `.../records/filter` or `.../records/sync` endpoints with a filter by `space` and `externalId` can be used to check the stored state of the conflicting records.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordsPartialSuccessResponse'
        '422':
          description: 'Some mutable record identifiers (`space` and `externalId`) are duplicated in the request.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnprocessableRecords'
        '500':
          description: 'If at least one record was not ingested due to an internal error, and all other errors in the `failed` list were non-retryable,

            this error code will be returned.


            **Note:** Record operations are not transactional. This means that during batch ingestion,

            some records may be created successfully even if the creation of others fails.

            The response body indicates which records were successfully created and which were not.


            An internal server error usually indicates an issue that requires investigation. A simple retry might not help,

            but a few retries could be a reasonable approach.


            **Note:** If you choose to retry on a 500 error, it is recommended to retry only the failed records rather than the entire request.

            For mutable streams this helps avoid receiving 409 status codes records that were already successfully created in a previous attempt.

            For immutable streams, this helps prevent accidental duplicate records from appearing in the stream (in rare cases when the deduplication mechanism fails).

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordsPartialSuccessResponse'
        '503':
          description: 'If at least one record was not ingested due to the service being temporarily unavailable,

            this error code will be returned.


            **Note:** Record operations are not transactional. This means that during batch ingestion, some records may be created successfully

            even if the creation of others fails. The response body indicates which records were successfully created and which were not.


            A "service temporarily unavailable" error usually indicates a temporary issue, and several retries may help complete the record creation.


            **Note:** It is recommended to retry ingestion of only the failed records rather than the entire request.

            For mutable streams, this helps avoid receiving 409 status codes for records that were already successfully created in a previous attempt.

            For immutable streams, this helps prevent accidental duplicate records from appearing in the stream (in rare cases when the deduplication mechanism fails).

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordsPartialSuccessResponse'
  /streams/{streamId}/records/upsert:
    post:
      tags:
      - Records
      summary: Upsert (create or update) records into a stream
      description: '


        > **Required capabilities:** `streamRecordsAcl:WRITE` `dataModelsAcl:READ`


        **Note:** This endpoint is only available for mutable streams.


        Before a user can upsert records, all referenced schema elements (Spaces, Containers, Properties) must be defined/created in [Data Modeling](https://docs.cognite.com/cdf/dm).


        To upsert records, the user must have capabilities to access (read) the referenced containers as well as capabilities to access (write) the referenced record ```space```.


        Batches of records are ingested or updated into a ```stream```.


        Under normal upsert operation, the record will be created or updated, and the properties defined in each of the containers in the ```sources``` array will be populated.


        If record identifiers (```space``` + ```externalId```) are already in the stream, records are fully updated (no partial updates for this endpoint).

        Otherwise, records are created.


        **Note:** The maximum total request size is 10MB.

        '
      operationId: upsertRecords
      parameters:
      - $ref: '#/components/parameters/StreamId'
      requestBody:
        description: 'Records to upsert into a stream.

          '
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IngestRecordsRequest'
        required: true
      x-capability:
      - streamRecordsAcl:WRITE
      - dataModelsAcl:READ
      responses:
        '202':
          $ref: '#/components/responses/RecordsIngestResponse'
        '400':
          $ref: '#/components/responses/ErrorResponse'
        '409':
          description: 'Some records with the specified `space` and `externalId` are being concurrently modified by this and other requests.

            But some records might have been created or updated successfully.

            Which records were successfully upserted and which were rejected with a conflict can be understood from the response content.


            **Note:** better to check which records are in the stream when you receive this error.

            `.../records/filter` or `.../records/sync` endpoints with a filter by `space` and `externalId` can be used

            to check the stored state of the conflicting records.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordsPartialSuccessResponse'
        '422':
          description: 'Some record identifiers (`space` and `externalId`) are duplicated in the request or attempt to modify records in an immutable stream.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnprocessableRecords'
        '500':
          description: 'If at least one record was not upserted due to an internal error, and all other errors in the `failed` list were non-retryable,

            this error code will be returned.


            **Note:** Record operations are not transactional. This means that during batch upsert,

            some records may be created/updated successfully even if the creation/updating of others fails.

            The response body indicates which records were successfully upserted and which were not.


            An internal server error usually indicates an issue that requires investigation. A simple retry might not help,

            but a few retries could be a reasonable approach.


            **Note:** If you choose to retry on a 500 error, it is recommended to retry only the failed records rather than the entire request.

            This helps avoid receiving 409 status codes or overriding records to outdated state (if multiple threads update records in your app).

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordsPartialSuccessResponse'
        '503':
          description: 'If at least one record was not upserted due to the service being temporarily unavailable,

            this error code will be returned.


            **Note:** Record operations are not transactional. This means that during batch upsert, some records may be created/updated successfully

            even if the creation/updating of others fails. The response body indicates which records were successfully upserted and which were not.


            A "service temporarily unavailable" error usually indicates a temporary issue, and several retries may help complete the record upserting.


            **Note:** It is recommended to retry only the failed records rather than the entire request.

            This helps avoid receiving 409 status codes or overriding records to outdated state (if multiple threads update records in your app).

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordsPartialSuccessResponse'
  /streams/{streamId}/records/delete:
    post:
      tags:
      - Records
      summary: Delete records from a stream
      description: '


        > **Required capabilities:** `streamRecordsAcl:WRITE`


        **Note:** This endpoint is only available for mutable streams.


        To delete records, the user must have capabilities to access (write to) the referenced record ```space```.


        Batches of records are deleted from a ```stream``` with implicit `ignoreUnknownIds=true` semantic.


        The record operations are eventually consistent,

        but under normal conditions deleted records stop being returned by other endpoints within a few seconds.

        Sync endpoint is returning a "tombstone" record (which only has a few top level fields and a deleted status)

        for at least 3 days since deleting the actual record.

        '
      operationId: deleteRecords
      parameters:
      - $ref: '#/components/parameters/StreamId'
      requestBody:
        description: 'Records to delete from a stream.

          '
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DeleteRecordsRequest'
        required: true
      x-capability:
      - streamRecordsAcl:WRITE
      responses:
        '200':
          $ref: '#/components/responses/RecordsDeleteResponse'
        '400':
          $ref: '#/components/responses/ErrorResponse'
        '422':
          description: 'Some record identifiers (`space` and `externalId`) are duplicated in the request or attempt to delete records from an immutable stream.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnprocessableRecords'
        '500':
          description: 'If at least one record was not deleted due to an internal error, and all other errors in the `failed` list were non-retryable,

            this error code will be returned.


            **Note:** Record operations are not transactional. This means that during batch delete,

            some records may be deleted successfully even if the deletion of others fails.

            The response body indicates which records were successfully deleted and which were not.


            An internal server error usually indicates an issue that requires investigation. A simple retry might not help,

            but a few retries could be a reasonable approach.


            **Note:** If you choose to retry on a 500 error, it is recommended to retry only the failed records rather than the entire request.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordsPartialSuccessResponse'
        '503':
          description: 'If at least one record was not deleted due to the service being temporarily unavailable,

            this error code will be returned.


            **Note:** Record operations are not transactional. This means that during batch delete, some records may be deleted successfully

            even if the deletion of others fails. The response body indicates which records were successfully deleted and which were not.


            A "service temporarily unavailable" error usually indicates a temporary issue, and several retries may help complete the records deletion.


            **Note:** It is recommended to retry deletion of only the failed records rather than the entire request.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordsPartialSuccessResponse'
  /streams/{streamId}/records/filter:
    post:
      tags:
      - Records
      summary: Retrieve records from a stream
      description: '


        > **Required capabilities:** `streamRecordsAcl:READ` `dataModelsAcl:READ`


        Filter the records from the ```stream```.

        '
      operationId: filterRecords
      parameters:
      - $ref: '#/components/parameters/StreamId'
      requestBody:
        description: 'Filter records based on the last updated time, on the space and on container(s) properties.

          The response supports custom sorting. Otherwise, the records in the response are sorted by last updated time.

          '
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FilterRecordsRequest'
        required: true
      x-capability:
      - streamRecordsAcl:READ
      - dataModelsAcl:READ
      responses:
        '200':
          $ref: '#/components/responses/RecordsFilterResponse'
        '400':
          $ref: '#/components/responses/ErrorResponse'
  /streams/{streamId}/records/aggregate:
    post:
      tags:
      - Records
      summary: Aggregate records data from a stream
      description: "\n\n> **Required capabilities:** `streamRecordsAcl:READ` `dataModelsAcl:READ`\n\nAggregate data for records from the ```stream```.\n\nYou can use an optional filter specification to limit the results.\n\nThe Records API supports three main groups of aggregates:\n\n*Metric aggregates*: ```sum```, ```min```, ```max```, ```count```, etc.\n\n*Bucket aggregates* (result records are aggregated into groups (buckets) â\x80\x94 similar to the Data Model Instances ```groupBy``` concept):\n  ```uniqueValues``` (group by property values), ```timeHistogram``` (group by date/time ranges), ```filters``` (group by filter criteria), etc.\n\n*Pipeline aggregates*: ```movingFunction```.\n**Note:** The pipeline aggregate applies to the results of another histogram aggregate.\n  It applies to metrics (such as count, min, max, sum, etc.), not to the records in the parent aggregate buckets.\n  This differs from sub-aggregates, which apply directly to records within each bucket.\n\nEvery aggregate request can contain multiple aggregate entries.\nEvery bucket aggregate can contain multiple sub-aggregates (of any type), which are applied to records in each bucket of the parent aggregate.\n\n<u>Example:</u>\n\nImagine there is paddle-tennis players `game_statistics` container with model:\n```\n{\n  game_id: Long,\n  game_time: Instant,\n  player

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