Project setup for embedded analytics
Contents
You can use PostHog to power analytics dashboards inside your product. Capture your customers' events in PostHog, query the data, and display the results in your own UI. This is often easier than building and maintaining your own infrastructure.
This is called embedded analytics, or customer-facing analytics. You can store all customer data in one PostHog project and filter it by customer, or create a separate project for each customer. This guide compares both approaches to help you choose the right setup.
How person profiles can merge
Person profiles are scoped to a project. If users from different customers have the same distinct ID, PostHog treats them as the same person and combines their events in one profile.
For example, suppose you're building a vibe-coding platform where customers can publish web apps that you manage. You want to use PostHog to show each customer a dashboard with their app's pageviews, users, and conversions. If the same person signs in to two customer apps and your platform identifies them as user 123 in both, that user's events from both apps appear in one person profile. Funnels and other per-user insights would count activity across both apps as belonging to one user.
One way to prevent this is to include the customer ID in each identified user's distinct ID:
This prevents identified users from different customers from sharing a profile. Anonymous activity can still merge if those websites use the same project token and share browser storage.
By default, the web SDK persists the anonymous distinct ID in a cookie. If that cookie is available to both websites, the SDK uses the same anonymous distinct ID. See JavaScript web persistence and cookies for details.
A project per customer is better when you plan to give customers direct PostHog access or need to fully isolate customer data for security or compliance reasons.
| Single project | Project per customer | |
|---|---|---|
| Data | Store all customer data together and filter it by a customer_id property. | Store each customer's data in a separate project. |
| Best for | Dashboards displayed inside your product. | Giving customers direct access to PostHog. |
| Person profiles | Require customer-scoped distinct IDs to prevent merging. | Automatically separated by project. |
| Querying | Pass a customer identifier to an Endpoint or the Query API. | Query each customer's project. |
| Plan | Available on the free plan. | Requires the Boost plan for unlimited projects. |
Filter customer data in one project
Add a customer identifier, such as customer_id, as an event property on every event. You can then retrieve data for a specific customer in two ways:
- Recommended – Create an Endpoint with a variable and pass the customer ID when you call it.
- Use the Query API and filter the query by the customer ID. Keep in mind that the Query API has project-level rate limits.
Run these requests from your backend. Make sure you don't accept an arbitrary ID from the client.
Create a project for each customer
A separate project isolates each customer's events and person profiles. Use this setup when customers need to log in to PostHog or when you need a strict data boundary between customers.
Create projects with the API
Create a project when you add a customer by calling the projects API.
Each project has its own project token for event ingestion.
To query a customer's data, use that project's ID when calling Endpoints or the Query API.
With this setup, analyzing data across all customers is more difficult because PostHog queries are scoped to one project. For example, to calculate daily active users across all customer apps, you would need to query each project separately and combine the results.
Free organizations are limited to one project. The Boost plan includes unlimited projects.
Give customers access
If you store each customer's data in a separate project and want to give them access to PostHog:
- Use project access control to invite each customer to only their project.
- Manage access control through the API to automate this setup.
- Disable full organization member visibility so customers only see themselves and members of their project.
Billing
Billing is organization-wide, so usage is combined across all projects. For example, 100 projects sending 20,000 events each count as 2 million events, not 100 separate free tiers.
Account for this combined usage when pricing your product.