---
title: "Projects — one product, one view"
description: "Keep every part of one product — website, apps, servers — in a single Togo project, and give each person one userId everywhere, so Togo sees the whole journey."
canonical: "https://www.togohq.ai/docs/concepts/projects"
applies_to: "Every Togo SDK — web, mobile and server — and mcp.togohq.ai/mcp"
updated: "2026-11-03T00:00:00Z"
---

# Projects — one product, one view

Keep every part of one product — website, apps, servers — in a single Togo project, and give each person one userId everywhere, so Togo sees the whole journey.

## A project is your product, not one of its apps

A **project** holds everything Togo knows about one product: its events and event registry, the
people who use it, its write keys and its reporting time zone. It belongs to an organization, and
everyone in the organization works on it together.

**One product is one project** — its marketing site, its web app, its mobile apps, its servers
and its integrations together. Togo follows a person across those parts only **inside one
project**. Split them into several projects and each holds a fragment of the same people, with no
way to join them afterwards.

| Put in the same project                                 | Give its own project             |
| ------------------------------------------------------- | -------------------------------- |
| The website, the web app and the mobile apps            | A second, separate product       |
| Your API servers, background jobs and webhook handlers  | A product you build for a client |
| Development, staging and production of all of the above | —                                |

**Environments are not projects.** Every project has two kinds of write key: a **test** key
(`togo_pkt_…`) for development and staging, whose events appear within seconds and are never
charted, and a **live** key (`togo_pkl_…`) for production. Give each part of your system its own
pair of keys inside the project — `website`, `game-server`, `payments` — rather than a project
each.

## One `userId` everywhere

Inside a project, Togo joins a person's activity by **your** id for them: the `userId` the browser
passes to `identify()` and your servers pass on every call. So the rule is short:

**Every part of your system uses the same `userId` for the same person** — your own account id,
the one your database already holds.

- **Not an email address**, and not a username a person can change.
- **Not a platform's own id** — an app store, console or social login id. Map it to your account id
  first, and send that.
- **Never invented for a guest.** A visitor or player who has not signed in is anonymous, and that
  is fine: their activity on the device joins their account the moment the app calls
  `identify()`. Do not make up a `userId` to fill the gap.

Different ids in different places split one person into several, and every count of people,
every funnel and every retention curve is quietly wrong. [People and
identity](/docs/concepts/people) explains how Togo decides who is who.

## Example: a game on the web, on phones and on your servers

Take a game that people discover on its website, play on their phones, and pay for through an app
store, with your game server and a payments webhook behind it. Four parts, **one project**, one
`userId` — the player's account id.

**1. The website — sign-up.** The browser SDK records the visit and the sign-up, and `identify()`
joins the visitor's anonymous browsing to their new account:

```ts
// website
const analytics = init({
  writeKey: process.env.NEXT_PUBLIC_TOGO_WRITE_KEY!,
  defaultProperties: { platform: 'web' },
});

analytics.track('account_created', { referral: 'friend_invite' });
analytics.identify(account.id);
```

**2. The mobile game — logging in and playing.** The mobile SDK makes the same calls as the
browser one. When the player logs in on their phone with the account they made on the website,
`identify()` with the **same id** joins the phone to that player — including anything they did in
the app before logging in:

```swift
// iOS app
Togo.setup(TogoConfig(writeKey: "togo_pkl_…", defaultProperties: ["platform": "ios"]))

Togo.identify(account.id) // after login: the same id the website used
Togo.track("level_completed", properties: ["level": 12])
```

**Your game server** records what happens on its side — a match result, a reward granted — with the
same id:

```ts
// game server
const analytics = init({
  writeKey: process.env.TOGO_WRITE_KEY!,
  defaultProperties: { service: 'game-server' },
});

analytics.track('match_won', { mode: 'ranked' }, { userId: account.id });
```

**3. The payments webhook — revenue.** When the store confirms a purchase, record it with the
same id:

```ts
// payments webhook
analytics.track('gems_purchased', { pack: 'starter', price_bucket: '1-5' }, { userId: account.id });
await analytics.flush(); // a webhook handler is often serverless
```

**4. One person, one journey.** Because every part uses `account.id` in one project, Togo sees one
player: the website visit and its campaign, the sign-up, the first login on a phone two days
later, the levels, and the first purchase. The `platform` and `service` properties still tell the
channels apart whenever you want them apart.

## What one view lets you ask

With the whole journey in one project, questions that cross channels have answers. Ask your
agent through the [Togo MCP server](/docs/mcp):

```text
Of the players who signed up on the website last month, how many logged in on mobile
within 7 days, and how many of those bought gems?
Of the players who came from a friend invite, how many bought gems within 30 days?
Where between website sign-up and first purchase do most players drop off?
```

Each of those needs the website, the game and the payments in one place. Across separate
projects, the first step of the funnel and the last would belong to different people, and the
answer would be missing or wrong.

That single view is what lets an agent help with what matters most — where the experience loses
people, which channels bring players who stay, and what leads to a first purchase — instead of
answering for one channel at a time.

## Setting it up

- **With your agent:** [Install Togo with your AI agent](/docs/install). Its setup looks for this
  product's existing project before creating one, and gives each part of your system its own key
  pair inside it.
- **By hand:** create one project in [app.togohq.ai](https://app.togohq.ai), then follow the guide
  for each part — [Next.js](/docs/nextjs), [React](/docs/react), [Node.js and
  serverless](/docs/node), your mobile app — using that project's keys everywhere, and the same
  `userId`.
