# User Identity (/docs/sdk/user-identity)



The SDK tracks two identifiers that are persisted locally and attached
to every event:

* **`install_id`** — opaque device / install identifier. Generated on
  first launch and persisted in platform storage (AsyncStorage on
  React Native, localStorage on web). Survives app restarts; resets on
  app uninstall (Keychain-backed persistence on iOS can survive
  reinstall, but that's platform behavior, not SDK guarantee).
* **`app_user_id`** — your platform's user ID. Set via `setAppUserId()`
  when the user signs in; cleared via `clearAppUserId()` on logout.

## Lifecycle [#lifecycle]

```
First launch  →  install_id generated
                ↓
User signs up →  setAppUserId('user_42') — subsequent events include it
                ↓
User logs out →  clearAppUserId() — subsequent events go back to install_id only
                ↓
User signs in →  setAppUserId('user_42') again
```

## APIs [#apis]

All of these are available in `@layers/client` and `@layers/react-native`
(and `@layers/node`, `@layers/expo` by extension):

```ts
// Set / clear the authenticated user
layers.setAppUserId('user_42');   // setAppUserId(undefined) also clears
// React Native: Layers.clearAppUserId() is a convenience wrapper

// Set user-level properties (sent to /users/properties endpoint)
await layers.setUserProperties({
  plan: 'premium',
  signup_date: '2026-01-15',
});

// Read current state
layers.getAppUserId();        // string | undefined
layers.getSessionId();        // string
```

There is no `identify(id, traits)` / `reset()` sugar — the two calls
above are the full API.

## install\_id stability [#install_id-stability]

| Scenario           | Same install\_id?                                                                            |
| ------------------ | -------------------------------------------------------------------------------------------- |
| App close & reopen | Yes                                                                                          |
| App update         | Yes                                                                                          |
| App reinstall      | Depends on platform storage (Keychain on iOS can persist; encrypted prefs on Android do not) |
| Different device   | No                                                                                           |

For cross-device identity, rely on `app_user_id` after sign-in.

## Cross-device stitching [#cross-device-stitching]

When the same `app_user_id` appears on multiple `install_id`s, events
are associated with the same user record server-side. Dashboard-level
rollups honor this.

## Advanced matching [#advanced-matching]

For better Meta / TikTok attribution match rates, pass hashed PII via
per-event properties or via user properties:

```ts
await layers.setUserProperties({
  email: 'user@example.com',     // will be SHA-256 hashed server-side
  phone: '+15550100',            // digits-only, SHA-256 hashed
});
```

The server-side relay handles hashing — you don't need to hash
client-side. If you do want to pre-hash, pass `email_hash` / `phone_hash`
directly (pre-computed SHA-256 hex). See
[Advanced matching](/docs/sdk/advanced-matching).

## Privacy [#privacy]

Raw email and phone only hit the relay in transit; the SDK doesn't
persist them. If you want zero-PII transmission, hash client-side
before calling `setUserProperties`.
