Stripe
Billing signals: seats, plan changes, failed payments, and MRR.
Category: Billing · Auth: Secret API key (or Connect OAuth)
Stripe is the richest commercial signal for most SaaS accounts. Money is the clearest statement of intent a customer makes — who's expanding, who's downgrading, and who's about to lapse on payment shows up in Stripe before it shows up anywhere else. Wiring it in means your churn score reacts to a failed renewal or a seat reduction the moment it happens, not at the next QBR.
What it pulls
- Seat & license counts — current seats used vs purchased, from subscription quantities.
- Plan upgrades & downgrades — tier changes that signal rising or falling commitment.
- Failed payments & dunning — the most direct pre-churn signal there is.
- MRR / ARR per account — the revenue at stake, used to weigh how much a churn would cost.
Signals it feeds
Stripe lights up the commercial and growth side of the score:
- Seats used vs purchased (
seat_purchased,seat_used) — utilization is a leading downgrade signal. - Plan upgrades and Seat expansion (
plan_upgraded,seat_expanded) — positive growth flags. - Contract value (MRR tier) — sets the revenue-at-risk band that prioritizes who to save first.
Setup
- In ChurnWarn, open Settings → Integrations → Stripe and choose Connect.
- In your Stripe dashboard → API keys, create a restricted key with read access to Customers, Subscriptions, and Invoices.
- Paste the key into ChurnWarn and save.
- Map Stripe customers to your accounts by email or the Stripe customer id.
- Press Sync now to backfill recent subscriptions and confirm signals land on the right accounts.
ChurnWarn only needs read access. Create a restricted key scoped to Customers, Subscriptions, and Invoices rather than your live secret key — if it ever leaks, the blast radius is read-only billing data.
Staying in sync
After the initial backfill, Stripe webhooks keep billing signals current in near-real-time — a failed payment or a plan change updates the account within seconds. Use Sync now whenever you want to force a fresh pull, and watch the integration's last sync and last error indicators to catch an expired or under-scoped key.
Reference: Stripe API keys documentation.