# SaaS (/docs/guides/saas)

This guide covers the core SaaS questions: do signups activate, do they stay, which accounts are healthy, and what makes them upgrade. The example is a project-management tool.

<Steps>

### Track the lifecycle [#track-the-lifecycle]

Pick one event per stage, with the properties you'll want to slice by:

| Stage | Event | Properties |
| --- | --- | --- |
| Acquisition | Pageviews (automatic) | UTMs, referrer |
| Signup | `signed_up` | `plan`, `source` |
| Activation | `project_created`: the action that predicts retention in *your* product | `template` |
| Collaboration | `invite_sent` | `role` |
| Engagement | `project_opened`, `task_created` | `project_id` |
| Revenue | `plan_upgraded` | `from`, `to`, `amount`, `interval` |

```ts title="after signup"
datahop.identify(user.id, { email: user.email, plan: 'free' }, { signup_source: source })
datahop.group('company', org.id, { name: org.name, plan: 'free', seats: 1 })
datahop.capture('signed_up', { plan: 'free', source })
```

Send billing events from the server:

```ts title="billing-webhook.ts"
datahop.capture({
  distinctId: user.id,
  event: 'plan_upgraded',
  properties: { from: 'free', to: 'pro', amount: 12, currency: 'USD', interval: 'monthly' },
  groups: { company: org.id },
  $set: { plan: 'pro' },
})
datahop.groupIdentify({ groupType: 'company', groupKey: org.id, properties: { plan: 'pro', mrr: 12 } })
```

Keep `plan` both on the person (what it is now) and on the event (what it was then). Then you can answer both "what do pro users do?" and "what did people do right before upgrading?".

### Signup to activation [#signup-to-activation]

Create a [funnel](/docs/product-analytics/insights#funnels): `signed_up` → `project_created` → `invite_sent` → `plan_upgraded`, converting within 14 days, over the last 60 days.

```text title="summary"
signed_up 4,231 → project_created 1,004 (23.7%) → invite_sent 317 (31.6%) → plan_upgraded 36 (11.4%)
Overall conversion 0.9%. Biggest drop-off: invite_sent → plan_upgraded (88.6% lost).
```

Break it down by `source` to compare channels by activation, not just by signups. Break it down by `role` or `company_size` to find who activates best.

### Retention [#retention]

Create a [retention](/docs/product-analytics/insights#retention) table: start with `signed_up`, return with `project_opened`, weekly.

```text title="summary"
2,196 people across 9 cohorts. Average retention — week 1: 22.7%, week 2: 33.4%, week 4: 23.2%.
```

A curve that flattens out means you have a retained core. To compare groups, filter by a cohort, such as people who sent an invite in their first week vs everyone else.

### Accounts [#accounts]

In B2B, the customer is the company. With `group('company', …)` in place:

- **Weekly active companies**: a [trend](/docs/product-analytics/insights#trends) of all events, measured as **Unique groups** of companies, by week.
- **Account activation**: the funnel above with **Count companies**. A company moves forward when *anyone* in it creates a project, and *anyone* sends an invite.
- **Account pages**: **People → Companies** shows each company's members, properties and timeline. It's useful before a sales call, or when a key account goes quiet.

### Plans [#plans]

Break any usage trend down by the person property `plan`, such as unique people opening a project per week, split into free, pro and business. For plans that belong to the account, break down by the company's `plan` property instead.

A person-property breakdown uses the **current** plan. For "what plan were they on at the time", break down by the event property.

### Test an upgrade prompt [#test-an-upgrade-prompt]

Go to **Experiments → New experiment** and describe it:

> Does showing an upgrade prompt after the third project get more free users to upgrade?

Check the plan Datahop drafts. It should target free users (`plan` equals `free`), use `plan_upgraded` within 14 days as the primary metric, and use revenue per user as a secondary metric. Then read the flag where the prompt would show, so only people who reach that moment count:

```ts
if (projectCount === 3 && datahop.getFeatureFlag('upgrade-prompt-3rd-project') === 'test') showUpgradePrompt()
```

Launch it and follow the [results](/docs/experiments/results). Upgrades are rare, so expect to need more people. The recommendation tells you roughly how many more days to run.

Experiments split by person. If teammates must never see different pricing, use a [flag that matches by company](/docs/feature-flags#match-by-company) instead, and compare companies with a funnel that counts companies.

</Steps>

## A dashboard to start with [#a-dashboard-to-start-with]

Put these on one [dashboard](/docs/product-analytics/dashboards): weekly signups by `source`, the activation funnel, signup → usage retention, weekly active companies, and upgrade revenue (sum of `amount`). Or ask your agent: *"Build a SaaS health dashboard with signups by source, the signup → project → invite → upgrade funnel, weekly retention and weekly upgrade revenue."*
