Most founders I know refresh the Stripe dashboard five or six times a day. They scroll the timeline, mentally subtract this morning's failed-payment notification, and decide whether the week is good or bad based on a vibe. The vibe is usually wrong, in both directions. A few good days bury a slow churn drift; a few bad days panic a quarter that is fine. Stripe is a system of record, not a reporting tool, and using it that way costs an hour a day in scroll plus a percentage of conviction.
The fix is a 90-second morning digest. One Slack message with MRR, net new, churn, expansion, failed payments, and any flagged anomalies. Posted at 9 a.m. local time, before the inbox opens. A weekly version on Monday with cohort retention and plan-level breakdown. Pulled nightly from the Stripe API, computed with the same math Baremetrics and ChartMogul use, never touching the account. This post is how that agent is built and what it should and should not do.
What this agent does
Once a night, the agent pulls subscriptions, invoices, charges, refunds, and balance transactions from Stripe. It normalizes every recurring price to a monthly equivalent, computes the five MRR movements for the previous day and the trailing 7 and 30 days, breaks the numbers down by plan and signup cohort, runs anomaly detection on every series, and posts a digest to Slack or email at the time you configured.
What it does not do: charge customers, refund customers, change subscriptions, send dunning emails, or modify any Stripe object. That is a different agent. Specifically, the failed-payment recovery one. See AI agent for Stripe failed-payment recovery for that pattern. This agent reports, the sibling agent acts. Keeping them separate is the whole point of the read-only scope. For the broader read-only versus write distinction, see what an AI agent can actually do.
Sources of truth
Stripe is the only source for revenue numbers. The agent does not maintain a parallel ledger. It reads, normalizes, and reports.
- Subscriptions. Every active and trialing subscription, with the attached price object, quantity, and any discount or coupon.
- Invoices. Status, amount paid, amount remaining, refunded amount, period start and end.
- Charges and refunds. Used to reconcile invoice paid amounts and detect refund patterns.
- Balance transactions. The post-fee net, useful for the cash view when it differs from the accrual view.
- Customers. Metadata, signup date, plan history. No personal data leaves Stripe.
The first run reads the trailing 13 months so the agent can compute year-over-year and the full cohort grid. Subsequent runs are incremental, using the created[gte] filter on each list endpoint and a saved cursor for events. Stripe's API is paginated and rate limited; the agent respects both, with retries on 429 and an exponential backoff. The math itself is well documented; ChartMogul and Baremetrics both publish how they compute MRR, and the agent follows the same rules with no creative deviation.
The metrics that matter
Six metrics matter for a founder running a subscription business. The agent computes all six on every run.
- MRR and ARR. Sum of normalized monthly recurring revenue across active subscriptions. ARR is MRR times 12. One-time charges, setup fees, and metered usage above the base plan are excluded from MRR by default; they appear in the "other revenue" line.
- Net new MRR. New plus expansion minus contraction minus churn plus reactivation. The number that should track upward; if it does not, one of the components explains why.
- Gross and net churn. Gross is MRR lost to cancellations and contractions divided by MRR at the start of the period. Net subtracts expansion. Most SaaS targets are net-negative monthly churn at scale; the agent flags when gross churn exceeds 5 percent in a single month, a common alarm threshold.
- ARPU and ARPA. Average revenue per user, average revenue per account. Useful split by plan to detect drift toward the cheap tier.
- Failed-payment rate. Failed charges divided by attempted charges in the period. Read-only here. The action lives in the sibling agent.
- Retention cohort grid. A 12-month cohort heatmap showing MRR retention by signup month. The agent generates the SVG and links to it from the weekly digest.
Each metric carries a breakdown by plan and a cohort overlay. The plan breakdown is what stops a founder from being surprised when a single popular plan is masking a problem in another.
Anomaly detection logic
Anomaly detection on small subscription businesses is a trap if you use generic thresholds. A 3 percent daily churn is alarming for a 10,000-customer SaaS and meaningless for a 200-customer one. The agent uses your own rolling baseline, not a textbook number.
Four detectors run on every batch.
- MRR spike or drop. Compare today's net new MRR against the rolling 14-day mean and standard deviation. Flag if it is more than 2 standard deviations off, in either direction. A spike is as worth flagging as a drop; spikes are usually a billing error or a duplicate subscription.
- Churn cluster. Three or more cancellations from the same plan or the same signup cohort within a 48-hour window. This is the early signal of a product-shaped problem; one off-cohort cancellation is noise, three is a pattern.
- Refund pattern. Refunds in the last 24 hours exceeding the 30-day rolling baseline by 50 percent or more. Refund patterns precede chargeback patterns, so this one matters.
- Failed-payment surge. Failed-charge rate in the last 24 hours more than 1.5 times the 7-day baseline. Often a card-network issue rather than a customer issue; either way, founder should know before the daily auto-retry has finished.
Each anomaly is one line in Slack with the metric, the magnitude, the affected customer count, and a link to the underlying list of subscription IDs. The agent never speculates on cause; it surfaces what changed and lets the founder click through.
Digest formats
Two digests, both pushed.
Daily, 9 a.m. local. Six lines. Yesterday's net new MRR with the delta against the 14-day average. Count of new paying customers. Count of churns. Count of failed payments. Anomaly flags, if any. A link to the full snapshot page. The whole thing fits on a phone screen and reads in under 30 seconds. The Slack integration pattern is in how to connect an agent to Slack.
Weekly, Monday 8 a.m. local. Longer. MRR by plan with last-week comparison. Expansion and contraction broken out. Cohort retention heatmap for the last 6 months as an embedded image. Top 5 expansions and top 5 churns, each with the plan and customer tenure, no names or emails. A trailing-30 versus prior-30 view of the failed-payment rate. The weekly is for the Monday review meeting or the solo planning hour.
Both digests are also available as a static HTML snapshot in case Slack is down or the founder wants to share the link with an investor.
Guardrails
- Read-only API key. Restricted key with read scopes only. The Stripe dashboard shows the exact scopes, and the agent fails loudly on startup if the key has any write permission.
- No PII in the digest. Customer counts, plan names, and tenure in days. No emails, no company names, no support-ticket excerpts.
- No automated actions. The agent posts, the founder decides. It does not open a ticket, it does not message a customer, it does not change a plan.
- Audit log of every run. Run start, run end, row counts, anomalies detected, digest IDs. Stored in append-only storage. See how to monitor agent activity for the broader pattern.
- Scope-fail tests on deploy. Before each release, an integration test attempts a write call and asserts the API returns a 403. If it does not fail, the deploy halts.
- Kill switch in Slack. One slash command pauses the agent. The same pattern covered in how to limit agent actions and AI agent safety and guardrails.
Common mistakes
- Including one-time charges in MRR. The number inflates, then drops the next month, and the founder loses trust in the report. Setup fees, professional services, and metered overages live in "other revenue".
- Double-counting upgrades as new MRR. A plan upgrade is expansion, not new. The agent must subtract the prior subscription's MRR before adding the new one, otherwise the new-MRR line is fiction.
- Ignoring refunds. A refund issued today against an invoice paid 60 days ago should reduce the current period's net revenue. Most founder-built spreadsheets miss this and show a happier number than reality.
- Treating trialing subscriptions as MRR. They are pipeline, not revenue. The agent excludes
trialingandincompletestatuses from MRR until the first paid invoice posts. - Daily churn-rate alarms on small bases. One cancellation on a 100-customer SaaS is 1 percent daily churn, which is not an emergency. Use rolling baselines, not absolute thresholds.
- One number, no breakdown. The number rises while a plan is dying. Always show by-plan and by-cohort.
- Letting the agent send anything to customers. If the scope expands to write, it stops being this agent. Spin up a separate one with a narrow write scope. The economics of that split, including why two narrow agents beat one wide agent on cost and risk, are in economics of bootstrapped AI agents.
Frequently asked questions
Does the agent touch my Stripe account?
No. The agent is read-only. It uses a restricted Stripe API key with read scopes on customers, subscriptions, invoices, charges, and balance transactions. It cannot create, modify, or refund anything. If you want an agent that acts on failed payments, that is a separate sibling agent with its own narrow write scope.
How does the agent calculate MRR so I can trust the number?
It walks active subscriptions, normalizes every interval to a monthly equivalent (annual divided by 12, quarterly divided by 3), subtracts coupon and percentage-off discounts, ignores one-time invoice items, and excludes subscriptions in trialing or incomplete status. Movements are decomposed into new, expansion, contraction, churn, and reactivation. The math matches the ChartMogul and Baremetrics definitions, with the same exclusion rules.
What anomalies does it flag?
Spikes or drops in MRR larger than the rolling 14-day standard deviation, a cluster of three or more churns from the same plan or signup cohort in a 48-hour window, a refund rate that exceeds the 30-day baseline, and a failed-payment rate that exceeds the 7-day baseline. Each anomaly is a Slack message with the underlying customer count and the suggested next step. The agent never guesses cause; it surfaces signal.
What goes in the daily digest versus the weekly digest?
Daily is a 6-line Slack post: yesterday's net new MRR, count of new customers, count of churns, count of failed payments, anomaly flags, and a link to the full snapshot. Weekly is longer: MRR by plan, expansion and contraction, retention cohort heatmap for the last 6 months, top 5 expansions, top 5 churns with their plan and tenure, and a comparison to last week. The daily fits on a phone screen; the weekly is for the Monday review.
Why not just use Baremetrics or ChartMogul?
You can. The agent is for founders who do not want a third dashboard, do not want another login, and want the numbers pushed to where they already work each morning. The math is the same. The difference is delivery surface and anomaly detection that is tuned to your own baseline rather than a generic threshold.
Three takeaways before you close this tab
- Read-only is the feature. A reporting agent that cannot write is one you do not have to babysit.
- Five movements beat one number. MRR moved, but how? New, expansion, contraction, churn, reactivation.
- Push the digest. Slack at 9 a.m. beats a dashboard you open at 11 p.m.
Sources
- Stripe Docs, "API reference: Subscriptions, Invoices, Balance transactions", retrieved 2026-05-12, stripe.com/docs/api
- ChartMogul, "How to calculate MRR: the definitive guide", retrieved 2026-05-12, chartmogul.com/resources/calculate-mrr
- Baremetrics, "MRR: the metric you need to know", retrieved 2026-05-12, baremetrics.com/academy/mrr
- SaaS Capital, "Spending benchmarks for private B2B SaaS companies", retrieved 2026-05-12, saas-capital.com/research/spending-benchmarks
- Stripe, "Restricted API keys", retrieved 2026-05-12, stripe.com/docs/keys#limit-access