B2B SaaS Wiring Guide
This guide explains how Apex derives your Activation, Retention, and Revenue dashboards. If you're running a B2B SaaS product with a product-led growth motion, this is your single source of truth for what data powers what.
The Data Model
Apex builds your dashboards from three independent data sources. Each one is optional — the more you connect, the richer the picture.
| Data source | What it powers | How to set it up |
|---|---|---|
| Contacts + createdAt | Signup counts, cohort membership, lifecycle distribution | Automatic when contacts are created via forms, API, or connectors |
| Custom events + identify | Product activity, activation funnel "Active" stage, time-to-activate | Install the snippet or SDK |
| Lifecycle stage updates | Activation funnel "Activated" stage, retention, churn | Lifecycle API or connectors like Stripe |
How the Activation Dashboard Works
The Activation dashboard builds a three-stage funnel:
Sign-ups → Active → Activated
- Sign-ups = contacts created in the selected time window (from their
createdAttimestamp) - Active = contacts who triggered at least one custom tracking event, or who have an
activatedAttimestamp - Activated = contacts whose lifecycle stage is
activated,customer, orexpanded
Info
If your dashboard shows sign-ups but zero "Active" users, you probably need to add event tracking. The snippet's automatic page_view events don't count — Apex looks for custom events (button clicks, feature usage, etc.) that signal real product engagement.
What to track for activation
At minimum, track the moment a user does the thing that makes them "real":
- Completed onboarding —
track("onboarding_completed") - Used a core feature —
track("report_created"),track("experiment_started") - Connected a data source —
track("integration_connected", { provider: "stripe" })
The more product events you send, the more Apex can distinguish "signed up and left" from "signed up and engaged."
How the Retention Dashboard Works
The Retention dashboard tracks two related but distinct things:
Contact-based retention (lifecycle stages)
- Retention % = contacts who are still in an active lifecycle stage divided by total contacts
- Churn rate = contacts who moved to
churnedstage divided by total contacts - Cohort matrix = month-by-month retention rates for each signup cohort
This requires contacts to have lifecycle stage transitions over time. Without lifecycle updates, all contacts appear permanently "active."
Revenue-based retention (Stripe)
- Net Revenue Retention (NRR) = (initial MRR + expansion − contraction − churned revenue) / initial MRR
- Powered entirely by Stripe charge data
Info
With Stripe webhooks configured, contact lifecycle stages update automatically when customers pay or cancel. If you're not using webhooks, contact retention and revenue retention may drift apart — Stripe reflects billing reality while lifecycle stages reflect your product's definition of active usage.
Connecting Stripe
Stripe adds revenue data to your dashboards:
| What Stripe provides | Dashboard impact |
|---|---|
| Charge amounts + timestamps | Revenue trend charts, NRR calculation |
| Customer email | Attribution back to the marketing source that generated the lead |
| Payment success/failure | Revenue retention metrics |
Stripe webhook automation
When you configure Stripe webhooks, Apex automatically updates contact lifecycle stages:
invoice.paid→ Contact moves tocustomerlifecycle stage +conversionValueis accumulated from the invoice amountcustomer.subscription.deleted→ Contact moves tochurnedlifecycle stage
Matching works in two steps: first by externalIds.stripe_customer_id (if the contact was previously matched), then by email fallback. On a successful email match, Apex stores the Stripe customer ID for faster future lookups.
Events are idempotent — replaying the same Stripe webhook won't double-apply lifecycle changes.
Setting up Stripe webhooks
- Set
STRIPE_WEBHOOK_SECRETin your environment variables - In the Stripe Dashboard → Webhooks, add an endpoint pointing to
https://your-apex-url/api/webhooks/stripe - Subscribe to
invoice.paidandcustomer.subscription.deletedevents - Stripe test mode (
sk_test_keys) works — use it to verify the connection first
Manual lifecycle updates
You can also update lifecycle stages manually via the API if you need more control:
POST /api/contacts/{contactId}/lifecycle
{ "stage": "customer" }
Test mode
Stripe test mode (keys starting with sk_test_) works with Apex. Use it to verify the connection before going live with production data.
The Identity Chain
For Apex to connect the dots between a website visitor, a signed-up user, and a paying customer, it needs identity:
- Anonymous visitor — The snippet assigns a
apex_vidcookie automatically - Known user — Call
identify(userId, { email })at signup or login - Paying customer — Stripe matches by email to the identified contact
If any link in this chain is missing, you'll see gaps:
| Symptom | Likely cause |
|---|---|
| Sign-ups not appearing in activation | No contacts being created — check snippet or API integration |
| "Active" count is zero | No custom events being sent — snippet page_view alone isn't enough |
| Revenue not attributed to sources | Stripe customer email doesn't match any contact email |
| Retention shows 0% churn | No lifecycle stage transitions — configure Stripe webhooks or send lifecycle events via the API |
Growth Reporting vs. Finance
Apex is a growth reporting tool, not a financial system. Important distinctions:
- Contact-level, not account-level — Apex tracks individual contacts. If your B2B product has team accounts, multiple contacts may belong to one billing customer. Revenue is attributed per-contact, not per-account.
- Approximate revenue — Stripe sync gives you directional revenue data for dashboards and experiment attribution. It is not a replacement for your accounting system.
- NRR is simplified — Apex calculates NRR from charge patterns, not from a full subscription management model. It's accurate enough for growth decisions but not for investor reporting.
Info
If you need account-level cohort analysis or precise subscription revenue metrics, those are on the roadmap. Today, Apex is optimized for the product-led growth loop: acquisition → activation → retention → revenue attribution.
Setup Checklist
Use this as a quick reference for wiring a new B2B SaaS project:
- Install the tracking snippet on your marketing site and app — Snippet installation
- Add
identify()calls at signup and login — Identity docs - Track key product events that signal activation — Custom events
- Connect Stripe for revenue data — Stripe connector
- Configure Stripe webhooks to automate
customerandchurnedlifecycle transitions — see webhook setup above - Update lifecycle stages as users progress (or let webhooks handle it) — Lifecycle concepts
- Check your dashboards — Activation and Retention should start showing data within minutes
Next Steps
- Activation concepts — How the activation funnel is calculated
- Retention concepts — Cohort analysis and NRR methodology
- Lifecycle stages — The full stage model and how it affects dashboards
- Running experiments — Start testing changes against your activation and retention metrics