MRR Reconciliation Report: Stripe → Airtable → Claude → Slack Narrative
Every 1st of the month, this workflow pulls your Stripe data, reconciles MRR, writes a plain-English narrative via Claude, and posts it to Slack — no analyst required.
The stack in the order it runs — data flows from the source through to where it lands.
Manual MRR reconciliation takes about 2 hours and produces a spreadsheet nobody opens. The wall of numbers isn't the problem — the missing narrative is. Which cohort churned? Which plan drove expansion? What was net new MRR after you account for upgrades, downgrades, and pauses? Most founders skip the whole thing or pay someone to write it. Claude writes a better first draft than most analysts, in seconds.
Stripe's Subscriptions and Customers API gives you everything for a complete MRR waterfall: new subscriptions (new MRR), cancellations (churned MRR), plan changes (expansion/contraction MRR), and reactivations. Airtable holds the monthly snapshot — historical record, and the source Claude pulls last month's numbers from for comparison. The Claude API call uses a structured, templated prompt built from the reconciliation data, not a freeform chat message. n8n orchestrates it; Slack delivers it.
This is a monthly workflow, not a daily one. The insight density is higher and the audience is broader — founders, investors, the whole team. That's exactly why the narrative layer matters. Claude converts a reconciliation table into three sentences a non-technical co-founder reads in 30 seconds.
Don't use this if you're on Paddle or running complex billing — usage-based, per-seat enterprise — because the Stripe subscription model won't capture your actual MRR accurately. Pull from your internal billing database instead. Also: if your revenue data sits under audit requirements, keep the raw numbers in Airtable and only run Claude on the narrative layer. Never use Claude for the arithmetic.
The stack (5)
How it runs
- 1
Schedule the workflow for the 1st of each month at 7 AM
In n8n, create a workflow with Schedule Trigger cron '0 7 1 * *'. Calculate the reporting period as: month_start = first day of last month 00:00:00 UTC as Unix timestamp, month_end = last day of last month 23:59:59 UTC. Store both as workflow variables accessible by all downstream nodes. One calculation point — that's it. Date math bugs across 4+ API calls are a real problem; this prevents them.
- 2
Pull new subscriptions from Stripe
HTTP Request node to 'https://api.stripe.com/v1/subscriptions'. Params: 'created[gte]' = month_start, 'created[lte]' = month_end, 'status' = 'active', 'limit' = 100. For each subscription, extract: customer ID, plan ID, plan amount, plan interval (if annual, divide by 12 for MRR contribution), created timestamp. This is your New MRR input. Handle pagination with a Loop node — don't skip this if you have more than 100 active subscriptions.
- 3
Pull canceled and updated subscriptions from Stripe
Two HTTP Request nodes. First: 'https://api.stripe.com/v1/subscriptions' with 'canceled_at[gte]' = month_start and 'status' = 'canceled' — churned MRR. Second: 'https://api.stripe.com/v1/events' with 'type' = 'customer.subscription.updated' and 'created[gte]' = month_start — plan upgrades and downgrades. For the events endpoint, diff 'previous_attributes.plan.amount' vs 'data.object.plan.amount' per customer to compute expansion or contraction MRR.
- 4
Compute MRR waterfall in a Code node
Code node: pull the previous month's total MRR from Airtable (queried at workflow start via 'Get Records' filtered to last month's row), then: add new MRR, subtract churned MRR, add expansion MRR, subtract contraction MRR. Output this object: { month, starting_mrr, new_mrr, churned_mrr, expansion_mrr, contraction_mrr, ending_mrr, net_new_mrr, churn_rate_pct, growth_rate_pct, new_customer_count, churned_customer_count }. All amounts in USD cents converted to dollars. churn_rate_pct = churned_mrr / starting_mrr * 100.
- 5
Store monthly snapshot in Airtable
Airtable 'Create Record' node targeting your 'MRR History' table. Map all waterfall fields. Set a 'Report Status' field to 'Pending Review' — you change it to 'Reviewed' manually after verifying the numbers. This record becomes the starting MRR for next month's run. Never delete rows from this table. It's your financial audit trail.
- 6
Generate narrative with Claude API
HTTP Request node to 'https://api.anthropic.com/v1/messages'. Auth: x-api-key header with your Claude API key. Model: 'claude-opus-4-5'. Build the prompt in a Set node before this step: 'You are writing a monthly MRR recap for a SaaS founder to share with their team. Be direct, specific, and use the exact numbers provided. Do not add caveats or filler sentences. Data: [inject waterfall object as JSON]. Write 3-4 sentences covering: what happened to MRR overall, the biggest driver (new/churn/expansion), churn rate vs last month, and one sentence on what to watch next month based on these trends.' Max tokens: 300.
- 7
Format and post to Slack with narrative + numbers
Slack 'Send Message' node to #founders or #monthly-metrics. Block Kit structure: header block 'MRR Recap — [Month Year]', a section block with the Claude narrative, a divider, then a fields block with waterfall numbers in two columns — Starting MRR / Ending MRR in row one, New / Churned in row two, Expansion / Contraction in row three, Net New / Growth % in row four. After posting, add a Slack 'Pin Message' node using the message timestamp returned from the post step. Pin it.
- 8
Send a reconciliation exception alert if numbers look wrong
Add an IF node before the Slack post. Conditions: if ending_mrr < 0, OR churn_rate_pct > 20, OR new_customer_count == 0 AND starting_mrr > 1000 — route to an alert Slack message tagging the founder: '⚠️ MRR reconciliation anomaly detected — please verify Stripe data before sharing this report.' These edge cases almost always mean a subscription plan is misconfigured or the date range caught a billing cycle edge. Post a wrong number to the whole team once and you'll wish you'd built this check.
Want me to build this for you instead?
Product Audit and CTO Mode run out of this same thinking. If you’re reading this thinking “I want this, but in my product” — let’s talk.
See servicesMore like this
Google Analytics 4 + HubSpot Lifecycle Stage: Weekly Acquisition-Quality Digest to Slack via Pipedream with Claude Narrative
Stop reporting traffic numbers. Report whether the traffic you paid for last week actually became pipeline — with a one-paragraph executive summary written by Claude.
Gmail Thread Aging + Stripe Invoice Overdue: Unified AR Follow-Up Digest to Slack via Zapier
Surface overdue Stripe invoices and the exact age of your last Gmail thread with that customer — every morning at 8:30, automatically — so AR follow-up stops living in someone's head.
Outlook Calendar Load + HubSpot Deal Velocity: Weekly Ops Digest to Microsoft Teams
Every Monday at 07:30, your revenue team gets one Teams card: last week's deal pipeline movement next to each rep's actual meeting load — so you stop guessing whether low close rates are a pipeline problem or a capacity problem.