Parameters
1 query
Query parameters
· 1period"year" | "quarter"OptionalGranularity: yearly (3 pairs) or quarterly YoY (12 pairs). Defaults to year.
yearyearCohort-based revenue retention: for customers who paid in a previous period, how much do they still pay this period? Returns per-period stats, per-customer retention bands, a stability score and a warning level. The most recent period is "floating" (truncated to today) and compared to the same offset in the prior period for a fair in-progress comparison. Returns insufficient_data if the organisation's first paid order is younger than 2 years.
1 query
period"year" | "quarter"OptionalGranularity: yearly (3 pairs) or quarterly YoY (12 pairs). Defaults to year.
yearyear1 status code documented
period"year" | "quarter"RequiredGranularity actually used.
currencystringRequiredCurrency code for all revenue values (org default).
warningobjectRequiredWarning summary.
level"insufficient_data" | "healthy" | "low_retention"RequiredHealth classification of the latest (floating) retention.
note"marketing_dependency"OptionalExtra advisory when retention is below 50%.
firstOrderDatestring | nullRequiredDate of the first paid order in the organisation (YYYY-MM-DD), null if none.
organisationAgeDaysnumberRequiredDays since the first paid order — used for the "younger than 2 years" gate.
periodsobject[]RequiredPeriods ordered newest first (idx 0 = floating current).
Single retention pair.
periodIdxnumberRequired0 = most recent (floating), N = N periods back.
labelstringRequiredHuman label, e.g. "2024 → 2025" or "Q2 2024 → Q2 2025".
baselineStartstringRequiredBaseline window start (YYYY-MM-DD).
baselineEndstringRequiredBaseline window end (YYYY-MM-DD).
currentStartstringRequiredCurrent window start (YYYY-MM-DD).
currentEndstringRequiredCurrent window end (YYYY-MM-DD).
isFloatingbooleanRequiredTrue if the current window is in-progress (truncated to today).
baselineCustomersnumberRequiredDistinct customers paying in baseline.
retainedCustomersnumberRequiredOf those, how many also paid in current.
lostCustomersnumberRequiredBaseline minus retained.
customerRetentionRatenumberRequiredretainedCustomers / baselineCustomers, in %.
baselineRevenuenumberRequiredRevenue in baseline from baseline customers.
currentRevenueFromBaselineCustomersnumberRequiredRevenue in current from those same baseline customers.
grossRetentionRatenumberRequiredGRR: SUM(MIN(current, baseline)) / SUM(baseline) — capped, no upsell.
netRetentionRatenumberRequiredNRR: SUM(current) / SUM(baseline) — can exceed 100% with upsell.
avgRevenuePerCustomerBaselinenumberRequiredAvg baseline revenue, averaged over retained customers (like-for-like).
avgRevenuePerCustomerCurrentnumberRequiredAvg current revenue, averaged over retained customers.
avgRevenuePerCustomerChangenumberRequiredPercentage change in avg spend from the same customers.
bandsobject[]RequiredPer-customer retention bands (6 fixed buckets).
band"growing" | "holding" | "declining" | "at_risk" | "critical" | "lost"RequiredcustomerCountnumberRequiredCustomers in this band.
customerPercentagenumberRequiredShare of baseline customers (0-100).
baselineRevenuenumberRequiredBaseline revenue from this band.
currentRevenuenumberRequiredCurrent revenue from this band.
stabilityobject | nullRequiredNull when warning.level is insufficient_data.
weightedRetentionnumberRequiredBaseline-weighted NRR across all periods (%).
weightedGrossRetentionnumberRequiredBaseline-weighted GRR across all periods (%).
volatilitynumberRequiredStandard deviation of NRR across periods (pp).
scorenumberRequiredStability score 0-100.
rating"excellent" | "good" | "moderate" | "concerning" | "critical"RequiredprojectedAnnualRevenuenumberRequiredEstimated revenue we can count on next period from existing customers.
currencyMixobjectRequiredCurrency situation — retention is computed only in the org default.
primaryCurrencyIdnumberRequiredOrg default currency ID.
primaryCurrencyCodestringRequiredOrg default currency code.
otherCurrenciesPresentbooleanRequiredTrue if orders in other currencies exist in the windows.
otherCurrenciesRevenuenumberRequiredTotal revenue ignored due to non-default currency.
{
"currency": "example_currency",
"warning": {
"note": "marketing_dependency",
"organisationAgeDays": 0
},
"periods": [
{
"periodIdx": 0,
"label": "example_label",
"baselineStart": "example_baselineStart",
"baselineEnd": "example_baselineEnd",
"currentStart": "example_currentStart",
"currentEnd": "example_currentEnd",
"isFloating": false,
"baselineCustomers": 0,
"retainedCustomers": 0,
"lostCustomers": 0,
"customerRetentionRate": 0,
"baselineRevenue": 0,
"currentRevenueFromBaselineCustomers": 0,
"grossRetentionRate": 0,
"netRetentionRate": 0,
"avgRevenuePerCustomerBaseline": 0,
"avgRevenuePerCustomerCurrent": 0,
"avgRevenuePerCustomerChange": 0,
"bands": [
{
"customerCount": 0,
"customerPercentage": 0,
"baselineRevenue": 0,
"currentRevenue": 0
}
]
}
],
"currencyMix": {
"primaryCurrencyId": 0,
"primaryCurrencyCode": "example_primaryCurrencyCode",
"otherCurrenciesPresent": false,
"otherCurrenciesRevenue": 0
}
}GET /bff/dashboard/revenue-retention
curl -X GET "https://api.bizkithub.com/bff/dashboard/revenue-retention?period=year" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY"All BizKitHub public API endpoints require authentication via API key.