"Check Stripe SaaS metrics from the terminal. Use when you need MRR, churn, LTV, NRR, ARPU, customer counts, MRR movements, reactivations, or a full dashboard. Triggers on 'check MRR', 'what's our churn', 'stripe metrics', 'how many customers', 'revenue breakdown', 'returning customers', 'reactivations', 'export metrics', or any Stripe analytics question. Runs `stripe-pulse` CLI commands and parses JSON output."
Resources
9Install
npx skillscat add viiralbeary/stripe-pulse Install via the SkillsCat registry.
stripe-pulse — Stripe SaaS Metrics CLI
Get MRR, ARR, churn, LTV, NRR, quick ratio, MRR movements, reactivations — directly from Stripe subscriptions.
Install: npm install -g stripe-pulse
Quick check: stripe-pulse mrr --json
Everything at once: stripe-pulse dashboard --json
When to Use
- User asks about MRR, revenue, churn, customers, or any SaaS metric
- User asks about returning customers, reactivations, or win-backs
- Updating pulse.md or state files that track MRR
- Running freshness guards that check Stripe data
- User wants to export metrics (CSV, markdown, JSON)
- User says "check stripe", "what's our MRR", "how's churn looking", "any reactivations"
- Comparing metrics across profiles/accounts
Quick Start
# First time: authenticate
stripe-pulse login
# Check MRR
stripe-pulse mrr --json
# → { "mrr": 392, "arr": 4704, "currency": "usd", "activeSubscriptions": 18, "breakdown": [...] }
# Full dashboard (most efficient — one call, all metrics)
stripe-pulse dashboard --json
# → { "mrr": ..., "churn": ..., "reactivatedCustomers": ..., "reactivations": [...], ... }Authentication
Three-tier auth chain (highest priority wins):
--api-key <key>flag on any commandSTRIPE_API_KEYenvironment variable- Credentials file at
~/.config/stripe-pulse/credentials.json
Multi-account: stripe-pulse mrr --profile activecalculator --json
Supports full keys (sk_live_*, sk_test_*) and restricted keys (rk_live_*, rk_test_*).
Commands
Single Metrics
| Command | Returns | Key Fields |
|---|---|---|
mrr --json |
MRR + breakdown | mrr, arr, activeSubscriptions, breakdown[] |
arr --json |
Annual run rate | arr, mrr |
customers --json |
Count by status | activeSubscribers, trialingCustomers, pastDueCustomers |
arpu --json |
Avg revenue/user | arpu |
ltv --json |
Lifetime value | ltv, avgLifespanMonths, monthlyChurnRate |
plans --json |
Revenue by plan | [{ productName, mrr, subscriptionCount, interval }] |
trials --json |
Trial conversion | conversionRate, trialsStarted, trialsConverted |
Period Metrics (default: last 30 days)
| Command | Returns | Key Fields |
|---|---|---|
churn --json |
Customer churn % | customerChurnRate, customersLost, reactivatedCustomers |
revenue-churn --json |
Revenue churn % | revenueChurnRate, mrrLost |
nrr --json |
Net revenue retention | nrr, expansionMrr, churnedMrr |
quick-ratio --json |
Growth efficiency | quickRatio, reactivationMrr (>4 excellent, >1 healthy) |
movements --json |
MRR waterfall | newMrr, expansionMrr, contractionMrr, churnedMrr, reactivationMrr, netNewMrr, reactivations[] |
Period flags: --from 2026-01-01 --to 2026-01-31
Customer Lists
| Command | Returns | Key Fields |
|---|---|---|
new-customers --json |
New in period | count, reactivatedCount, reactivations[], customers[].email, .mrr |
churned --json |
Churned in period | count, customers[].email, .canceledAt |
active --json |
All active (by MRR desc) | count, customers[].email, .mrr |
Dashboard (All-in-One)
stripe-pulse dashboard --jsonReturns every metric in one call: mrr, arr, activeSubscribers, arpu, customerChurnRate, revenueChurnRate, ltv, nrr, quickRatio, reactivatedCustomers, reactivations[], trialConversionRate, mrrByPlan[], currency, dataAsOf.
This is the most efficient call. Use it when you need multiple metrics — one API batch instead of many.
Auth & Diagnostics
| Command | Purpose |
|---|---|
login |
Save Stripe API key (interactive) |
login --key sk_xxx --profile name |
Non-interactive login |
logout |
Remove credentials |
switch <profile> |
Switch active profile |
whoami --json |
Show profile, masked key, mode |
doctor --json |
Diagnostic checks (version, node, API key, connection) |
Global Flags
| Flag | Effect |
|---|---|
--json |
Force JSON output |
--profile <name> |
Use specific Stripe account |
--api-key <key> |
Override API key for this request |
--from <date> |
Period start (YYYY-MM-DD) |
--to <date> |
Period end (YYYY-MM-DD) |
--format csv |
CSV output (for export) |
--format markdown |
Markdown table (for docs/updates) |
--verbose |
Extended output (reactivation details, extra context) |
--chart |
ASCII chart (MRR trend, plan bars) |
--quiet |
Suppress stderr, implies --json |
Auto-JSON: When stdout is piped (non-TTY), JSON is automatic. No --json needed.
Reactivation Tracking
When a customer cancels and later resubscribes, Stripe creates a new subscription ID. stripe-pulse detects this by matching customer IDs across canceled and new subscriptions.
Classification rules:
- Matches at the customer ID level (industry standard — same as Baremetrics, ChartMogul, ProfitWell)
- Only paid reactivations count — free-tier returns are excluded (
mrrCents > 0) - 24h minimum gap — cancel/resub within 24 hours is treated as a plan switch, not reactivation
- One per customer — if a customer creates multiple new subs, only the most recent counts
- Churn still counts — reactivation is a separate positive MRR movement, not a reversal
Quick Ratio formula: (New + Expansion + Reactivation) / (Churn + Contraction)
Where reactivation data appears:
| Command | Fields |
|---|---|
dashboard --json |
reactivatedCustomers, reactivations[] |
movements --json |
reactivationMrr, reactivations[] |
churn --json |
reactivatedCustomers (netted from customersLost for same-period) |
new-customers --json |
reactivatedCount, reactivations[] (filtered from customer list) |
quick-ratio --json |
reactivationMrr (in numerator) |
Reactivation detail object:
{
"customerId": "cus_abc",
"previousSubscriptionId": "sub_old",
"newSubscriptionId": "sub_new",
"canceledAt": "2026-01-15",
"reactivatedAt": "2026-03-01",
"mrrCents": 2900
}Output Formats
# JSON (for parsing)
stripe-pulse mrr --json
# CSV (for spreadsheets)
stripe-pulse active --format csv > customers.csv
# Markdown (for investor updates)
stripe-pulse dashboard --format markdown
# Chart (MRR trend + movements waterfall)
stripe-pulse mrr --chartExit Codes
| Code | Meaning |
|---|---|
0 |
Success |
1 |
API error (Stripe call failed) |
2 |
Auth error (no key, invalid key) |
3 |
Validation error (bad date, bad option) |
Gotchas
- Always use
--jsonwhen parsing output. Human output has ANSI colors that break parsing. Piped stdout auto-switches to JSON. dashboard --jsonis more efficient than individual commands. One parallel batch vs many sequential calls. Use it when you need 2+ metrics.customerscounts unique customers,mrrcounts subscriptions. A customer with 2 subscriptions = 1 customer but 2 inactiveSubscriptions.- Historical MRR (
--chart) is approximate. Reconstructed from subscription timestamps using current pricing. Doesn't reflect past price changes. - Period defaults to last 30 days. Always pass
--from/--tofor specific periods. - Restricted keys work but show less info. Product names may show as price IDs if product read permission is missing.
- Benchmark strings only appear in human output. JSON has raw numbers only — no "⚠ High" or "✓ Good" strings.
- MRR breakdown is coupon-aware. Forever-duration discounts are distributed proportionally across plan items.
new-customerstotalMrr vsmovementsnewMrr can differ.new-customerscounts all subs created in period (including already-canceled).movementsonly counts currently active ones.- Designed for early-stage SaaS (up to ~10,000 subscriptions). Under 500 subs: 2-3 seconds. 2,000+ subs: 15-30 seconds. No caching between commands.
Common Patterns
Get a single number
stripe-pulse mrr --json | jq .mrr
# → 392Check if churn is concerning
stripe-pulse churn --json | jq '.customerChurnRate > 10'
# → true/falseGet churned customer emails
stripe-pulse churned --json | jq -r '.customers[].email'Check for reactivations
stripe-pulse movements --json | jq '.reactivations'
# → [{ customerId, previousSubscriptionId, newSubscriptionId, canceledAt, reactivatedAt, mrrCents }]
stripe-pulse dashboard --json | jq '.reactivatedCustomers'
# → 2Compare two accounts
stripe-pulse mrr --profile activecalculator --json | jq .mrr
stripe-pulse mrr --profile teamai --json | jq .mrrDiagnose connection issues
stripe-pulse doctor --json | jq '.checks[] | select(.status == "fail")'