Run a report query
client.reports.query(ReportQueryParams { aggregation, endDate, granularity, 16 more } params, RequestOptionsoptions?): ReportQueryResponse { meta, object, value, 7 more }
POST/v2/reports/query
Executes an ad-hoc reporting query: one metric + aggregation over a date range, with optional filters, grouping, segmentation and period-over-period comparison.
Building a query
- Pick a
metricandaggregationfrom the datasets catalog (GET /v2/reports/datasets). Counts usecount; duration metrics supportsum,avg,median,min,max,rangeandpercentile(passpercentile: 95for p95); rate metrics usevalue. - Set the reporting window with
startDate/endDate(ISO 8601) and agranularity(hour,day,week,month) for the returned time series. Reporting data is available from July 14, 2026. Windows ending earlier are rejected; crossing windows are clamped to that boundary in the requested timezone. - Optionally narrow with
filters— a rule ({ "kind": "rule", "fieldId": "...", "operator": "in", "value": [...] }) or anand/orgroup of rules. Attribute IDs and allowed operators come from the catalog. - Optionally break results down with
groupBy(primary dimension) andsegmentBy(secondary dimension). - Optionally pass
compareStartDate/compareEndDateto getpreviousValue/deltaPercentalongside every data point.
Top-N and Show Other
For high-cardinality breakdowns, cap the number of returned series:
topValuesLimitkeeps only the top NgroupByvalues;segmentTopValuesLimitdoes the same forsegmentBy. Both accept integers from 1 to 100; the editor offers common presets plus a Custom value.topValuesLimitrequiresgroupBy;segmentTopValuesLimitrequiressegmentBy.- For time-series segment breakdowns, members are ranked inside each time bucket. The response keeps the union of those bucket winners in its series catalog, while a member outside a bucket’s Top N has a zero value in that bucket. This matches the chart’s per-period ranking semantics. A comparison period is folded into the primary period’s union of visible members so current and previous series keep the same identities.
- For non-time-series grouped results, members are ranked over the full filtered primary range. A comparison period reuses the primary period’s ranked set rather than independently changing the legend.
showOther/segmentShowOtherappend a single synthetic bucket with id__other__and labelOtherthat sums every value outside the top set. Because the values are summed, Show Other is only supported for additive aggregations (count,sum,value); it is rejected foravg,median,min,max,range,percentile, and for percentage metrics (whose ratios cannot be summed).showOtheralso requirestopValuesLimit(andsegmentShowOtherrequiressegmentTopValuesLimit). PlaintopValuesLimit(without Show Other) works with any aggregation.- The
__other__group/segment aggregates rows outside the selected top groups and cannot be drilled into (POST /v2/reports/drill-inrejectsdataPointFilters.groupValue/segmentValueequal to__other__).
Example
{
"metric": "new_conversations",
"aggregation": "count",
"startDate": "2026-07-14",
"endDate": "2026-07-15",
"granularity": "day",
"groupBy": "conversation.channel",
"filters": {
"kind": "rule",
"fieldId": "conversation.state",
"operator": "is",
"value": "closed"
}
}
Response shape
value— the aggregate across the whole windowtimeSeries— one datum per granularity bucketgroupedData/segmentData— present whengroupBy/segmentBywere requestedflowData— present forview: "sankey"(Overview conversation-flow metrics)meta— echo of the resolved metric, dataset, unit and aggregation
Special views
view: "hourly_heatmap"buckets by day-of-week × hour-of-day (use with volume metrics)view: "sankey"returns conversation flow edges (Overview metrics only)
Version Availability
This endpoint is only available in API version 2026-01-01.nova and newer, and only for workspaces with the Reports product enabled (404 otherwise).
Run a report query
import Featurebase from 'featurebase-node';
const client = new Featurebase({
apiKey: process.env['FEATUREBASE_API_KEY'], // This is the default and can be omitted
});
const response = await client.reports.query({
aggregation: 'count',
endDate: '2026-07-15',
granularity: 'day',
metric: 'new_conversations',
startDate: '2026-07-14',
});
console.log(response.meta);{
"meta": {
"aggregation": "count",
"datasetId": "datasetId",
"granularity": "granularity",
"metric": "metric",
"officeHoursOnly": true,
"unit": "count",
"groupBy": "groupBy",
"segmentBy": "segmentBy"
},
"object": "report_query_result",
"value": 0,
"deltaPercent": 0,
"flowData": [
{
"metricId": "metricId",
"pathId": "pathId",
"source": "source",
"sourceLabel": "sourceLabel",
"target": "target",
"targetLabel": "targetLabel",
"value": 0,
"colorKey": "colorKey",
"percentage": 0,
"sortOrder": 0
}
],
"groupedData": [
{
"group": "group",
"value": 0,
"groupLabel": "groupLabel",
"identity": {
"id": "id",
"kind": "teammate",
"label": "label",
"avatarUrl": "avatarUrl",
"color": "color",
"website": "website"
},
"previousValue": 0,
"segments": [
{
"segment": "segment",
"value": 0,
"identity": {
"id": "id",
"kind": "teammate",
"label": "label",
"avatarUrl": "avatarUrl",
"color": "color",
"website": "website"
},
"previousValue": 0,
"segmentLabel": "segmentLabel"
}
]
}
],
"previousValue": 0,
"segmentData": [
{
"segment": "segment",
"value": 0,
"identity": {
"id": "id",
"kind": "teammate",
"label": "label",
"avatarUrl": "avatarUrl",
"color": "color",
"website": "website"
},
"previousValue": 0,
"segmentLabel": "segmentLabel"
}
],
"table": {
"columns": [
{
"id": "id",
"kind": "dimension",
"label": "label",
"sortable": true,
"unit": "count",
"align": "left",
"sticky": true,
"summary": "sum",
"valueType": "valueType"
}
],
"key": "key",
"mode": "aggregate",
"page": 0,
"pageSize": 0,
"rows": [
{
"id": "id",
"cells": {
"foo": {
"display": "display",
"deltaPercent": 0,
"denominator": 0,
"identity": {
"id": "id",
"kind": "teammate",
"label": "label",
"avatarUrl": "avatarUrl",
"color": "color",
"website": "website"
},
"numerator": 0,
"previousValue": 0,
"raw": {},
"sortValue": "string",
"value": {}
}
}
}
],
"totalRows": 0,
"sort": {
"columnId": "columnId",
"direction": "asc"
},
"summaryRows": [
{
"id": "id",
"cells": {
"foo": {
"display": "display",
"deltaPercent": 0,
"denominator": 0,
"identity": {
"id": "id",
"kind": "teammate",
"label": "label",
"avatarUrl": "avatarUrl",
"color": "color",
"website": "website"
},
"numerator": 0,
"previousValue": 0,
"raw": {},
"sortValue": "string",
"value": {}
}
}
}
]
},
"timeSeries": [
{
"date": "2026-07-15",
"value": 0,
"previousValue": 0,
"segments": [
{
"segment": "segment",
"value": 0,
"identity": {
"id": "id",
"kind": "teammate",
"label": "label",
"avatarUrl": "avatarUrl",
"color": "color",
"website": "website"
},
"previousValue": 0,
"segmentLabel": "segmentLabel"
}
]
}
]
}Returns Examples
{
"meta": {
"aggregation": "count",
"datasetId": "datasetId",
"granularity": "granularity",
"metric": "metric",
"officeHoursOnly": true,
"unit": "count",
"groupBy": "groupBy",
"segmentBy": "segmentBy"
},
"object": "report_query_result",
"value": 0,
"deltaPercent": 0,
"flowData": [
{
"metricId": "metricId",
"pathId": "pathId",
"source": "source",
"sourceLabel": "sourceLabel",
"target": "target",
"targetLabel": "targetLabel",
"value": 0,
"colorKey": "colorKey",
"percentage": 0,
"sortOrder": 0
}
],
"groupedData": [
{
"group": "group",
"value": 0,
"groupLabel": "groupLabel",
"identity": {
"id": "id",
"kind": "teammate",
"label": "label",
"avatarUrl": "avatarUrl",
"color": "color",
"website": "website"
},
"previousValue": 0,
"segments": [
{
"segment": "segment",
"value": 0,
"identity": {
"id": "id",
"kind": "teammate",
"label": "label",
"avatarUrl": "avatarUrl",
"color": "color",
"website": "website"
},
"previousValue": 0,
"segmentLabel": "segmentLabel"
}
]
}
],
"previousValue": 0,
"segmentData": [
{
"segment": "segment",
"value": 0,
"identity": {
"id": "id",
"kind": "teammate",
"label": "label",
"avatarUrl": "avatarUrl",
"color": "color",
"website": "website"
},
"previousValue": 0,
"segmentLabel": "segmentLabel"
}
],
"table": {
"columns": [
{
"id": "id",
"kind": "dimension",
"label": "label",
"sortable": true,
"unit": "count",
"align": "left",
"sticky": true,
"summary": "sum",
"valueType": "valueType"
}
],
"key": "key",
"mode": "aggregate",
"page": 0,
"pageSize": 0,
"rows": [
{
"id": "id",
"cells": {
"foo": {
"display": "display",
"deltaPercent": 0,
"denominator": 0,
"identity": {
"id": "id",
"kind": "teammate",
"label": "label",
"avatarUrl": "avatarUrl",
"color": "color",
"website": "website"
},
"numerator": 0,
"previousValue": 0,
"raw": {},
"sortValue": "string",
"value": {}
}
}
}
],
"totalRows": 0,
"sort": {
"columnId": "columnId",
"direction": "asc"
},
"summaryRows": [
{
"id": "id",
"cells": {
"foo": {
"display": "display",
"deltaPercent": 0,
"denominator": 0,
"identity": {
"id": "id",
"kind": "teammate",
"label": "label",
"avatarUrl": "avatarUrl",
"color": "color",
"website": "website"
},
"numerator": 0,
"previousValue": 0,
"raw": {},
"sortValue": "string",
"value": {}
}
}
}
]
},
"timeSeries": [
{
"date": "2026-07-15",
"value": 0,
"previousValue": 0,
"segments": [
{
"segment": "segment",
"value": 0,
"identity": {
"id": "id",
"kind": "teammate",
"label": "label",
"avatarUrl": "avatarUrl",
"color": "color",
"website": "website"
},
"previousValue": 0,
"segmentLabel": "segmentLabel"
}
]
}
]
}