curl --request POST \
--url https://{cluster}.cognitedata.com/api/v1/projects/{project}/streams/{streamId}/records/aggregate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"aggregates": {
"my_avg_aggregate1": {
"avg": {
"property": [
"mySpace",
"myContainer",
"manufacturer"
]
}
},
"my_terms_aggregate2": {
"uniqueValues": {
"property": [
"mySpace",
"myContainer",
"manufacturer"
],
"aggregates": {
"my_sub_aggregate1": {
"min": {
"property": [
"mySpace",
"myContainer",
"price"
]
}
},
"my_sub_aggregate2": {
"max": {
"property": [
"mySpace",
"myContainer",
"price"
]
}
},
"my_sub_aggregate3": {
"uniqueValues": {
"property": [
"mySpace",
"myContainer",
"region"
]
}
}
}
}
}
},
"lastUpdatedTime": {
"gt": 1705341600000,
"lt": "2030-05-15T18:00:00.00Z"
},
"filter": {
"and": [
{
"containsAll": {
"property": [
"mySpace",
"myContainer",
"myProperty"
],
"values": [
10011,
10012
]
}
},
{
"range": {
"property": [
"my_space",
"my_container",
"my_weight"
],
"gte": 0
}
}
]
}
}
'{
"aggregates": {
"my_avg_aggregate1": {
"avg": 42
},
"my_terms_aggregate2": {
"uniqueValueBuckets": [
{
"value": "Cognite",
"count": 42,
"aggregates": {
"my_sub_aggregate1": {
"min": 13
},
"my_sub_aggregate2": {
"max": 69
},
"my_sub_aggregate3": {
"uniqueValueBuckets": [
{
"value": "us1",
"count": 42
},
{
"value": "ie1",
"count": 7
}
]
}
}
},
{
"value": "AkerBP",
"count": 21,
"aggregates": {
"my_sub_aggregate1": {
"min": 99
},
"my_sub_aggregate2": {
"max": 999
},
"my_sub_aggregate3": {
"uniqueValueBuckets": [
{
"value": "us1",
"count": 11
}
]
}
}
}
]
}
}
}Required capabilities:
StreamRecordsAcl:READDataModelsAcl:READ
Aggregate data for records from the stream.
You can use an optional filter specification to limit the results.
The Records API supports three main groups of aggregates:
Metric aggregates: sum, min, max, count, etc.
Bucket aggregates (result records are aggregated into groups (buckets) — similar to the Data Model Instances groupBy concept):
uniqueValues (group by property values), timeHistogram (group by date/time ranges), filters (group by filter criteria), etc.
Pipeline aggregates: movingFunction.
Note: The pipeline aggregate applies to the results of another histogram aggregate.
It applies to metrics (such as count, min, max, sum, etc.), not to the records in the parent aggregate buckets.
This differs from sub-aggregates, which apply directly to records within each bucket.
Every aggregate request can contain multiple aggregate entries. Every bucket aggregate can contain multiple sub-aggregates (of any type), which are applied to records in each bucket of the parent aggregate.
Example:Imagine there is paddle-tennis players game_statistics container with model:
{
game_id: Long,
game_time: Instant,
player_name: String,
points_scored: Int,
...
}
To get the following data:
for each day
calculate average number of points scored by players in all games on that day
and for each player
calculate the total number of points scored by the player in all games they participated in on that day
and find the max number of points scored by the player in all games they participated in on that day
and find the max number of points scored by players in all games they participated in during the entire search period.
Use aggregates like these (meta language):
timeHistogram(daily, game_time) // group by (form buckets) 1-day range based on `game_time` property values
avg(points_scored) // inside every day group calculate average value in `points_scored` property
uniqueValues(player_name) // inside every day group group by (form buckets) player names
sum(points_scored) // inside every player group which is inside every day group calculate the sum of points scored
max(points_scored) // inside every player group which is inside every day group find the maximum of points scored
max(points_scored) // find the maximum number of points scored across all statistic records (without any grouping)
Or the same in Cognite Records Aggregates DSL (Json):
{
"my_groups_by_1d_range": {
"timeHistogram": {
"calendarInterval": "1d",
"property": [ "paddle", "game_statistics", "game_time" ],
"aggregates": {
"my_groups_by_player_name": {
"uniqueValues": {
"property": [ "paddle", "game_statistics", "player_name" ],
"aggregates": {
"my_player_daily_scores_sum": {
"sum": { "property": [ "paddle", "game_statistics", "points_scored" ] }
},
"my_player_daily_scores_maximum": {
"max": { "property": [ "paddle", "game_statistics", "points_scored" ] }
}
}
}
},
"my_daily_scores_average": {
"avg": { "property": [ "paddle", "game_statistics", "points_scored" ] }
}
}
}
},
"my_scores_maximum_across_all_games": {
"max": { "property": [ "paddle", "game_statistics", "points_scored" ] }
}
}
and the response would be
{
"my_groups_by_1d_range": {
"timeHistogramBuckets": [
{
"count": 13
"intervalStart": "2025-05-25T00:00:00Z",
"aggregates": {
"my_groups_by_player_name": {
"uniqueValueBuckets": [
{
"count": 3
"value": "Vasya Rogov",
"aggregates": {
"my_player_daily_scores_sum": {
"sum": 57
},
"my_player_daily_scores_maximum": {
"max": 25
}
}
},
{
"count": 5
"value": "Vinni Pooh",
"aggregates": {
"my_player_daily_scores_sum": {
"sum": 53
},
"my_player_daily_scores_maximum": {
"max": 21
}
}
},
...
]
},
"my_daily_scores_average": {
"avg": 33
}
}
},
{
"count": 7
"intervalStart": "2025-05-26T00:00:00Z",
"aggregates": {
"my_groups_by_player_name": {
"uniqueValueBuckets": [
{
"count": 1
"value": "Vasya Rogov",
"aggregates": {
"my_player_daily_scores_sum": {
"sum": 24
},
"my_player_daily_scores_maximum": {
"max": 24
}
}
},
{
"count": 2
"value": "Pyatochok",
"aggregates": {
"my_player_daily_scores_sum": {
"sum": 42
},
"my_player_daily_scores_maximum": {
"max": 23
}
}
},
...
]
},
"my_daily_scores_average": {
"avg": 22
}
}
},
...
]
},
"my_scores_maximum_across_all_games": {
"max": 42
}
}
curl --request POST \
--url https://{cluster}.cognitedata.com/api/v1/projects/{project}/streams/{streamId}/records/aggregate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"aggregates": {
"my_avg_aggregate1": {
"avg": {
"property": [
"mySpace",
"myContainer",
"manufacturer"
]
}
},
"my_terms_aggregate2": {
"uniqueValues": {
"property": [
"mySpace",
"myContainer",
"manufacturer"
],
"aggregates": {
"my_sub_aggregate1": {
"min": {
"property": [
"mySpace",
"myContainer",
"price"
]
}
},
"my_sub_aggregate2": {
"max": {
"property": [
"mySpace",
"myContainer",
"price"
]
}
},
"my_sub_aggregate3": {
"uniqueValues": {
"property": [
"mySpace",
"myContainer",
"region"
]
}
}
}
}
}
},
"lastUpdatedTime": {
"gt": 1705341600000,
"lt": "2030-05-15T18:00:00.00Z"
},
"filter": {
"and": [
{
"containsAll": {
"property": [
"mySpace",
"myContainer",
"myProperty"
],
"values": [
10011,
10012
]
}
},
{
"range": {
"property": [
"my_space",
"my_container",
"my_weight"
],
"gte": 0
}
}
]
}
}
'{
"aggregates": {
"my_avg_aggregate1": {
"avg": 42
},
"my_terms_aggregate2": {
"uniqueValueBuckets": [
{
"value": "Cognite",
"count": 42,
"aggregates": {
"my_sub_aggregate1": {
"min": 13
},
"my_sub_aggregate2": {
"max": 69
},
"my_sub_aggregate3": {
"uniqueValueBuckets": [
{
"value": "us1",
"count": 42
},
{
"value": "ie1",
"count": 7
}
]
}
}
},
{
"value": "AkerBP",
"count": 21,
"aggregates": {
"my_sub_aggregate1": {
"min": 99
},
"my_sub_aggregate2": {
"max": 999
},
"my_sub_aggregate3": {
"uniqueValueBuckets": [
{
"value": "us1",
"count": 11
}
]
}
}
}
]
}
}
}Access token issued by the CDF project's configured identity provider. Access token must be an OpenID Connect token, and the project must be configured to accept OpenID Connect tokens. Use a header key of 'Authorization' with a value of 'Bearer $accesstoken'. The token can be obtained through any flow supported by the identity provider.
An identifier of the stream where the records are stored.
1 - 100^[a-z]([a-z0-9_-]{0,98}[a-z0-9])?$"test1"
Aggregation specification.
Defines an aggregation request. This will let you aggregate supported data types. The request supports filters, and allows optional search matching.
A dictionary of requested aggregates with client defined names/identifiers.
Example:
{
"my_aggr_1": {
"min": {"property": ["space1", "container1", "property1"]}
},
"my_aggr_2": {
"uniqueValues": {
"property": ["space1", "container2", "property1"],
"aggregates": {
"my_sub_aggr": {
"avg": {"property": ["space2", "container1", "property3"]}
}
}
}
},
}Max number of (sub-)aggregate trees on a level is 5, Max aggregate tree depth is 5. Max number of aggregates in the forest is 16.
Show child attributes
{
"my_avg_aggregate1": {
"avg": {
"property": ["mySpace", "myContainer", "manufacturer"]
}
},
"my_terms_aggregate2": {
"uniqueValues": {
"property": ["mySpace", "myContainer", "manufacturer"],
"aggregates": {
"my_sub_aggregate1": {
"min": {
"property": ["mySpace", "myContainer", "price"]
}
},
"my_sub_aggregate2": {
"max": {
"property": ["mySpace", "myContainer", "price"]
}
},
"my_sub_aggregate3": {
"uniqueValues": {
"property": ["mySpace", "myContainer", "region"]
}
}
}
}
}
}Matches records with the last updated time within the provided range. This attribute is mandatory for immutable streams but it's optional for mutable streams. The maximum time interval that can be defined by the attribute is limited by the stream settings. If more data needs to be queried than allowed by the stream settings, it should be done with multiple requests. For example, if stream allows querying up to 1 month of data, but a quarterly report is needed, the solution is to make 3 requests, one for each month, and then aggregate the responses.
The range must include at least a left (gt or gte) bound.
It is not allowed to specify two upper or lower bounds, e.g. gte and gt, in the same filter.
gte: Greater than or equal to.
gt: Greater than.
lte: Less than or equal to.
lt: Less than.
Note: lastUpdatedTime is a CDF generated timestamp that marks the moment a record is stored in the API
The range bounds can be specified in two formats:
2030-05-15T18:00:00.00Z).1705341600000).Show child attributes
{
"gt": 1705341600000,
"lt": "2030-05-15T18:00:00.00Z"
}Build a new query by combining other queries, using boolean operators. We support the and, or, and
not boolean operators.
Show child attributes
{
"and": [
{
"containsAll": {
"property": ["mySpace", "myContainer", "myProperty"],
"values": [10011, 10012]
}
},
{
"range": {
"property": ["my_space", "my_container", "my_weight"],
"gte": 0
}
}
]
}Aggregated query results.
A dictionary of the results for the requested aggregates mapped by the aggregates identifiers.
Example:
{
"my_aggr_1": {
"avg": 42
},
"my_aggr_2": {
"max": 69
},
}Show child attributes
{
"my_avg_aggregate1": { "avg": 42 },
"my_terms_aggregate2": {
"uniqueValueBuckets": [
{
"value": "Cognite",
"count": 42,
"aggregates": {
"my_sub_aggregate1": { "min": 13 },
"my_sub_aggregate2": { "max": 69 },
"my_sub_aggregate3": {
"uniqueValueBuckets": [
{ "value": "us1", "count": 42 },
{ "value": "ie1", "count": 7 }
]
}
}
},
{
"value": "AkerBP",
"count": 21,
"aggregates": {
"my_sub_aggregate1": { "min": 99 },
"my_sub_aggregate2": { "max": 999 },
"my_sub_aggregate3": {
"uniqueValueBuckets": [{ "value": "us1", "count": 11 }]
}
}
}
]
}
}Was this page helpful?