Analytics
Analytics answers the questions finance asks: what is recurring revenue, how much is churning, what did you bill and collect, what is still owed, and how much customer money are you holding.
The API is generic rather than one endpoint per figure: you ask for a metric by key, as a series, a breakdown or an overview tile. The dashboard reads the same endpoints.
| Endpoint | Answers |
|---|---|
GET /v1/analytics/metrics | Every metric served: key, unit, stock or flow, grains, dimensions |
GET /v1/analytics/series | One metric as a dense time series |
GET /v1/analytics/breakdown | One metric sliced by one dimension, reduced over the window |
GET /v1/analytics/overview | The headline tiles for a window, with deltas against the previous one |
GET /v1/analytics/invoices/aging | Open receivable in aging bands as of a date |
GET /v1/analytics/currencies | The currencies the workspace has data in |
GET /v1/analytics/wallet-custody | Customer money you are holding, and a period's wallet activity |
Find the metric
GET /v1/analytics/metrics is the catalogue, rendered from the server's own
registry, so a metric picker built on it cannot drift from what the server
answers. Each entry has a key, label, description, unit (money,
count, ratio, duration), series_kind (stock or flow), additivity,
the grains it can be bucketed in and the closed set of dimensions it may be
sliced by. A metric that is declared but not yet served is listed with
available: false rather than left out.
Keys include mrr, arr, mrr_movement, churned_mrr, active_subscriptions,
active_customers, churned_customers, gross_billings, net_billings,
cash_collected, ar_balance and usage_revenue. Read the catalogue for the
full list and for each metric's exact definition.
Ask for a series
Code
metric, from and to are required. The window is half-open: from is
inclusive, to exclusive. grain is day, week, month, quarter or
year (defaulting to the metric's finest). dimension slices the series, and
top_n keeps the N largest series and folds the rest into Other. timezone
is an IANA zone; buckets are local days, in the organisation's zone by
default.
The response carries metric, label, unit, series_kind, grain,
series_names and points, each point a bucket, a series name (total
when unsliced), a value and imputed. Three things are worth knowing before
you consume it:
- The series is dense. A bucket in which nothing happened is present.
imputedmarks a point carried forward rather than observed. Only a stock is ever carried.metasays how fresh and complete the answer is:as_of,basis(live,rollupormixed),complete_from,partialwithnotes, and thetimezonethat actually produced the buckets.
A window larger than the bucket cap is refused rather than truncated.
GET /v1/analytics/breakdown takes the same parameters plus a required
dimension and reduces each slice over the window; it is a reduction of the same
series, so the two cannot disagree about their total.
GET /v1/analytics/overview takes from, to and currency and returns one tile
per headline metric with its value, the previous window's value, delta_abs
and delta_pct (absent when the previous value was zero), and how the window was
reduced.
One currency at a time
Every money figure is scoped to a single currency, and this is not a convenience
filter. Summing CHF and EUR produces something that looks like money and is not.
currency is required for a money metric and refused when missing, except with
dimension=currency, which returns one labelled series per currency instead of
mixing them. GET /v1/analytics/currencies lists the codes you have data in.
To report across currencies, query per currency and convert with a rate you chose deliberately. See Exchange rates.
Stock versus flow
MRR is a stock: a level at an instant. Billings are a flow: what happened
during a period. A stock must never be summed across buckets: adding up seven
days of MRR gives a number seven times too large that looks entirely plausible.
Every metric and every overview tile states its series_kind, and overview
tiles reduce a stock to its level at the end of the window.
MRR counts the recurring, pre-tax charges of live deal lines. Usage, one-off and
manual charges are not in it; usage is reported beside it as usage_revenue. A
trial phase at a free price contributes nothing. Two systems can both be right and
disagree about MRR by drawing these lines differently, so read the metric's
description before reconciling.
Receivables and wallet custody
GET /v1/analytics/invoices/aging splits the open receivable into five aging
bands as of a report date (as_of, default yesterday), read from a nightly
snapshot and aged against that date rather than today. A day with no snapshot
answers 404 rather than five zeros. currency is required.
Prepaid wallet balances are your customers' money sitting with you.
It is not revenue, and it is the figure people most often forget to report.
GET /v1/analytics/wallet-custody (with a required currency) returns how much
you hold and how a period's wallet activity split between revenue, discount,
breakage, top-ups and refunds.
Exports
POST /v1/reports/exports renders a metric series to CSV asynchronously, for
ranges no interactive query should attempt, and
GET /v1/reports/exports/{id} returns its state and, when it is ready, a
download link. An identical request is reused rather than run twice.
Reference
| Topic | When you need it |
|---|---|
| Subscriptions | Status and phases, the inputs to MRR |
| Invoices | Where billings come from |
| Wallets | The balances behind wallet custody |
| Analytics API | Every parameter and response shape |