Mixpanel Funnel + Stripe MRR Overlap: Daily Activation-to-Revenue Health Check to Microsoft Teams via Pipedream
Know before standup whether yesterday's activated users converted to paid — not after you've burned a sprint on the wrong fix.
The stack in the order it runs — data flows from the source through to where it lands.
The gap between 'user activated' (a Mixpanel event) and 'user paid' (a Stripe charge) is where early-stage SaaS quietly bleeds. Most teams check these in separate dashboards, weekly at best. By the time they spot a drop, they've already wasted a sprint on a feature that wasn't the problem.
Pipedream is the right glue here. It's code-first — Node.js or Python steps, no infrastructure to spin up. The Mixpanel JQL/Insights API and Stripe API both return JSON that's trivial to join in a single code step. Pipedream's built-in Microsoft Teams action handles Adaptive Card formatting so the digest is actually readable — plain webhook posts look terrible in Teams. n8n could do this too, but Pipedream's managed hosting and per-step error logs make debugging Mixpanel query pagination far less painful.
The real tradeoffs: Pipedream's free tier gives you 10,000 invocations/month — a daily workflow costs 30, so you're fine there. The harder one is that Mixpanel's API returns event counts, not user-level conversion paths, unless you use JQL, which requires the Growth plan or above. On Mixpanel's free tier you can substitute the Insights API for aggregate funnel data, but you lose cohort-level granularity. Stripe's API is reliable but rate-limited at 100 requests/second — for large catalogs, add a 200ms delay between paginated requests.
Skip this if you already have a BI layer — Metabase on a Postgres replica, Looker Studio pulling from BigQuery, anything like that. This is purpose-built for teams under ~5,000 MAU who haven't invested in a data warehouse yet and need a daily signal without hiring a data engineer.
The stack (4)
Chat + channels for Microsoft-365 shops.
If the company is on Outlook/365, Teams is where reports get read — push there, not a separate tool.
How it runs
- 1
Create a Pipedream workflow with a daily schedule trigger
In Pipedream, create a new workflow. Set the trigger to 'Schedule' with cron expression `0 7 * * *` (7 AM UTC — adjust to your team's timezone). Name it 'Daily Activation-to-Revenue Health Check'. Under workflow settings, set timeout to 60 seconds — the Mixpanel API drags on large event sets. Enable 'Auto-retry on failure' with 2 retries. That's it. Fires every morning before standup.
- 2
Pull yesterday's funnel data from Mixpanel Insights API
Add a Node.js code step. Use `axios` to POST to `https://mixpanel.com/api/2.0/insights` with Basic Auth — your Mixpanel Service Account username and secret as the password. Request body: `{ 'bookmark_id': YOUR_FUNNEL_BOOKMARK_ID, 'from_date': yesterday_YYYY-MM-DD, 'to_date': yesterday_YYYY-MM-DD }`. If you haven't saved a funnel bookmark, use the Funnels API instead: `https://mixpanel.com/api/2.0/funnels` with params `funnel_id`, `from_date`, `to_date`, `interval=1`. Parse out three numbers: total users who entered the funnel, total who completed the activation event (e.g., 'Project Created' or 'First Report Viewed'), and the conversion rate.
- 3
Pull new Stripe subscriptions and MRR delta for the same day
Add a second Node.js code step. Call `https://api.stripe.com/v1/subscriptions` with params `created[gte]` (yesterday 00:00:00 UTC as Unix timestamp), `created[lte]` (yesterday 23:59:59 UTC), `status=active`, `limit=100`. Paginate using `has_more` + `starting_after`. For each subscription, extract `plan.amount` and `plan.interval` — normalize everything to monthly (divide annual by 12). Sum to get `new_mrr_yesterday`. Then call `https://api.stripe.com/v1/subscriptions?status=canceled&canceled_at[gte]=...` for the same window to get churned MRR. Net MRR delta = new_mrr minus churned_mrr.
- 4
Compute the activation-to-paid conversion ratio
In a third code step, join the two datasets. The key metric: `activation_to_paid_rate = new_stripe_customers_yesterday / mixpanel_activated_users_yesterday * 100`. To do exact matching, you need the Stripe customer email cross-referenced against Mixpanel's `$email` property — straightforward if you've set `distinct_id` to email in Mixpanel. If not, treat the ratio (new paid / new activated) as a directional signal, not an exact overlap. Also compute the 7-day rolling average from your last 6 stored data points, stored in Pipedream's `$store` key-value store using `this.$store.set('day_N', value)`.
- 5
Store daily snapshot for trend comparison
Add a code step that reads the last 6 days of data from Pipedream's built-in `$store` via `this.$store.get('history')` — structured as a JSON array. Append today's data point: `{ date, activated_users, new_paid_users, activation_to_paid_rate, net_mrr_delta }`. Trim the array to 7 entries max. Write it back with `this.$store.set('history', updatedArray)`. No external database needed. One caveat: if your history data goes above 1MB, move to Airtable as your data store instead.
- 6
Format the Microsoft Teams Adaptive Card
Add a code step that builds the Teams Adaptive Card JSON payload. Structure: a header row with the date and a status emoji (🟢 if `activation_to_paid_rate` is above your baseline, 🔴 if it's dropped more than 20% below), a facts block showing `Activated Users Yesterday`, `New Paid Conversions`, `Activation-to-Paid Rate`, and `Net MRR Delta`, plus a 7-day trend line as an ASCII sparkline (e.g., `▂▃▅▄▆▃▇`). Generate the sparkline by mapping the 7-day `activation_to_paid_rate` array to Unicode block characters. Include a button linking to your Mixpanel funnel dashboard URL.
- 7
Post to Microsoft Teams via webhook
Add the built-in Pipedream 'Microsoft Teams' action, or use an HTTP Request step pointing at your Teams incoming webhook URL (create it via: Teams channel → Connectors → Incoming Webhook → copy URL). Set Content-Type to `application/json` and post the Adaptive Card payload. For the full Adaptive Card schema to render — not just a plain message — the payload must have `type: 'message'` and an `attachments` array with `contentType: 'application/vnd.microsoft.card.adaptive'`. Always test in a `#bot-testing` channel first. Malformed Adaptive Card JSON silently fails: you get a 200 response and nothing posts.
- 8
Add a threshold alert for conversion rate drops
Before the Teams post step, add a conditional: if `activation_to_paid_rate` drops more than 25% below the 7-day average, modify the Adaptive Card to include an `@mention` of your product lead — use their Teams user ID in the `msteams` mention schema — and change the card color to red (`style: 'attention'` on the Adaptive Card container). Low-noise on good days, loud when something breaks. That's the only way these daily digests stay useful past week two.
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
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.
Intercom Ticket Volume + Razorpay Failed Payments: Daily Support-Cost-per-Revenue Alert to Slack via Zapier
Catch the support cost blowout from Razorpay failed payments before your agents are already buried.
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.