User Identity
install_id, app_user_id, setAppUserId, setUserProperties, and advanced matching.
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 viasetAppUserId()when the user signs in; cleared viaclearAppUserId()on logout.
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') againAPIs
All of these are available in @layers/client and @layers/react-native
(and @layers/node, @layers/expo by extension):
// 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(); // stringThere is no identify(id, traits) / reset() sugar — the two calls
above are the full API.
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
When the same app_user_id appears on multiple install_ids, events
are associated with the same user record server-side. Dashboard-level
rollups honor this.
Advanced matching
For better Meta / TikTok attribution match rates, pass hashed PII via per-event properties or via user properties:
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.
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.