> ## Documentation Index
> Fetch the complete documentation index at: https://docs.endorlabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.endorlabs.com/feedback

```json
{
  "path": "/developers-api/rest-api/using-the-rest-api/grouping/index",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# Grouping

> Learn how to group results from the Endor Labs REST API.

export const YamlTable = ({children, data: propData, content}) => {
  const KV_RE = /^([A-Za-z][A-Za-z0-9_()/#\s-]+?):\s*(.+)$/;
  const INLINE_MD_RE = /(\[([^\]]+)\]\(([^)]+)\))|(`([^`]+)`)|(\*\*([^*]+)\*\*)|(\*([^*]+)\*)/g;
  const YES_RE = /^-yes-$/i;
  const NO_RE = /^-no-$/i;
  const LIMITED_RE = /^-(limited|partial)-$/i;
  const SIMPLE_TAG_RE = /(<br\s*\/?>)|(<p\s*\/?>)|(-note-)|(-warning-)/gi;
  const tryParseKV = trimmed => {
    const m = KV_RE.exec(trimmed);
    return m ? {
      key: m[1],
      value: m[2].trim()
    } : null;
  };
  const registerKey = (key, seenKeys, orderedKeys) => {
    if (!seenKeys.has(key)) {
      orderedKeys.push(key);
      seenKeys.add(key);
    }
  };
  const flushEntry = (currentEntry, entries) => {
    if (Object.keys(currentEntry).length > 0) entries.push(currentEntry);
  };
  const parseDashPrefixed = (lines, entries, orderedKeys, seenKeys) => {
    let currentEntry = {};
    let inEntry = false;
    for (const line of lines) {
      const trimmed = line.trim();
      if (trimmed.startsWith('- ')) {
        if (inEntry) entries.push(currentEntry);
        currentEntry = {};
        inEntry = true;
        const kv = tryParseKV(trimmed.substring(2).trim());
        if (kv) {
          registerKey(kv.key, seenKeys, orderedKeys);
          currentEntry[kv.key] = kv.value;
        }
      } else if (inEntry && trimmed !== '') {
        const kv = tryParseKV(trimmed);
        if (kv) {
          registerKey(kv.key, seenKeys, orderedKeys);
          currentEntry[kv.key] = kv.value;
        }
      }
    }
    flushEntry(currentEntry, entries);
  };
  const parseBlankSeparated = (lines, entries, orderedKeys, seenKeys) => {
    let currentEntry = {};
    let inEntry = false;
    for (const line of lines) {
      const trimmed = line.trim();
      if (trimmed === '') {
        if (inEntry) {
          flushEntry(currentEntry, entries);
          currentEntry = {};
          inEntry = false;
        }
        continue;
      }
      const kv = tryParseKV(trimmed);
      if (!kv) continue;
      const isNewEntry = !line.startsWith(' ') && !line.startsWith('\t');
      if (isNewEntry && inEntry && Object.keys(currentEntry).length > 0) {
        entries.push(currentEntry);
        currentEntry = {};
      }
      registerKey(kv.key, seenKeys, orderedKeys);
      currentEntry[kv.key] = kv.value;
      inEntry = true;
    }
    flushEntry(currentEntry, entries);
  };
  const normalizeEntries = (entries, orderedKeys) => entries.map(entry => {
    const filled = {};
    for (const key of orderedKeys) filled[key] = entry[key] || '';
    return filled;
  });
  const parseYamlTableContent = contentStr => {
    if (!contentStr) return [];
    const entries = [];
    const orderedKeys = [];
    const seenKeys = new Set();
    const lines = contentStr.split('\n');
    if (lines.some(line => line.trim().startsWith('- '))) {
      parseDashPrefixed(lines, entries, orderedKeys, seenKeys);
    } else {
      parseBlankSeparated(lines, entries, orderedKeys, seenKeys);
    }
    return normalizeEntries(entries, orderedKeys);
  };
  const processText = text => {
    if (!text) return text;
    const parts = [];
    let keyIndex = 0;
    let lastIndex = 0;
    let match;
    while ((match = INLINE_MD_RE.exec(text)) !== null) {
      if (match.index > lastIndex) parts.push(text.slice(lastIndex, match.index));
      if (match[1]) {
        parts.push(<a key={keyIndex++} href={match[3]}>{match[2]}</a>);
      } else if (match[4]) {
        parts.push(<code key={keyIndex++}>{match[5]}</code>);
      } else if (match[6]) {
        parts.push(<strong key={keyIndex++}>{match[7]}</strong>);
      } else if (match[8]) {
        parts.push(<em key={keyIndex++}>{match[9]}</em>);
      }
      lastIndex = match.index + match[0].length;
    }
    if (lastIndex < text.length) parts.push(text.slice(lastIndex));
    if (parts.length === 0) return text;
    const keyRef = {
      current: keyIndex
    };
    return expandHtmlTags(parts, keyRef);
  };
  const processBadges = text => {
    if (!text || typeof text !== 'string') return text;
    if (YES_RE.test(text)) return <span className="yt-badge-yes" role="img" aria-label="Supported" title="Supported">✓</span>;
    if (NO_RE.test(text)) return <span className="yt-badge-no" role="img" aria-label="Not supported" title="Not supported">✗</span>;
    if (LIMITED_RE.test(text)) return <span className="yt-badge-limited" role="img" aria-label="Partially supported" title="Partially supported">◐</span>;
    return processText(text);
  };
  const expandSimpleTags = (str, keyRef) => {
    const result = [];
    let last = 0;
    SIMPLE_TAG_RE.lastIndex = 0;
    let m;
    while ((m = SIMPLE_TAG_RE.exec(str)) !== null) {
      if (m.index > last) result.push(str.slice(last, m.index));
      if (m[1]) {
        result.push(<br key={keyRef.current++} />);
      } else if (m[2]) {
        result.push(<br key={keyRef.current++} />, <br key={keyRef.current++} />);
      } else if (m[3]) {
        result.push(<span key={keyRef.current++} className="yt-badge-note" style={{
          fontWeight: 600
        }}>Note: </span>);
      } else if (m[4]) {
        result.push(<span key={keyRef.current++} className="yt-badge-warning" style={{
          fontWeight: 600
        }}>Warning: </span>);
      }
      last = m.index + m[0].length;
    }
    if (last < str.length) result.push(str.slice(last));
    return result;
  };
  const expandHtmlTags = (chunks, keyRef) => {
    const out = [];
    for (const chunk of chunks) {
      if (typeof chunk === 'string') {
        out.push(...expandSimpleTags(chunk, keyRef));
      } else {
        out.push(chunk);
      }
    }
    return out;
  };
  const extractText = node => {
    if (node === null || node === undefined) return '';
    if (typeof node === 'string') return node;
    if (typeof node === 'number') return String(node);
    if (typeof node === 'boolean') return '';
    if (Array.isArray(node)) return node.map(extractText).join('');
    if (node && typeof node === 'object' && node.type) {
      const props = node.props || ({});
      if (typeof props.children === 'string') return props.children;
      if (props.children) return extractText(props.children);
      return '';
    }
    return String(node || '');
  };
  const [mounted, setMounted] = useState(false);
  useEffect(() => {
    setMounted(true);
  }, []);
  const data = useMemo(() => {
    if (propData) return propData;
    if (content && typeof content === 'string') return parseYamlTableContent(content);
    if (!children) return [];
    if (typeof children === 'string') return parseYamlTableContent(children);
    const childrenArray = Array.isArray(children) ? children : [children];
    return parseYamlTableContent(childrenArray.map(extractText).join('').trim());
  }, [children, propData, content]);
  const columns = useMemo(() => {
    if (!data || data.length === 0) return [];
    const firstRow = data[0];
    if (!firstRow || typeof firstRow !== 'object') return [];
    return Object.keys(firstRow);
  }, [data]);
  if (!mounted) return null;
  if (!data || data.length === 0) return null;
  const rowKey = row => columns.map(c => row[c] || '').join('|');
  return <table>
      <thead>
        <tr>
          {columns.map(col => <th key={col}>{col.replaceAll('_', ' ')}</th>)}
        </tr>
      </thead>
      <tbody>
        {data.map(row => <tr key={rowKey(row)}>
            {columns.map(col => <td key={col}>{processBadges(row[col])}</td>)}
          </tr>)}
      </tbody>
    </table>;
};

There are many scenarios where it is useful to group the objects returned by the Endor Labs REST API in different ways.
Like [filter keys](/developers-api/rest-api/using-the-rest-api/filters#keys), a group-aggregation-paths key specifies the field, or fields, by which to group the objects, using a dot-delimited path.
For example, the following request returns the count of findings for each severity level:

<Tabs>
  <Tab title="endorctl">
    ```bash theme={null}
    endorctl api list --resource Finding \
      --filter "spec.finding_categories contains FINDING_CATEGORY_VULNERABILITY" \
      --group-aggregation-paths "spec.level" \
      --timeout 60s
    ```
  </Tab>

  <Tab title="curl">
    ```bash theme={null}
    curl --get \
      --header "Authorization: Bearer $ENDOR_TOKEN" \
      --header "Request-Timeout: 60" \
      --data-urlencode "list_parameters.filter=spec.finding_categories contains FINDING_CATEGORY_VULNERABILITY" \
      --data-urlencode "list_parameters.group.aggregation_paths=spec.level" \
      https://api.endorlabs.com/v1/namespaces/$ENDOR_NAMESPACE/findings \
      | jq '.'
    ```
  </Tab>

  <Tab title="HTTP">
    ```bash theme={null}
    @baseUrl = https://api.endorlabs.com
    @token = `<insert-access-token>`
    @namespace = `<insert-namespace>`

    ###
    GET {{baseUrl}}/v1/namespaces/{{namespace}}/findings?list_parameters.filter=spec.finding_categories contains FINDING_CATEGORY_VULNERABILITY&list_parameters.group.aggregation_paths=spec.level HTTP/1.1
    Content-type: application/json
    Authorization: Bearer {{token}}
    Request-Timeout: 60
    ```
  </Tab>
</Tabs>

```bash expandable theme={null}
{
  "group_response": {
    "groups": {
      "[{\"key\":\"spec.level\",\"value\":\"FINDING_LEVEL_CRITICAL\"}]": {
        "aggregation_count": {
          "count": 49
        }
      },
      "[{\"key\":\"spec.level\",\"value\":\"FINDING_LEVEL_HIGH\"}]": {
        "aggregation_count": {
          "count": 166
        }
      },
      "[{\"key\":\"spec.level\",\"value\":\"FINDING_LEVEL_LOW\"}]": {
        "aggregation_count": {
          "count": 31
        }
      },
      "[{\"key\":\"spec.level\",\"value\":\"FINDING_LEVEL_MEDIUM\"}]": {
        "aggregation_count": {
          "count": 202
        }
      }
    }
  }
}
```

## Group by path

The following options are available to group objects based on the value of a field in a given path.

<Tabs>
  <Tab title="endorctl">
    <YamlTable>
      {`


            - Option: \`group-aggregation-paths\`
            Description: Specify one or more fields to group objects by.
            - Option: \`group-show-aggregation-uuids\`
            Description: Get the UUIDs of the objects in each group as specified by \`--group-aggregation-paths\`.
            - Option: \`group-unique-count-paths\`
            Description: Count the number of unique values, for these fields, in the group.
            - Option: \`group-unique-value-paths\`
            Description: Get the unique values, for these fields, in the group.

            `}
    </YamlTable>

    For the complete list of all `endorctl api list` options, see [flags and variables](/developers-api/cli/commands/api#endorctl-api-list-flags-and-variables).
  </Tab>

  <Tab title="curl / HTTP">
    <YamlTable>
      {`


            - List_Parameter: \`group.aggregation_paths\`
            Description: Specify one or more fields to group objects by.
            - List_Parameter: \`group.show_aggregation_uuids\`
            Description: Get the UUIDs of the objects in each group as specified by \`group.aggregation_paths\`.
            - List_Parameter: \`group.unique_count_paths\`
            Description: Count the number of unique values, for these fields, in the group.
            - List_Parameter: \`group.unique_value_paths\`
            Description: Get the unique values, for these fields, in the group.

            `}
    </YamlTable>

    For the complete list of all HTTP list parameters, see [list parameters](/developers-api/rest-api/using-the-rest-api/getting-started#list-parameters).
  </Tab>
</Tabs>

### Group by path example

The following example uses all options to group package versions by call graph [resolution error](/developers-api/rest-api/using-the-rest-api/data-model/resource-kinds#resolution-errors). For each group, it lists the UUIDs, counts the ecosystems, and shows the unique ecosystems:

<Tabs>
  <Tab title="endorctl">
    ```bash theme={null}
    endorctl api list --resource PackageVersion \
      --filter "spec.resolution_errors.call_graph exists" \
      --group-aggregation-paths "spec.resolution_errors.call_graph.status_error" \
      --group-show-aggregation-uuids \
      --group-unique-count-paths "spec.ecosystem" \
      --group-unique-value-paths "spec.ecosystem" \
      --timeout 60s
    ```
  </Tab>

  <Tab title="curl">
    ```bash theme={null}
    curl --get \
      --header "Authorization: Bearer $ENDOR_TOKEN" \
      --header "Request-Timeout: 60" \
      --data-urlencode "list_parameters.filter=spec.resolution_errors.call_graph exists" \
      --data-urlencode "list_parameters.group.aggregation_paths=spec.resolution_errors.call_graph.status_error" \
      --data-urlencode "list_parameters.group.show_aggregation_uuids=true" \
      --data-urlencode "list_parameters.group.unique_value_paths=spec.ecosystem" \
      --data-urlencode "list_parameters.group.unique_count_paths=spec.ecosystem" \
      https://api.endorlabs.com/v1/namespaces/$ENDOR_NAMESPACE/package-versions \
      | jq '.'
    ```
  </Tab>

  <Tab title="HTTP">
    ```bash theme={null}
    @baseUrl = https://api.endorlabs.com
    @token = `<insert-access-token>`
    @namespace = `<insert-namespace>`

    ###
    GET {{baseUrl}}/v1/namespaces/{{namespace}}/package-versions?list_parameters.filter=spec.resolution_errors.call_graph exists&list_parameters.group.aggregation_paths=spec.resolution_errors.call_graph.status_error&list_parameters.group.show_aggregation_uuids=true&list_parameters.group.unique_value_paths=spec.ecosystem&list_parameters.group.unique_count_paths=spec.ecosystem HTTP/1.1
    Content-type: application/json
    Authorization: Bearer {{token}}
    Request-Timeout: 60
    ```
  </Tab>
</Tabs>

```bash expandable theme={null}
{
  "group_response": {
    "groups": {
      "[{\"key\":\"spec.resolution_errors.call_graph.status_error\",\"value\":\"STATUS_ERROR_CALL_GRAPH\"}]": {
        "aggregation_count": {
          "count": 10
        },
        "aggregation_uuids": [
          "6494c13cdcb266d2af02804f",
          "64ace2dd05228d0041488208",
          "64ace2dc05228d00414881eb",
          "64af3a042efc155e48304bf2",
          "65b86b4a0f460309eac456b5",
          "64ace2dc832ee78dd03d85b0",
          "64c190aa17e6bfc2548f7a48",
          "64af39d2bebf530905411327",
          "64c190a817e6bfc2548f7a19",
          "64cc2b68727cd13ec36860c8"
        ],
        "unique_counts": {
          "spec.ecosystem": {
            "count": 2
          }
        },
        "unique_values": {
          "spec.ecosystem": [
            "ECOSYSTEM_MAVEN",
            "ECOSYSTEM_PYPI"
          ]
        }
      },
      "[{\"key\":\"spec.resolution_errors.call_graph.status_error\",\"value\":\"STATUS_ERROR_INTERNAL\"}]": {
        "aggregation_count": {
          "count": 2
        },
        "aggregation_uuids": [
          "6632e2d6b7765d736fac1865",
          "664ba7986fafc782b3cda1f6"
        ],
        "unique_counts": {
          "spec.ecosystem": {
            "count": 1
          }
        },
        "unique_values": {
          "spec.ecosystem": [
            "ECOSYSTEM_NPM"
          ]
        }
      },
      "[{\"key\":\"spec.resolution_errors.call_graph.status_error\",\"value\":\"STATUS_ERROR_MISSING_ARTIFACT\"}]": {
        "aggregation_count": {
          "count": 23
        },
        "aggregation_uuids": [
          "65c3e90ae2dd352a18b6f852",
          "64b99a3b3d5f8dc732555200",
          "64c190a921d68642091aa015",
          "650a2457204ab859367160a2",
          "650a245780113616f95f770e",
          "65d6840edb5cf8c9839c3d47",
          "65e8c21647aae08e2a4e5f5c",
          "64c190a921d68642091aa027",
          "64c190a958d2eff448df09e1",
          "650a2457204ab859367160a6",
          "64c190aa58d2eff448df09f0",
          "64af0879c41c606cbcef6288",
          "64c190ab17e6bfc2548f7a4d",
          "64c190aa17e6bfc2548f7a41",
          "64c190a958d2eff448df09ec",
          "64c190ab21d68642091aa033",
          "64c190ab58d2eff448df09f3",
          "64b99a3b6883c0ec1c456c3a",
          "64c190aa21d68642091aa02f",
          "64b99a3ce3b06b2f8a465bdc",
          "64c190a917e6bfc2548f7a35",
          "64b99a3b6883c0ec1c456c39",
          "650a24573e183ec1be29adc6"
        ],
        "unique_counts": {
          "spec.ecosystem": {
            "count": 1
          }
        },
        "unique_values": {
          "spec.ecosystem": [
            "ECOSYSTEM_MAVEN"
          ]
        }
      },
      "[{\"key\":\"spec.resolution_errors.call_graph.status_error\",\"value\":\"STATUS_ERROR_VENV\"}]": {
        "aggregation_count": {
          "count": 10
        },
        "aggregation_uuids": [
          "64c41863da2fbc7700d12a0e",
          "64c845aca83e181b82ef9041",
          "64dd4f61177264d779e203f3",
          "64c418647146e5738bf0af2d",
          "64c845ac41f581de1a6592d1",
          "64c845ac41f581de1a6592d0",
          "664be4bc6fafc782b363d8e3",
          "652e0bcb1d4d2ceedc87a376",
          "66311e48bf25e232ab24b68c",
          "64d6ce776e5804222a2726de"
        ],
        "unique_counts": {
          "spec.ecosystem": {
            "count": 1
          }
        },
        "unique_values": {
          "spec.ecosystem": [
            "ECOSYSTEM_PYPI"
          ]
        }
      }
    }
  }
}
```

## Group by time

The Endor Labs REST API also provides options to group objects by a given time interval. Common time fields include `meta.create_time` and `meta.update_time`, but you can sort objects based on any time field.

For example, to group objects based on create time in 2 week intervals, set the aggregation path to `meta.create_time`, the time interval to `GROUP_BY_TIME_INTERVAL_WEEK` and the group size to `2`.

The following options are available to group objects based on the value of a time field in a given path.

<Tabs>
  <Tab title="curl / HTTP">
    <YamlTable>
      {`


            - List_Parameter: \`group_by_time.aggregation_paths\`
            Description: Group the objects based on this time field.
            - List_Parameter: \`group_by_time.interval\`
            Description: The [time interval](#time-intervals) to group the objects by.
            - List_Parameter: \`group_by_time.group_size\`
            Description: The time interval size to group the objects by.
            - List_Parameter: \`group_by_time.start_time\`
            Description: Beginning of the time period to group objects.
            - List_Parameter: \`group_by_time.end_time\`
            Description: End of the time period to group objects.
            - List_Parameter: \`group_by_time.show_aggregation_uuids\`
            Description: Get the UUIDs of the objects in each group.

            `}
    </YamlTable>

    For the complete list of all HTTP list parameters, see [list parameters](/developers-api/rest-api/using-the-rest-api/getting-started#list-parameters).
  </Tab>
</Tabs>

### Time intervals

The following time intervals are supported.

<Tabs>
  <Tab title="curl / HTTP">
    <YamlTable>
      {`


            - Value: \`GROUP_BY_TIME_INTERVAL_YEAR\`
            Description: Year
            - Value: \`GROUP_BY_TIME_INTERVAL_QUARTER\`
            Description: Quarter
            - Value: \`GROUP_BY_TIME_INTERVAL_MONTH\`
            Description: Month
            - Value: \`GROUP_BY_TIME_INTERVAL_WEEK\`
            Description: Week
            - Value: \`GROUP_BY_TIME_INTERVAL_DAY\`
            Description: Day
            - Value: \`GROUP_BY_TIME_INTERVAL_HOUR\`
            Description: Hour
            - Value: \`GROUP_BY_TIME_INTERVAL_MINUTE\`
            Description: Minute
            - Value: \`GROUP_BY_TIME_INTERVAL_SECOND\`
            Description: Second

            `}
    </YamlTable>
  </Tab>
</Tabs>

### Group by time example

The following example requests the UUIDs of all critical findings, grouped by create time in two-week intervals:

<Tabs>
  <Tab title="curl">
    ```bash theme={null}
    curl --get \
      --header "Authorization: Bearer $ENDOR_TOKEN" \
      --header "Request-Timeout: 60" \
      --data-urlencode "list_parameters.filter=spec.level==FINDING_LEVEL_CRITICAL" \
      --data-urlencode "list_parameters.group_by_time.aggregation_paths=meta.create_time" \
      --data-urlencode "list_parameters.group_by_time.interval=GROUP_BY_TIME_INTERVAL_WEEK" \
      --data-urlencode "list_parameters.group_by_time.group_size=2" \
      --data-urlencode "list_parameters.group_by_time.show_aggregation_uuids=true" \
      https://api.endorlabs.com/v1/namespaces/$ENDOR_NAMESPACE/findings \
      | jq '.'
    ```
  </Tab>

  <Tab title="HTTP">
    ```bash theme={null}
    @baseUrl = https://api.endorlabs.com
    @token = `<insert-access-token>`
    @namespace = `<insert-namespace>`

    ###
    GET {{baseUrl}}/v1/namespaces/{{namespace}}/findings?list_parameters.filter=spec.level==FINDING_LEVEL_CRITICAL&list_parameters.group_by_time.aggregation_paths=meta.create_time&list_parameters.group_by_time.interval=GROUP_BY_TIME_INTERVAL_WEEK&list_parameters.group_by_time.group_size=2&list_parameters.group_by_time.show_aggregation_uuids=true HTTP/1.1
    Content-type: application/json
    Authorization: Bearer {{token}}
    Request-Timeout: 60
    ```
  </Tab>
</Tabs>

```bash expandable theme={null}
{
  "group_response": {
    "groups": {
      "\"2024-01-28T00:00:00Z\"": {
        "aggregation_count": {
          "count": 7
        },
        "aggregation_uuids": [
          "65c02da021a5d767fc147ec0",
          "65c02da021a5d767fc147ec3",
          "65c02da0aa4b66fa5009eaec",
          "65c02da0056f94b6129aa209",
          "65c02da021a5d767fc147eca",
          "65c02da1aa4b66fa5009eaf9",
          "65c02daa056f94b6129aa46f"
        ],
        "unique_counts": {},
        "unique_values": {}
      },
      "\"2024-03-10T00:00:00Z\"": {
        "aggregation_count": {
          "count": 2
        },
        "aggregation_uuids": [
          "65faf8ec357952c8eda2d36b",
          "65fcdcedd40334d9e0065748"
        ],
        "unique_counts": {},
        "unique_values": {}
      },
      "\"2024-03-24T00:00:00Z\"": {
        "aggregation_count": {
          "count": 2
        },
        "aggregation_uuids": [
          "660728d190fdb066027d07bb",
          "660728d8bddd7358d570ce9c"
        ],
        "unique_counts": {},
        "unique_values": {}
      },
      "\"2024-04-07T00:00:00Z\"": {
        "aggregation_count": {
          "count": 15
        },
        "aggregation_uuids": [
          "6615c531bb58b077e43cbb16",
          "6615c531e2a0c32733a7d50b",
          "6615c531e2a0c32733a7d514",
          "66216bb723ebef7ca3f4571a",
          "66216bb7c28c6f37b51cd0e8",
          "66216bb723ebef7ca3f4571d",
          "66216bc62c21fa9407eda175",
          "66216bc6c28c6f37b51cd2d4",
          "66216bc62c21fa9407eda17b",
          "66216bd72c21fa9407eda210",
          "66216bd823ebef7ca3f459a8",
          "66216bd823ebef7ca3f459ab",
          "66216bd8c28c6f37b51cd381",
          "66216be623ebef7ca3f45a8a",
          "66216be6c28c6f37b51cd465"
        ],
        "unique_counts": {},
        "unique_values": {}
      },
      "\"2024-04-21T00:00:00Z\"": {
        "aggregation_count": {
          "count": 1
        },
        "aggregation_uuids": [
          "66341d55f9aa19f4b730a74c"
        ],
        "unique_counts": {},
        "unique_values": {}
      },
      "\"2024-05-19T00:00:00Z\"": {
        "aggregation_count": {
          "count": 19
        },
        "aggregation_uuids": [
          "664be2cc6fafc782b35fdc89",
          "664be2cc6fafc782b35fdceb",
          "664be2d56fafc782b35ff0d8",
          "664be2d56fafc782b35ff0e0",
          "664be2d5f420988edd47792d",
          "664be2dd67636bf844aedcae",
          "664be2dd6fafc782b36000a8",
          "664be2dd6fafc782b36000aa",
          "664be2ddf420988edd4788eb",
          "664be2e867636bf844aef4e9",
          "664be2e8f420988edd47a140",
          "664be2e8f420988edd47a148",
          "6656ababd2d288f1981ea2ba",
          "6656ababce82b72012f10bbc",
          "6656ababce82b72012f10bbd",
          "6656abab252554c986334a6b",
          "6656ababd2d288f1981ea2bd",
          "6656abab252554c986334a6d",
          "6656abacce82b72012f10bbf"
        ],
        "unique_counts": {},
        "unique_values": {}
      },
      "\"2024-06-02T00:00:00Z\"": {
        "aggregation_count": {
          "count": 5
        },
        "aggregation_uuids": [
          "665fa482c980f9f8157e08c3",
          "6660a9f0e238ad93ad92089e",
          "6660a9f05728ef99cf0c8535",
          "6660a9f0b70974e544ccd05a",
          "6660a9f05728ef99cf0c853f"
        ],
        "unique_counts": {},
        "unique_values": {}
      }
    }
  }
}
```
