BizKitHub
DocsAPI ReferenceDashboard/bff/dashboard/revenue-retention
getDashboardAdmin BFF

/bff/dashboard/revenue-retention

Cohort-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.

DashboardgetBffDashboardRevenue-retention

Parameters

1 query

Query parameters

· 1
period"year" | "quarter"Optional

Granularity: yearly (3 pairs) or quarterly YoY (12 pairs). Defaults to year.

Default: year
Exampleyear

Response schema

1 status code documented

200SuccessYear-over-year revenue retention analysis.
period"year" | "quarter"Required

Granularity actually used.

currencystringRequired

Currency code for all revenue values (org default).

warningobjectRequired

Warning summary.

level"insufficient_data" | "healthy" | "low_retention"Required

Health classification of the latest (floating) retention.

note"marketing_dependency"Optional

Extra advisory when retention is below 50%.

firstOrderDatestring | nullRequired

Date of the first paid order in the organisation (YYYY-MM-DD), null if none.

One of 2:
Variant 1
string
Variant 2
null
organisationAgeDaysnumberRequired

Days since the first paid order — used for the "younger than 2 years" gate.

periodsobject[]Required

Periods ordered newest first (idx 0 = floating current).

Each array item:

Single retention pair.

periodIdxnumberRequired

0 = most recent (floating), N = N periods back.

labelstringRequired

Human label, e.g. "2024 → 2025" or "Q2 2024 → Q2 2025".

baselineStartstringRequired

Baseline window start (YYYY-MM-DD).

baselineEndstringRequired

Baseline window end (YYYY-MM-DD).

currentStartstringRequired

Current window start (YYYY-MM-DD).

currentEndstringRequired

Current window end (YYYY-MM-DD).

isFloatingbooleanRequired

True if the current window is in-progress (truncated to today).

baselineCustomersnumberRequired

Distinct customers paying in baseline.

retainedCustomersnumberRequired

Of those, how many also paid in current.

lostCustomersnumberRequired

Baseline minus retained.

customerRetentionRatenumberRequired

retainedCustomers / baselineCustomers, in %.

baselineRevenuenumberRequired

Revenue in baseline from baseline customers.

currentRevenueFromBaselineCustomersnumberRequired

Revenue in current from those same baseline customers.

grossRetentionRatenumberRequired

GRR: SUM(MIN(current, baseline)) / SUM(baseline) — capped, no upsell.

netRetentionRatenumberRequired

NRR: SUM(current) / SUM(baseline) — can exceed 100% with upsell.

avgRevenuePerCustomerBaselinenumberRequired

Avg baseline revenue, averaged over retained customers (like-for-like).

avgRevenuePerCustomerCurrentnumberRequired

Avg current revenue, averaged over retained customers.

avgRevenuePerCustomerChangenumberRequired

Percentage change in avg spend from the same customers.

bandsobject[]Required

Per-customer retention bands (6 fixed buckets).

Each array item:
band"growing" | "holding" | "declining" | "at_risk" | "critical" | "lost"Required
customerCountnumberRequired

Customers in this band.

customerPercentagenumberRequired

Share of baseline customers (0-100).

baselineRevenuenumberRequired

Baseline revenue from this band.

currentRevenuenumberRequired

Current revenue from this band.

stabilityobject | nullRequired

Null when warning.level is insufficient_data.

One of 2:
Variant 1
weightedRetentionnumberRequired

Baseline-weighted NRR across all periods (%).

weightedGrossRetentionnumberRequired

Baseline-weighted GRR across all periods (%).

volatilitynumberRequired

Standard deviation of NRR across periods (pp).

scorenumberRequired

Stability score 0-100.

rating"excellent" | "good" | "moderate" | "concerning" | "critical"Required
projectedAnnualRevenuenumberRequired

Estimated revenue we can count on next period from existing customers.

Variant 2
null
currencyMixobjectRequired

Currency situation — retention is computed only in the org default.

primaryCurrencyIdnumberRequired

Org default currency ID.

primaryCurrencyCodestringRequired

Org default currency code.

otherCurrenciesPresentbooleanRequired

True if orders in other currencies exist in the windows.

otherCurrenciesRevenuenumberRequired

Total revenue ignored due to non-default currency.

Response example

application/json
{
  "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
  }
}

Request example

GET /bff/dashboard/revenue-retention

get
curl -X GET "https://api.bizkithub.com/bff/dashboard/revenue-retention?period=year" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY"

Need an API key?

All BizKitHub public API endpoints require authentication via API key.

Get API Key