Grouping
Break results down by one or more fields.
Grouping splits a count into buckets, one per distinct value of a field. Instead of one total you get a breakdown, which is how dashboards answer questions like "completions by country" or "usage by plan".
What grouping returns
typescript
const byCountry = await vanta.groupBy({
groupBy: ['context.country'],
filters: filter('type', 'equals', 'checkout.completed'),
time: timeRange('2024-01-01T00:00:00Z', '2024-12-31T23:59:59Z'),
})The response contains one group per distinct value, each with its count:
json
{
"groups": [
{ "field": "context.country", "value": "US", "count": 8124 },
{ "field": "context.country", "value": "DE", "count": 3172 },
{ "field": "context.country", "value": "BR", "count": 2190 }
]
}Single field
Group by a property to see how your data splits across it:
typescript
const byPlan = await vanta.groupBy({
groupBy: ['data.plan'],
filters: filter('type', 'equals', 'user.signup'),
time: timeRange('2024-01-01T00:00:00Z', '2024-12-31T23:59:59Z'),
})Multiple fields
Pass more than one field to create nested groups. Each combination of values becomes its own group:
typescript
const byPlanAndCountry = await vanta.groupBy({
groupBy: ['data.plan', 'context.country'],
filters: filter('type', 'equals', 'checkout.completed'),
time: timeRange('2024-01-01T00:00:00Z', '2024-12-31T23:59:59Z'),
})Grouping with filters
Grouping composes with filtering. Restrict the events first, then split the survivors:
typescript
const bySource = await vanta.groupBy({
groupBy: ['source'],
filters: and(
filter('type', 'equals', 'user.signup'),
filter('data.plan', 'equals', 'pro'),
),
time: timeRange('2024-01-01T00:00:00Z', '2024-12-31T23:59:59Z'),
})