{
  "schema": "leumas.docs.page/1",
  "id": "adapter:domain/saas-metrics",
  "slug": "adapters/domain/saas-metrics",
  "kind": "capabilities",
  "bucket": "package",
  "title": "saas-metrics",
  "name": "Saas Metrics",
  "eyebrow": null,
  "chip": null,
  "summary": "SaaS subscription-finance and recurring-revenue metrics pack for founders, RevOps, growth analysts and investors modelling a subscription business: compute Monthly Recurring Revenue (mrr) and Annual...",
  "keywords": [
    "saas-metrics",
    "subscription-finance",
    "revops",
    "investors",
    "arpu",
    "contraction",
    "lifetime",
    "churnrate"
  ],
  "audience": "both",
  "funnel": {
    "product": null,
    "cta": null
  },
  "body": "# saas-metrics\n\nSaaS subscription-finance intelligence pack. Deterministic recurring-revenue, unit-economics and\nboard-metric math for founders, RevOps and investors, with an optional AI commentary layer on the\ncohort and Rule-of-40 tools that activates only when a model is reachable (and silently falls back to\nthe heuristic core otherwise).\n\n**Estimates for planning/benchmarking only — not financial or investment advice.**\n\n## Tools\n\n| Tool | Args | Does |\n|---|---|---|\n| `mrr` | `{mrr \\| customers,arpu \\| plans[]}` | Monthly Recurring Revenue (+ ARR). Build from a flat number, customers×ARPU, or a `plans:[{price,customers,period}]` array. |\n| `arr` | `{arr \\| mrr \\| plans[]}` | Annual Recurring Revenue (+ implied MRR). |\n| `arpu` | `{revenue, customers, expansion?, contraction?}` | Average revenue per user/account, net of expansion/contraction. |\n| `ltv` | `{arpu, churn, grossMargin?}` | Lifetime value = ARPU × margin ÷ churn (constant-churn geometric model) + avg lifetime. |\n| `churnRate` | `{startCustomers, lostCustomers, newCustomers?}` | Churn %, retention %, end count, net change. |\n| `retentionCohort` | `{cohorts:[{sizes:[…]}], options?}` | Per-cohort retention %, averaged curve, stabilization flag. `options.advise` adds an AI read. |\n| `quickRatio` | `{newMrr, expansionMrr, churnedMrr, contractionMrr}` | SaaS Quick Ratio (growth efficiency) + grade. |\n| `magicNumber` | `{newArr \\| currentArr,priorArr; salesMarketingSpend}` | Sales Magic Number (efficiency) + implied payback. |\n| `ruleOf40` | `{growthRate, profitMargin, options?}` | Rule of 40 score, pass/fail, growth-vs-profit profile. `options.advise` adds an AI verdict. |\n| `netRevenueRetention` | `{startingMrr, expansionMrr, contractionMrr, churnedMrr}` | NRR + GRR %, ending MRR, grade. |\n| `cac` | `{spend, newCustomers \\| channels[]}` | Blended CAC, or per-channel CAC sorted cheapest-first. |\n| `paybackMonths` | `{cac, arpu, grossMargin?}` | CAC payback period in months + grade. |\n\nThe two tools with an AI path (`retentionCohort`, `ruleOf40`) tag their result `{ mode: 'heuristic' | 'llm' }`.\n\n## Example\n\n```js\nimport pack from './index.js';\nawait pack.adapters.ltv({ arpu: 100, churn: 0.05, grossMargin: 0.8 });\n// { ltv: 1600, arpu:100, churnRate:0.05, grossMargin:0.8, avgLifetimeMonths:20, … }\n\nawait pack.adapters.netRevenueRetention({ startingMrr: 100000, expansionMrr: 15000, contractionMrr: 4000, churnedMrr: 6000 });\n// { nrrPct:105, grrPct:90, endingMrr:105000, grade:'net-expanding', … }\n\nawait pack.adapters.quickRatio({ newMrr: 40000, expansionMrr: 10000, churnedMrr: 8000, contractionMrr: 2000 });\n// { quickRatio:5, addedMrr:50000, lostMrr:10000, grade:'excellent', … }\n```\n\n## DRY boundaries\n\n- **`finance`** owns time-value-of-money (NPV, IRR, loan amortization, discounted cash flow);\n  **`numbers`** owns generic scalar math and series stats; **`tax`** owns income-tax withholding;\n  **`invoice`** owns billing documents. This pack owns *subscription-business composition* —\n  recurring-revenue aggregation, cohort retention, unit economics (LTV/CAC/payback) and the SaaS board\n  ratios (Quick Ratio, Magic Number, Rule of 40, NRR/GRR) — which none of those own.\n- Self-contained: the only cross-pack import is `../_shared/llm.js` for the optional AI layer.\n\n## Hybrid intelligence\n\nEvery deterministic core runs offline with no model. `retentionCohort` and `ruleOf40` accept\n`options.advise:true` to request LLM commentary; with no model configured/reachable they return the\nexact same numbers tagged `mode:'heuristic'`. A down model never throws.\n",
  "source": {
    "path": "shared/engines/adapters/domain/saas-metrics/README.md",
    "blobSha": "",
    "commit": "",
    "committedAt": "",
    "provenance": "no-git",
    "bytes": 3795,
    "hash": "373aea236c025e36e05a9e551147857fb1066931"
  },
  "urls": {
    "html": "/p/adapters/domain/saas-metrics",
    "json": "/docs/adapters/domain/saas-metrics.json",
    "md": "/docs/adapters/domain/saas-metrics.md"
  },
  "links": {
    "composes": [],
    "usedBy": [],
    "product": [],
    "howTo": [],
    "skills": []
  }
}
