---
title: "Query revenue analytics"
method: POST
path: "/analytics/revenue"
tags: ["Analytics"]
---

# Query revenue analytics

`POST /analytics/revenue`

Aggregates revenue_facts by the requested dimensions at day/period/total granularity. allocation_policy places whole-period charges on their booked day (billed) or spreads them across the period (amortized); include_adjustments breaks out true-up/overage/revert amounts as labeled rows. Requires the tenant's revenue analytics setting.

## Request body

- RevenueAnalyticsRequest
  - `allocation_policy` 'billed' | 'amortized'
  - `currency` string
  - `customer_ids` string[] — Filters restrict the rows before aggregation.
  - `end_time` string, date-time
  - `granularity` 'day' | 'period' | 'total'
  - `group_by` string[] — GroupBy dimensions: revenue_source, source (the event source recorded in meter_usage; requires customer_ids or subscription_ids), customer_id, subscription_id, price_id, meter_id, currency. revenue_source is always applied — every row says what kind of revenue it is — and requested dimensions are added on top.
  - `include_adjustments` boolean — IncludeAdjustments breaks the non-obvious components — commitment true-ups, overage and revert (contra) rows — out as their own rows, each labeled with its kind in adjustment_type. Off, they fold into their parent buckets (true-up/overage into usage, reverts into their own source) so visible rows read as plain usage/fixed. Totals are identical either way.
  - `meter_ids` string[]
  - `price_ids` string[]
  - `start_time` string, date-time, required — StartTime/EndTime bound the day range (inclusive days derived in UTC). EndTime is optional and defaults to now.
  - `status` 'PROVISIONAL' | 'FINAL'
  - `subscription_ids` string[]

## Response `200`

OK

- RevenueAnalyticsResponse
  - `contains_allocated` boolean — ContainsAllocated is true when any bucket includes whole-period amounts spread across days (amortized) or booked on a single day (billed) — i.e. the day view carries period-shaped charges, not only true daily accruals.
  - `query` RevenueAnalyticsRequest
    - `allocation_policy` 'billed' | 'amortized'
    - `currency` string
    - `customer_ids` string[] — Filters restrict the rows before aggregation.
    - `end_time` string, date-time
    - `granularity` 'day' | 'period' | 'total'
    - `group_by` string[] — GroupBy dimensions: revenue_source, source (the event source recorded in meter_usage; requires customer_ids or subscription_ids), customer_id, subscription_id, price_id, meter_id, currency. revenue_source is always applied — every row says what kind of revenue it is — and requested dimensions are added on top.
    - `include_adjustments` boolean — IncludeAdjustments breaks the non-obvious components — commitment true-ups, overage and revert (contra) rows — out as their own rows, each labeled with its kind in adjustment_type. Off, they fold into their parent buckets (true-up/overage into usage, reverts into their own source) so visible rows read as plain usage/fixed. Totals are identical either way.
    - `meter_ids` string[]
    - `price_ids` string[]
    - `start_time` string, date-time, required — StartTime/EndTime bound the day range (inclusive days derived in UTC). EndTime is optional and defaults to now.
    - `status` 'PROVISIONAL' | 'FINAL'
    - `subscription_ids` string[]
  - `rows` RevenueAnalyticsRow[]
    - `adjustment_type` string — AdjustmentType labels rows broken out by include_adjustments: "commitment_trueup", "overage" or "revert". Empty for plain rows.
    - `billable_qty` number
    - `day` string — Day is set for day granularity; PeriodStart/PeriodEnd for period.
    - `entitlement_amount` number
    - `entitlement_qty` number
    - `group` object — Group holds the requested dimensions and their values for this bucket.
    - `invoice_discount` number
    - `line_discount` number
    - `net_amount` number
    - `period_end` string, date-time
    - `period_start` string, date-time
    - `status` 'PROVISIONAL' | 'FINAL'
    - `tier_delta` number
    - `usage_at_list_rate` number

## Other responses

- `400` — Invalid request
- `403` — Revenue analytics not enabled
- `500` — Server error

## Changes

- **2026-09-23** `4e02a6d3e3d9` — 1 info
  - added the optional property `rows/items/status` to the response with the `200` status
- **2026-09-22** `ddf4ea4fc5a1` — 2 info
  - the request property `end_time` became optional
  - added the optional property `query` to the response with the `200` status
- **2026-09-22** `b395e3f05ba2` — 1 info
  - endpoint added
- **2026-09-21** `15dcbc3c880b` — 1 breaking
  - api path removed without deprecation
- **2026-09-21** `56ac1e6adeb7` — 1 info
  - endpoint added

[Full history](https://skmtc.dev/flexprice/apis/flexprice-api/changes/analytics/revenue/post.md)

---

[API](https://skmtc.dev/flexprice/apis/flexprice-api.md) · [All operations](https://skmtc.dev/flexprice/apis/flexprice-api/llms.txt) · [OpenAPI document](https://skmtc.dev/flexprice/apis/flexprice-api/revisions/19bac1b92501?raw)
