# Events and users

Every Apparent SDK has the same calls with the same words. Examples here are in TypeScript; each SDK page has its own.

## What's tracked by itself

| Event | When |
|---|---|
| `first_open` | The first launch after install. |
| `app_open` | Each visit: at launch, and after 30 minutes away. Not for launches by a push or a background job. |
| `app_background` | The app goes away, with the seconds it was open. |
| `app_updated` | The first launch on a new version. |
| `screen_view` | Each new screen, with the one before it. |
| `error` | A crash or an error you report. |
| `install_source` | Android, first launch: which link brought the install. |

## The five events worth adding

- `sign_up`: someone makes an account (skip if the app has no accounts).
- `paywall_view`: the upgrade screen shows.
- `purchase`: a purchase goes through.
- `<main_action>`: the one thing people come for, named after it, like scan_completed or habit_completed.
- `<thing>_failed`: something the person tried didn't work, like purchase_failed or upload_failed.

Apparent already understands these names: `paywall_view` fills in "From store to sale", names ending in `_failed` or `_error` show as problems, and you pick your main action on the app's page.

## Names and properties

```ts
Apparent.track("lesson_complete", { topic: "grammar", minutes: 4, first: true });
```

- Names are `lowercase_snake`, the thing first and the verb last: `paywall_view`, `purchase_tap`, `lesson_complete`.
- Properties are flat: text, numbers, true/false or empty. Anything else is turned into text. Text over 500 characters is cut, at most 40 properties.
- Never put emails, names or other personal data in properties.
- `setProperties({ plan: "pro" })` adds a property to every later event. Setting it to empty removes it.

## Screens

Use stable route names, not titles or ids: `practice/[topic]`, not `Grammar` or `practice/17`. A repeat of the same screen is ignored.

## Signed-in users

```ts
Apparent.identify(user.id);   // after sign-in
Apparent.reset();             // on sign-out (logout() on Swift, Kotlin and Flutter)
```

- Signing in keeps the install's id, so what someone did before signing in stays theirs.
- Signing out starts a fresh id, so the next person on the phone is someone new.
- Use your own user id, never an email address.

## Opting out

`optOut()` stops everything and clears what's waiting; `optIn()` starts again. Both are remembered across launches. Offer it if your app asks for consent.

## Test phones

Leave the SDK on in debug builds. Every SDK says when it runs in a simulator or emulator, so those are left out even without a device model. Simulators, emulators, Google's pre-launch phones, Apple's review and phones on a version that isn't in the store yet are recognised and left out of every number.
