Skip to main content
Reports

Run a report query

Executes an ad-hoc reporting query: one metric + aggregation over a date range, with optional filters, grouping, segmentation and period-over-period comparison.

POST
/v2/reports/query

Building a query

  1. Pick a metric and aggregation from the datasets catalog (GET /v2/reports/datasets). Counts use count; duration metrics support sum, avg, median, min, max, range and percentile (pass percentile: 95 for p95); rate metrics use value.
  2. Set the reporting window with startDate / endDate (ISO 8601) and a granularity (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.
  3. Optionally narrow with filters — a rule ({ "kind": "rule", "fieldId": "...", "operator": "in", "value": [...] }) or an and/or group of rules. Attribute IDs and allowed operators come from the catalog.
  4. Optionally break results down with groupBy (primary dimension) and segmentBy (secondary dimension).
  5. Optionally pass compareStartDate / compareEndDate to get previousValue / deltaPercent alongside every data point.

Top-N and Show Other

For high-cardinality breakdowns, cap the number of returned series:

  • topValuesLimit keeps only the top N groupBy values; segmentTopValuesLimit does the same for segmentBy. Both accept integers from 1 to 100; the editor offers common presets plus a Custom value. topValuesLimit requires groupBy; segmentTopValuesLimit requires segmentBy.
  • 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 / segmentShowOther append a single synthetic bucket with id __other__ and label Other that 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 for avg, median, min, max, range, percentile, and for percentage metrics (whose ratios cannot be summed). showOther also requires topValuesLimit (and segmentShowOther requires segmentTopValuesLimit). Plain topValuesLimit (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-in rejects dataPointFilters.groupValue / segmentValue equal 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 window
  • timeSeries — one datum per granularity bucket
  • groupedData / segmentData — present when groupBy / segmentBy were requested
  • flowData — present for view: "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).

Authorizationstringheaderrequired

API key as Bearer token. Use: Authorization: Bearer sk_...

Featurebase-Versionenum<string>header

API version for this request. Defaults to your organization's configured API version if not specified.

Available options: 2026-08-19.orbit, 2026-01-01.nova, 2025-12-12.clover
Example: 2026-08-19.orbit

Body

application/json
aggregationenum<string>required

Aggregation function applied to the metric. Each metric supports a subset of aggregations — see the allowedAggregations field in the GET /v2/reports/datasets catalog.

Available options: count, sum, avg, median, min, max, range, percentile, value
Example: count
compareEndDatestring

End of the comparison window. Must be paired with compareStartDate.

Required string length: 10 - 64
compareStartDatestring

Start of the comparison window for period-over-period deltas. Must be paired with compareEndDate.

Required string length: 10 - 64
endDatestringrequired

End of the reporting window (ISO 8601 date or datetime, inclusive). Windows ending before 2026-07-14 are rejected.

Required string length: 10 - 64
Example: 2026-07-15
filtersobject

Filter expression: a single rule, or an and/or group combining rules and nested groups. Attribute IDs and their allowed operators come from GET /v2/reports/datasets.

granularityenum<string>required

Time bucket size for the returned time series.

Available options: hour, day, week, month
Example: day
groupBystring

Attribute ID to group results by (e.g. conversation.channel). See supportsGroupBy in the catalog.

Maximum string length: 512
Example: conversation.channel
metricstringrequired

Metric ID to query (e.g. new_conversations). Discover metric IDs via GET /v2/reports/datasets.

Required string length: 1 - 128
Example: new_conversations
officeHoursOnlybooleandefault:false

Restrict time-based metrics to configured office hours. Only supported by some metrics (see supportsOfficeHours in the catalog).

percentileinteger

Percentile (1-100) — required when aggregation is percentile.

Required range: 1 <= x <= 100
Example: 95
segmentBystring

Attribute ID for secondary segmentation within each group or time bucket.

Maximum string length: 512
segmentShowOtherboolean

When true, fold segmentBy values outside the top set into a synthetic __other__ / Other segment. Only supported for additive aggregations (count, sum, value) and not for percentage metrics. The __other__ segment cannot be drilled into. Requires segmentBy and segmentTopValuesLimit.

segmentTopValuesLimitinteger

Keep only the top N segmentBy values per series. Under a time View-by, segments are ranked independently inside each time bucket and the response series catalog contains the union of bucket winners. Under a dimension View-by, ranking is applied within each retained parent group. Allowed range: 1 to 100; the editor offers common presets plus a Custom value. Requires segmentBy.

Required range: 1 <= x <= 100
Example: 5
showOtherboolean

When true, append a single synthetic group with id __other__ and label Other that sums the values of every groupBy value outside the top set. Only supported for additive aggregations (count, sum, value) and not for percentage metrics. The __other__ group cannot be drilled into. Requires groupBy and topValuesLimit.

startDatestringrequired

Start of the reporting window (ISO 8601 date or datetime, inclusive). Reporting data is available from 2026-07-14; crossing windows are clamped to that boundary.

Required string length: 10 - 64
Example: 2026-07-14
timezonestring

IANA timezone for date bucketing (e.g. America/New_York). Defaults to UTC.

Maximum string length: 64
Example: Europe/Tallinn
topValuesLimitinteger

Keep only the top N groupBy (View-by) values, ranked by the selected metric/aggregation over the full filtered primary range. Allowed range: 1 to 100; the editor offers common presets plus a Custom value. A comparison period reuses the primary period's ranked set. Requires groupBy.

Required range: 1 <= x <= 100
Example: 10
viewenum<string>

Result shape. standard returns a time series (plus grouped/segment data when requested), hourly_heatmap buckets by day-of-week × hour-of-day, sankey returns conversation flow data. Each metric lists its supportedViews in the GET /v2/reports/datasets catalog.

Available options: standard, hourly_heatmap, sankey
Example: standard

Response

application/json

Success

deltaPercentnumber

Percentage change vs the comparison window.

flowDataobject[]
groupedDataobject[]
metaobjectrequired
objectenum<string>required
Available options: report_query_result
previousValuenumber

Aggregated value for the comparison window, when requested.

segmentDataobject[]
tableobject
timeSeriesobject[]
valuenumberrequired

Aggregated value across the whole reporting window.