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 flow
Mixpanel logo
Source
Mixpanel
Stripe logo
Process
Stripe
Pipedream logo
Process
Pipedream
Microsoft Teams logo
Destination
Microsoft Teams

The stack in the order it runs — data flows from the source through to where it lands.

Why this stack

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)

  1. Mixpanel logo

    Product analytics for events and funnels.

    The export/query API turns product metrics into scheduled reports you push to chat.

  2. Stripe logo

    Global payments with first-class APIs.

    Events + Sigma let you wire billing into any ops report or alert.

  3. Pipedream logo

    Code-level workflows with hosted triggers.

    Drop into Node/Python mid-flow when no-code hits a wall.

  4. Microsoft Teams logo

    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. 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. 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. 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. 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. 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. 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. 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. 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 services

More like this