How does Outlit model the customer journey?
Outlit tracks contacts and accounts separately:Contact Journey (per person)
Account Billing (per company)
What are the contact journey stages?
Each person (contact) progresses through stages based on their product engagement:| Stage | Meaning | How It’s Set |
|---|---|---|
| Discovered | Email known, hasn’t signed up yet | Auto-detected by browser SDK when email is provided without userId |
| Signed Up | Created an account | Auto-detected by browser SDK when both email and userId are provided |
| Activated | Completed onboarding or key milestone | Manual — call user.activate() |
| Engaged | Actively using the product | Auto-inferred from product activity via PostHog or your SDK (browser/server) |
| Inactive | No activity for extended period | Auto-inferred when no activity detected for 30+ days |
Contact stages track product engagement, not billing. A contact can be Engaged even if their company hasn’t paid, or Inactive even if their company is actively paying.
How stages progress
Contacts move forward through Discovered, Signed Up, Activated, and Engaged. They can never move backwards—an Engaged contact can’t become Activated again. The one exception is Inactive: contacts automatically return to Engaged when they have new activity.How does Outlit detect stages automatically?
Discovered vs Signed Up
The difference is determined by the identifiers you provide:- Discovered
- Signed Up
When you identify a visitor with only an email (no userId), they’re marked as Discovered:Typical triggers: newsletter signup, contact form submission, lead magnet download.
Automatic engagement and inactivity
Outlit monitors product activity and automatically advances contacts to Engaged when they show consistent usage — active on multiple distinct days within a rolling time window. Activity signals come from the browser SDK, server SDK, and connected integrations like PostHog. When contacts haven’t had any product activity for an extended period (default: 30 days), they’re marked Inactive. When an inactive contact returns, they automatically recover to Engaged.How do I manually set contact stages?
These examples show browser SDK usage where the user is already identified. For server-side usage, see Node.js SDK → Contact Stage Methods.
user.activate()
Mark a contact as activated after they complete onboarding:user.engaged()
While engagement is calculated automatically, you can explicitly mark it for specific milestones:What are the account billing statuses?
Each account (company) has a billing status that’s separate from individual contact journeys:| Status | Meaning | How It’s Set |
|---|---|---|
| None | Never had a subscription | Default |
| Trialing | Active trial period | Automatic (Stripe) or manual |
| Paying | Active paid subscription | Automatic (Stripe) or manual |
| Churned | Had subscription, now cancelled | Automatic (Stripe) or manual |
How does Stripe integration work?
If you’ve connected Stripe to Outlit, billing status is handled automatically:| Stripe Subscription Status | Account Billing Status |
|---|---|
trialing | Trialing |
active | Paying |
canceled | Churned |
unpaid | Churned |
Stripe integration links accounts via email matching. When Outlit syncs a Stripe customer, it finds the matching account and updates its billing status.
How do I set billing status manually?
For non-Stripe payment processors or custom billing logic:Billing methods target the account by domain, not individual contacts. All contacts under that account share the same billing status.
Best practices
Let integrations handle what they can. Discovered and Signed Up are auto-detected by the browser SDK based on identifiers. Engaged and Inactive are auto-inferred from product activity via PostHog or your SDK. Stripe handles billing status. The main stage you need to instrument manually is Activated — calluser.activate() when users complete your definition of activation.
Understand the separation. Contact journey and account billing are independent. Jane can be Engaged while her company is on None, or Inactive while her company is Paying. When Jane returns after being Inactive, she auto-recovers to Engaged regardless of billing status.
Call stage methods at the right time. Stage methods like user.activate() should be called when the action is confirmed complete, not when the user clicks a button. Wait for the backend to confirm success before tracking.
Include useful properties. Properties help you analyze stage transitions. Include context like which onboarding flow was completed, time-to-activate, and which steps were skipped.
Frequently Asked Questions
What's the difference between contact journey and account billing?
What's the difference between contact journey and account billing?
Contact journey tracks individual people’s product engagement (Discovered through Inactive). Account billing tracks the commercial relationship (None through Churned). They’re independent — Jane can be Engaged while her company is on a free plan, or Inactive while her company is actively paying.
Which stages require manual instrumentation?
Which stages require manual instrumentation?
Activated is the main stage you instrument manually by calling
user.activate(). Discovered and Signed Up are auto-detected by the browser SDK. Engaged and Inactive are auto-inferred from product activity. If Stripe is connected, billing statuses sync automatically; otherwise, set billing status manually with the customer billing methods.Can contacts move backward in journey stages?
Can contacts move backward in journey stages?
No. Contacts progress forward through Discovered, Signed Up, Activated, and Engaged. The one exception is the Engaged ↔ Inactive cycle: inactive contacts automatically return to Engaged when they show new activity.
Next Steps
Identity Resolution
How Outlit connects anonymous visitors to known contacts
Server-Side Tracking
Track stage events from your backend
Browser Integration
Set up browser tracking
API Reference
Direct API for stage events