.NET React Templates
Features

Usage analytics

Usage analytics turns the same normalized meter events used for enforcement into customer and operator visibility.

Usage and quotas

Customer APIs

  • GET /saas/usage/analytics?meterKey={key}&days={7..365} — current summaries, daily series, per-user breakdown, rejected operations, and period-end projection.
  • GET /saas/usage/export?meterKey={key}&days={7..365} — CSV export.

Both require analytics.basic. Advanced breakdowns can be gated with analytics.advanced when extending the UI. The requested window is clamped to configured retention.

The /usage page shows one card per meter with its allowance, reset date, remaining units, and reservations; selecting a card loads its 30-day series and per-member breakdown, and a meter with no activity in the window shows an empty state instead of a blank chart. The /dashboard API activity chart reads the same endpoint for api.requests over 14 days.

The /usage page should fetch when the organization, meter, or date range changes. Keep request parameters and callback dependencies stable to avoid render-driven request loops.

Customer Usage Dashboard and Analytics

Data flow

Successful quota operations append UsageEvent rows and update period aggregates. BuildUsageRollupsCommand periodically writes UsageDailyRollup rows by organization and, when allowed by the meter definition, by user. Analytics reads rollups and falls back to raw events when a rollup is not yet available.

Saas.AnalyticsRetentionDays controls the global history window. Each meter's AllowCustomerBreakdown and AllowUserBreakdown flags control safe dimensions; do not add high-cardinality or sensitive dimensions casually.

SaaS-admin analytics

GET /saas/admin/analytics provides platform metrics, organization growth, plan mix, and quota pressure for Admin users. Quota pressure is the organizations that have used at least 80% of an allowance in a period that's still in effect. Customers who canceled aren't included, as their data is measured against the Free plan they fall back to, nor is a single-user plan's one seat that's taken. These appear at /admin/usage and in the /admin overview. Customer 360 at /admin/customers includes current usage summaries for support and billing diagnosis.

Platform Usage Analytics and Quota Pressure

Revenue history

BuildSaasDailySnapshotCommand records each day's platform metrics in SaasDailySnapshot, one row per metric and dimension, which is the history operator trends are charted from. Its revenue metrics come from SaasRevenue, which estimates recurring revenue from the local projection of subscriptions and the plan catalog's prices, so it never queries Stripe:

MetricValue
revenue.mrrMonthly recurring revenue of active and past-due subscriptions, overall (all) and for each plan (plan:<code>)
revenue.arrTwelve times MRR
revenue.trialing_mrrWhat current trials would add to MRR if they converted
revenue.arpaAverage revenue per paying account
subscriptions.payingBilled subscriptions on a paid price

A subscription's monthly amount is its Stripe price when that price is in the catalog, otherwise its plan version's price for its interval, with annual prices divided by twelve. The estimated MRR in the admin analytics uses the same calculation, so the current value matches its history. It is an estimate: Stripe owns coupons, discounts, taxes, and credits, and a negotiated price that isn't in the catalog, such as a contact-sales contract, counts as zero.

Revenue movement

GET /saas/admin/revenue (GetRevenueMetrics) returns current MRR, ARR, trial pipeline, ARPA, and MRR by plan, MRR over time from the snapshots (each day for up to 3 months of history, otherwise each week), the ten largest customers, and for each of up to 12 months its starting and ending MRR with what moved it. Movement comes from the billing:subscription.changed audit events: a change from no MRR to some is new, from some to none is churn, and an increase or decrease is expansion or contraction. It requires an operator who can manage billing (Admin or BillingAdmin).

Customer health

GET /saas/admin/customer-health (GetCustomerHealth) scores each customer from 0 to 100, least healthy first, with each signal that changed its score:

SignalPoints
Payment past due−30
Subscription paused−20
Failed payments in the last 90 days−10 each, up to −20
No usage recorded, or none in 14 days−25
No usage in 7 days−10
API requests down 50% or more on the previous 30 days−30
API requests down 25% or more on the previous 30 days−15
90% or more of the current period's API allowance used−10

Scores of 80 and above are Healthy, 55 and above Watch, and below that AtRisk. Canceled subscriptions are Churned, and are only returned when asked for. Usage trends need 60 days of history and at least 100 requests in the previous 30 days. Customers whose usage grew 25% or more, or who have used 75% of their API allowance, are marked as expansion candidates. It requires ViewCustomers; what customers pay and how many payments failed are only returned to operators who can manage billing.

Adding analytics to a feature

  1. Register a meter in Saas.Meters.
  2. Add allowances to relevant plan drafts and publish them.
  3. use reserve/settle for fallible or variable work, or atomically consume for simple work;
  4. record a stable action/source and user for useful attribution;
  5. add customer-safe visualization and CSV labels;
  6. verify hard-limit rejection and period rollover.

Do not maintain a separate analytics counter beside quota state. One metering path prevents billing, enforcement, and dashboards from disagreeing.

Verify

Generate accepted and rejected operations across several users and days. Compare aggregate, chart, projection, and CSV values; run rollups more than once; test a reset boundary, retention cutoff, disabled breakdown, and organization isolation.