This tutorial explains when to use the grouped endpoint instead of the standard data endpoint, how to structure a grouped request, and how to read the series map in the response.
This tutorial builds on the Fetching a Metric with Postman, Filtering and Dimensions, and Time Granularity: Trend Analysis tutorials. You should have the CDQ Insights API collection in Postman.
Learning Goals
In this tutorial, you will learn how to:
- Decide when to use the grouped endpoint instead of the standard endpoint
- Structure a grouped request with
groupByandbreakdownBy - Read the
rowsandseriesmap in the grouped response - Apply filters, options, and multiple metrics on the grouped endpoint
So far all requests have gone to POST /analytics/rest/insights. That endpoint is optimised for trend analysis: you get one value per time bucket, per dimension combination, making it ideal for time-series charts and tracking change over time.
The grouped endpoint, POST /analytics/rest/insights/grouped, is optimised for snapshot views. It returns a cross-sectional breakdown at a point in time: one row per groupBy value, with each row containing a breakdown across a second dimension as a series map. There is no timeGranularity on the grouped endpoint; it always returns the latest value within the requested date range.
Think of it this way:
| Standard endpoint | Grouped endpoint | |
|---|---|---|
| Best for | Trend analysis, time-series charts | Snapshot tables, bar charts, dashboards |
| Returns | One result per date + dimension combination | One row per groupBy value, series map per breakdownBy value |
| Time granularity | Supported | Not supported |
The grouped endpoint has two query parameters in the URL, groupBy and breakdownBy, with the rest of the request in the JSON body as usual:
POST /analytics/rest/insights/grouped?groupBy=country&breakdownBy=dataSourceIdgroupBy: the primary dimension. Each unique value becomes a row in the response.breakdownBy: the secondary dimension. Each unique value becomes a key in the series map within each row.
Both must be dimensions that are valid for all metrics in the ids array. If either value is not a supported dimension for one of the requested metrics, the API returns a 400 Bad Request with a message listing the valid common dimensions.
dimensions is not a valid body parameter on the grouped endpoint. Unlike the standard endpoint, grouping and breakdown are controlled exclusively via the groupBy and breakdownBy URL parameters. Including dimensions in the request body will result in a 400 Bad Request.
Let's fetch validated records grouped by country, broken down by data source:
curl -i -X POST \
'https://api.cdq.com/analytics/rest/insights/grouped?groupBy=country&breakdownBy=dataSourceId' \
-H 'Content-Type: application/json' \
-H 'x-api-key: YOUR_API_KEY_HERE' \
-d '{
"ids": ["validated_records"],
"dateFrom": "2026-05-01",
"dateTo": "2026-05-31"
}'Note that groupBy and breakdownBy are part of the URL, not the request body. The response looks different from the standard endpoint:
{
"items": [
{
"insightId": "validated_records",
"rows": [
{
"country": "DE",
"series": {
"61a5d59b470c0332d08e609c": 3887,
"666865b75031e4693aa011f6": 131,
"6880d77bdf35c96310e3692d": 591
}
},
{
"country": "PL",
"series": {
"61a5d59b470c0332d08e609c": 12,
"666865b75031e4693aa011f6": 3346,
"6880d77bdf35c96310e3692d": 15
}
},
{
"country": "FR",
"series": {
"61a5d59b470c0332d08e609c": 815,
"666865b75031e4693aa011f6": 3,
"6880d77bdf35c96310e3692d": 274
}
}
]
}
]
}The response structure differs from the standard endpoint in a few ways:
insightIdinstead ofid: same value, different field name.rowsinstead ofresults: each row represents onegroupByvalue.- No
datefield: the grouped endpoint always returns the latest value within the date range. seriesmap: keys arebreakdownByvalues (in this case data source IDs), values are the metric values for that combination.
So for Germany (DE), the response tells you that data source 61a5d59b... has 3,887 validated records, 666865b7... has 131, and 6880d77b... has 591.
Data source IDs in the series map are the raw identifiers from your CDQ workspace. Cross-reference them with your data source configuration to map them to human-readable names.
Filters work the same way as on the standard endpoint: they narrow the data before the metric is calculated. Let's limit the response to a specific set of countries:
curl -i -X POST \
'https://api.cdq.com/analytics/rest/insights/grouped?groupBy=country&breakdownBy=dataSourceId' \
-H 'Content-Type: application/json' \
-H 'x-api-key: YOUR_API_KEY_HERE' \
-d '{
"ids": ["validated_records"],
"dateFrom": "2026-05-01",
"dateTo": "2026-05-31",
"filters": [
{
"field": "country",
"operator": "IN",
"values": ["DE", "PL", "FR"]
}
]
}'The response will only contain rows for DE, PL, and FR.
The grouped endpoint supports the same options as the standard endpoint. The most useful for grouped views is topNCountriesByBusinessPartnerCount, which limits the response to the top N countries by business partner volume, avoiding an overwhelming number of rows when your workspace spans many countries:
curl -i -X POST \
'https://api.cdq.com/analytics/rest/insights/grouped?groupBy=country&breakdownBy=dataSourceId' \
-H 'Content-Type: application/json' \
-H 'x-api-key: YOUR_API_KEY_HERE' \
-d '{
"ids": ["validated_records"],
"dateFrom": "2026-05-01",
"dateTo": "2026-05-31",
"options": {
"topNCountriesByBusinessPartnerCount": 10
}
}'This returns rows only for the 10 countries with the highest business partner count in your workspace: a focused view that works well for dashboard widgets.
Like the standard endpoint, you can request multiple metrics in a single call. Each metric gets its own item in the response:
curl -i -X POST \
'https://api.cdq.com/analytics/rest/insights/grouped?groupBy=country&breakdownBy=dataSourceId' \
-H 'Content-Type: application/json' \
-H 'x-api-key: YOUR_API_KEY_HERE' \
-d '{
"ids": [
"validated_records",
"data_quality_ratio",
"defective_records_ratio",
"erroneous_records_ratio",
"violated_data_quality_categories_count"
],
"dateFrom": "2026-05-01",
"dateTo": "2026-05-31",
"options": {
"topNCountriesByBusinessPartnerCount": 10
}
}'There are three rules to follow when combining multiple metrics in a single request:
groupByandbreakdownBymust be valid dimensions for all requested metrics. If a dimension is not supported by one of the metrics, the API returns a400 Bad Requestlisting the valid common dimensions across all requested metrics.- Options must be supported by all requested metrics. Each metric defines which options it accepts in the
optionsfield of the catalogue. If you include an option that is not supported by even one metric in theidsarray, the API rejects the entire request. For example,topNResultsis only supported bybusiness_partners_count, so including it alongsidevalidated_recordswill fail. Always check theoptionsfield in the catalogue for each metric before combining them. - Filters must use fields that are valid for all requested metrics. Check
filtersSupportedin the catalogue for each metric.
Metrics within the same category are the safest combination: they tend to share the same dimensions, filters, and options. Mixing metrics across categories requires careful cross-checking of the catalogue.
Use the grouped endpoint when you want to answer questions like:
- Which countries have the most validated records, and how are they distributed across data sources?
- What is the data quality ratio per country, broken down by data source, as a table?
- Which data sources are contributing the most business partners in each country?
Use the standard endpoint when you want to answer questions like:
- How has my data quality ratio changed over the last six months?
- Is Poland's data quality improving week on week?
- What was the AML open/closed ratio on a specific date?
Save each request in your CDQ Insights API collection:
validated records (grouped by country, breakdown by data source)validated records (grouped, filtered to top 10 countries)validated records + data quality ratio (grouped, multi-metric)
We are constantly working on providing an outstanding user experience with our products. Please share your opinion about this tutorial!