Real-time business metrics for your billing operation. Track monthly recurring revenue (MRR), customer churn, revenue breakdown by plan, and other key indicators.
- MRR - the normalized monthly revenue from all active subscriptions
- Churn - the rate at which customers cancel or downgrade
- Revenue - breakdown by product, plan, currency, and time period
Break a metric down by one dimension
Slices a metric by one of its declared dimensions and reduces each slice over the window. It is a REDUCTION of the same series /analytics/series returns — the same source, the same fold, the same stock-versus-flow rules — so a breakdown and its series can never disagree about their own total. share is computed at read time and never stored: a share cannot be re-aggregated, and both value and total are returned so any subset can be recomputed. top_n folds the tail into a single 'Other' slice, flagged with is_other and always sorted last regardless of size.
query Parameters
metricMetric key.
dimensionOne of the metric's declared dimensions.
fromStart of the window. INCLUSIVE.
toEnd of the window. EXCLUSIVE.
grainBucket width used internally before reduction. Defaults to the metric's finest grain; it does not change the answer for a flow.
currencyISO 4217 code. Required for a money metric.
top_nKeep the N largest slices and fold the rest into 'Other', ranked by total over the window.
timezoneIANA zone. Defaults to the organization's configured timezone.
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Break a metric down by one dimension › Responses
OK
Invoice aging as of a date
Open receivable split into aging bands AS OF a given day, read from the nightly snapshot.
The bands are aged against the REPORT DATE, not against today. An invoice 90 days overdue now was 30 days overdue two months ago, and this endpoint says so — which is the whole reason the snapshot exists. invoices.amount_due mutates in place, so the same question asked live would return today's balances under an older date.
A day with no snapshot answers 404 with that explanation rather than five zeros: 'nothing was owed' and 'nobody has computed this' are different answers and must not render identically.
All five bands are always present, in aging order, zero-filled.
query Parameters
currencyISO 4217 code. Aging never mixes currencies.
as_ofReport date, YYYY-MM-DD. Defaults to yesterday — the most recent day the snapshot can be complete for.
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Invoice aging as of a date › Responses
OK
List available metrics
Returns every metric this API serves, with its unit, grains, the closed set of dimensions it may be sliced by, and whether a coarser figure may be derived by summing finer buckets. Rendered from the server's own registry, so a client's metric picker cannot drift from what the server will actually answer. A metric that is declared but not yet served appears with available=false rather than being absent.
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
List available metrics › Responses
OK
Get the dashboard overview
Returns the dashboard's headline tiles for a window, each with the same reduction over the immediately preceding window of equal length so the deltas are comparable.
Two things are explicit on every tile because they are not interchangeable. reduction says HOW the window became one number: a FLOW is summed, a STOCK is the level at the end of the window and is never summed across buckets — adding up seven consecutive days of MRR gives a number seven times too large that looks entirely plausible. And available is false, with a reason, for a metric that is declared but not yet servable; the tile is still returned, because a missing number that says why is more useful than a plausible wrong one.
delta_pct is ABSENT when the previous value was zero: a change from nothing is undefined, not infinite and not +100%.
query Parameters
fromStart of the window, RFC 3339 or YYYY-MM-DD. INCLUSIVE.
toEnd of the window. EXCLUSIVE — the window is half-open [from, to).
currencyISO 4217 code. Required: the money tiles cannot be aggregated across currencies.
timezoneIANA zone to bucket in. Defaults to the organization's configured timezone.
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Get the dashboard overview › Responses
OK
Get a metric time series
Returns one metric as a dense, gap-filled time series bucketed in the organization's local days. Three things about the response are worth reading before consuming it. The series is DENSE: a bucket in which nothing happened is present, because a chart must not be left to decide what a hole means. imputed distinguishes a CARRIED-FORWARD level from an observed one — only a stock is ever carried, since a level persists through a quiet bucket while a flow does not. And meta states the freshness and completeness of the answer, including any known qualification: a figure bounded by an accrual horizon says so rather than presenting an absent period as a zero. A window larger than the bucket cap is REFUSED rather than truncated, because a truncated series is indistinguishable from a complete one once it is drawn.
query Parameters
metricMetric key. GET /v1/analytics/metrics lists every one this API serves.
fromStart of the window, RFC 3339 or YYYY-MM-DD. INCLUSIVE.
toEnd of the window, RFC 3339 or YYYY-MM-DD. EXCLUSIVE — the range is half-open [from, to).
grainBucket width: day or month. Defaults to the metric's finest declared grain.
currencyISO 4217 code. REQUIRED for a money metric: an aggregate over mixed currencies has no meaning, so it is refused rather than guessed.
dimensionSlice the series by one of the metric's declared dimensions.
top_nKeep the N highest-ranking series and fold the rest into a single 'Other'. Ranked by total over the whole window, not the last bucket, so the legend does not jump as the window moves.
timezoneIANA zone to bucket in. Defaults to the organization's configured timezone. Buckets are LOCAL days, not UTC days.
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Get a metric time series › Responses
OK
Get wallet custody position
Returns how much customer money the organization currently holds (a liability, not revenue) and how a period's wallet activity split between revenue, discount, breakage, top-ups and refunds. Required currency filter — wallets hold one currency each. Reports how many ledger rows are still unclassified, so a partial answer is visible as one.
query Parameters
currencyISO 4217 currency code (e.g. EUR, USD). Wallets hold one currency each, so a summary is per-currency.
fromStart of the reporting window, RFC 3339 (inclusive). Defaults to 30 days before 'to'.
toEnd of the reporting window, RFC 3339 (exclusive). Defaults to now.
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Get wallet custody position › Responses
OK