{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["admonition","partial"]},"type":"markdown"},"seo":{"title":"CDQ Insights API - The Grouped Endpoint - Snapshot Views","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"cdq-insights-api---the-grouped-endpoint---snapshot-views","__idx":0},"children":["CDQ Insights API - The Grouped Endpoint - Snapshot Views"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"overview","__idx":1},"children":["Overview"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["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."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This tutorial builds on the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Fetching a Metric with Postman"]},", ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Filtering and Dimensions"]},", and ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Time Granularity: Trend Analysis"]}," tutorials. You should have the CDQ Insights API collection in Postman."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Learning Goals"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["In this tutorial, you will learn how to:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Decide when to use the grouped endpoint instead of the standard endpoint"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Structure a grouped request with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["groupBy"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["breakdownBy"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Read the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["rows"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["series"]}," map in the grouped response"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Apply filters, options, and multiple metrics on the grouped endpoint"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"two-endpoints-two-purposes","__idx":2},"children":["Two endpoints, two purposes"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["So far all requests have gone to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["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."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The grouped endpoint, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /analytics/rest/insights/grouped"]},", is optimised for snapshot views. It returns a cross-sectional breakdown at a point in time: one row per ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["groupBy"]}," value, with each row containing a breakdown across a second dimension as a series map. There is no ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["timeGranularity"]}," on the grouped endpoint; it always returns the latest value within the requested date range."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Think of it this way:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":""},"children":[]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Standard endpoint"},"children":["Standard endpoint"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Grouped endpoint"},"children":["Grouped endpoint"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Best for"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Trend analysis, time-series charts"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Snapshot tables, bar charts, dashboards"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Returns"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["One result per date + dimension combination"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["One row per ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["groupBy"]}," value, series map per ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["breakdownBy"]}," value"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Time granularity"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Supported"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Not supported"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"the-request-format","__idx":3},"children":["The request format"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The grouped endpoint has two query parameters in the URL, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["groupBy"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["breakdownBy"]},", with the rest of the request in the JSON body as usual:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"POST /analytics/rest/insights/grouped?groupBy=country&breakdownBy=dataSourceId\n"},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["groupBy"]},": the primary dimension. Each unique value becomes a row in the response."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["breakdownBy"]},": the secondary dimension. Each unique value becomes a key in the series map within each row."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Both must be dimensions that are valid for all metrics in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ids"]}," array. If either value is not a supported dimension for one of the requested metrics, the API returns a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["400 Bad Request"]}," with a message listing the valid common dimensions."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dimensions"]}," is not a valid body parameter on the grouped endpoint. Unlike the standard endpoint, grouping and breakdown are controlled exclusively via the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["groupBy"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["breakdownBy"]}," URL parameters. Including ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dimensions"]}," in the request body will result in a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["400 Bad Request"]},"."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-1-your-first-grouped-request","__idx":4},"children":["Step 1: Your first grouped request"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Let's fetch validated records grouped by country, broken down by data source:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl -i -X POST \\\n  'https://api.cdq.com/analytics/rest/insights/grouped?groupBy=country&breakdownBy=dataSourceId' \\\n  -H 'Content-Type: application/json' \\\n  -H 'x-api-key: YOUR_API_KEY_HERE' \\\n  -d '{\n    \"ids\": [\"validated_records\"],\n    \"dateFrom\": \"2026-05-01\",\n    \"dateTo\": \"2026-05-31\"\n  }'\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Note that ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["groupBy"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["breakdownBy"]}," are part of the URL, not the request body. The response looks different from the standard endpoint:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"items\": [\n    {\n      \"insightId\": \"validated_records\",\n      \"rows\": [\n        {\n          \"country\": \"DE\",\n          \"series\": {\n            \"61a5d59b470c0332d08e609c\": 3887,\n            \"666865b75031e4693aa011f6\": 131,\n            \"6880d77bdf35c96310e3692d\": 591\n          }\n        },\n        {\n          \"country\": \"PL\",\n          \"series\": {\n            \"61a5d59b470c0332d08e609c\": 12,\n            \"666865b75031e4693aa011f6\": 3346,\n            \"6880d77bdf35c96310e3692d\": 15\n          }\n        },\n        {\n          \"country\": \"FR\",\n          \"series\": {\n            \"61a5d59b470c0332d08e609c\": 815,\n            \"666865b75031e4693aa011f6\": 3,\n            \"6880d77bdf35c96310e3692d\": 274\n          }\n        }\n      ]\n    }\n  ]\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"reading-the-grouped-response","__idx":5},"children":["Reading the grouped response"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The response structure differs from the standard endpoint in a few ways:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["insightId"]}," instead of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["id"]},": same value, different field name."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["rows"]}," instead of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["results"]},": each row represents one ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["groupBy"]}," value."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["No ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["date"]}," field: the grouped endpoint always returns the latest value within the date range."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["series"]}," map: keys are ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["breakdownBy"]}," values (in this case data source IDs), values are the metric values for that combination."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["So for Germany (DE), the response tells you that data source ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["61a5d59b..."]}," has 3,887 validated records, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["666865b7..."]}," has 131, and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["6880d77b..."]}," has 591."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["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."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-2-filtering-the-grouped-response","__idx":6},"children":["Step 2: Filtering the grouped response"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["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:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl -i -X POST \\\n  'https://api.cdq.com/analytics/rest/insights/grouped?groupBy=country&breakdownBy=dataSourceId' \\\n  -H 'Content-Type: application/json' \\\n  -H 'x-api-key: YOUR_API_KEY_HERE' \\\n  -d '{\n    \"ids\": [\"validated_records\"],\n    \"dateFrom\": \"2026-05-01\",\n    \"dateTo\": \"2026-05-31\",\n    \"filters\": [\n      {\n        \"field\": \"country\",\n        \"operator\": \"IN\",\n        \"values\": [\"DE\", \"PL\", \"FR\"]\n      }\n    ]\n  }'\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The response will only contain rows for DE, PL, and FR."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-3-using-options","__idx":7},"children":["Step 3: Using options"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The grouped endpoint supports the same options as the standard endpoint. The most useful for grouped views is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["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:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl -i -X POST \\\n  'https://api.cdq.com/analytics/rest/insights/grouped?groupBy=country&breakdownBy=dataSourceId' \\\n  -H 'Content-Type: application/json' \\\n  -H 'x-api-key: YOUR_API_KEY_HERE' \\\n  -d '{\n    \"ids\": [\"validated_records\"],\n    \"dateFrom\": \"2026-05-01\",\n    \"dateTo\": \"2026-05-31\",\n    \"options\": {\n      \"topNCountriesByBusinessPartnerCount\": 10\n    }\n  }'\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["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."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-4-requesting-multiple-metrics","__idx":8},"children":["Step 4: Requesting multiple metrics"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Like the standard endpoint, you can request multiple metrics in a single call. Each metric gets its own item in the response:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl -i -X POST \\\n  'https://api.cdq.com/analytics/rest/insights/grouped?groupBy=country&breakdownBy=dataSourceId' \\\n  -H 'Content-Type: application/json' \\\n  -H 'x-api-key: YOUR_API_KEY_HERE' \\\n  -d '{\n    \"ids\": [\n      \"validated_records\",\n      \"data_quality_ratio\",\n      \"defective_records_ratio\",\n      \"erroneous_records_ratio\",\n      \"violated_data_quality_categories_count\"\n    ],\n    \"dateFrom\": \"2026-05-01\",\n    \"dateTo\": \"2026-05-31\",\n    \"options\": {\n      \"topNCountriesByBusinessPartnerCount\": 10\n    }\n  }'\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["There are three rules to follow when combining multiple metrics in a single request:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["groupBy"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["breakdownBy"]}," must be valid dimensions for all requested metrics. If a dimension is not supported by one of the metrics, the API returns a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["400 Bad Request"]}," listing the valid common dimensions across all requested metrics."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Options must be supported by all requested metrics. Each metric defines which options it accepts in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["options"]}," field of the catalogue. If you include an option that is not supported by even one metric in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ids"]}," array, the API rejects the entire request. For example, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["topNResults"]}," is only supported by ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["business_partners_count"]},", so including it alongside ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["validated_records"]}," will fail. Always check the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["options"]}," field in the catalogue for each metric before combining them."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Filters must use fields that are valid for all requested metrics. Check ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["filtersSupported"]}," in the catalogue for each metric."]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["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."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"when-to-use-grouped-vs-standard","__idx":9},"children":["When to use grouped vs standard"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["grouped endpoint"]}," when you want to answer questions like:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Which countries have the most validated records, and how are they distributed across data sources?"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["What is the data quality ratio per country, broken down by data source, as a table?"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Which data sources are contributing the most business partners in each country?"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["standard endpoint"]}," when you want to answer questions like:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["How has my data quality ratio changed over the last six months?"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Is Poland's data quality improving week on week?"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["What was the AML open/closed ratio on a specific date?"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"saving-your-requests-in-postman","__idx":10},"children":["Saving your requests in Postman"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Save each request in your CDQ Insights API collection:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["validated records (grouped by country, breakdown by data source)"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["validated records (grouped, filtered to top 10 countries)"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["validated records + data quality ratio (grouped, multi-metric)"]}]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"your-opinion-matters","__idx":11},"children":["Your opinion matters!"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["We are constantly working on providing an outstanding user experience with our products. Please share your opinion about this tutorial!"]}]},"headings":[{"value":"CDQ Insights API - The Grouped Endpoint - Snapshot Views","id":"cdq-insights-api---the-grouped-endpoint---snapshot-views","depth":1},{"value":"Overview","id":"overview","depth":2},{"value":"Two endpoints, two purposes","id":"two-endpoints-two-purposes","depth":2},{"value":"The request format","id":"the-request-format","depth":2},{"value":"Step 1: Your first grouped request","id":"step-1-your-first-grouped-request","depth":2},{"value":"Reading the grouped response","id":"reading-the-grouped-response","depth":2},{"value":"Step 2: Filtering the grouped response","id":"step-2-filtering-the-grouped-response","depth":2},{"value":"Step 3: Using options","id":"step-3-using-options","depth":2},{"value":"Step 4: Requesting multiple metrics","id":"step-4-requesting-multiple-metrics","depth":2},{"value":"When to use grouped vs standard","id":"when-to-use-grouped-vs-standard","depth":2},{"value":"Saving your requests in Postman","id":"saving-your-requests-in-postman","depth":2},{"value":"Your opinion matters!","id":"your-opinion-matters","depth":2}],"frontmatter":{"seo":{"title":"CDQ Insights API - The Grouped Endpoint - Snapshot Views"},"toc":{"enable":true},"edition":{"createdAt":"2026-06-09T00:00:00.000Z"}},"lastModified":"2026-06-09T12:40:14.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/documentation/_public/tutorials/insights/ins-grouped-endpoint-snapshot-views","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}