Contact management
Identify users, update user properties and contacts, and track events.
Once the SDK is initialized, you can begin tracking user identity and behavior. This guide will walk you through updating user profiles, managing email and phone contacts, handling session identity, tracking locations, and sending custom events.
On this page
- Update user properties
- Understand emailId vs email
- Add contact additional info
- Manage the user identity session
- Listen for identity updates
- Set advertising and vendor identifiers
- Track location
- Configure unique client IDs
- Track custom and screen events
Update user properties
You can update user profile data in two ways: using the builder pattern or by passing a ZTUser object directly to updateUser().
Using the Builder Pattern (Recommended)
The builder pattern provides a clean, fluent API to set multiple properties at once:
ZetaClient.user.build((user) => {
user.uid = 'user-unique-id';
user.firstName = 'John';
user.lastName = 'Doe';
user.name = 'John Doe';
user.signedUpAt = '2026-07-01T10:30:00Z'; // ISO 8601 format
user.source = 'organic';
user.emailId = '[email protected]';
user.email = {
email: '[email protected]',
additionalInfo: {},
};
user.phone = {
phone: '+1234567890',
additionalInfo: {},
};
user.additionalProperties = {
membership_level: 'gold',
preferred_language: 'en',
points_balance: 1500,
is_subscribed: true,
};
user.location = {
latitude: 40.7128,
longitude: -74.006,
isForeground: true,
};
});Direct Object Update
Alternatively, you can pass a partial ZTUser object directly:
const user = {
name: 'Jane Smith',
firstName: 'Jane',
lastName: 'Smith',
};
ZetaClient.user.updateUser(user);Understand emailId vs email
When updating user profiles, it is important to distinguish between emailId and email:
user.emailId: Use when the email address should be treated as the user's primary unique identifier. This populates the Email field under ZMP Identifiers (and also creates a Contact for this email).user.email: Use when you want to add the email as a contact channel with additional properties (such as subscription status or preferences). This populates the Contact section in ZMP.
Important: If the user's
uidis set to an email address in the same submission, theemailIdvalue is ignored.
Add contact additional info
For email and phone contacts, you can attach rich metadata using the ZTContactAdditionalInfo object:
const contactAdditionalInfo = {
subscriptionStatus: 'active',
inactivityReason: 'none',
signedUpAt: '2026-07-01T10:30:00Z',
doubleOptInStatus: 'single',
phoneType: 'mobile',
lastSent: '2026-07-01T10:30:00Z',
lastOpened: '2026-07-01T10:30:00Z',
lastClicked: '2026-07-01T10:30:00Z',
properties: { marketing_segment: 'newsletter' },
};
ZetaClient.user.build((user) => {
user.email = {
email: '[email protected]',
additionalInfo: contactAdditionalInfo,
};
});Contact Additional Info Properties
preference(string[]): Optional. Defaults to["standard"]if not provided. Other preferences can be customized in ZMP Settings; only values defined there may be passed here.subscriptionStatus(string): The contact's subscription state. Supported values arenew,active, orinactive.inactivityReason(string): Optional. Reason for contact inactivity.signedUpAt(string): Optional. Date when the contact signed up (ISO 8601 format recommended).doubleOptInStatus(string): Optional. Default isnull; acceptssingleordouble.phoneType(string): Optional. Default isnull; acceptsmobileorlandline.lastSent/lastOpened/lastClicked(string): Optional. Date-time values in ISO 8601 format, UTC.properties(object): Optional. Additional custom key-value pairs for the contact.
Manage the user identity session
The SDK tracks user session-specific properties and events. Setting uid or emailId starts the user identity session:
ZetaClient.user.build((user) => {
user.uid = 'john123';
user.emailId = '[email protected]';
});Clearing the user session
When a user logs out or switches accounts, clear the identity session on the device. This ensures subsequent events are not associated with the previous user:
ZetaClient.user.clear();Listen for identity updates
Native identity callbacks are surfaced to JavaScript through an event listener. Register a listener for ZetaCoreEvents.IdentityDelegate, then call ZetaClient.getCachedBSIN() to request the current identity state. The event carries the device's bsin (Browser Session Identifier), which ZMP assigns shortly after initialization:
import { Platform, NativeEventEmitter, DeviceEventEmitter } from 'react-native';
import ZetaClient, { ZetaCoreEvents } from 'zetakit_reactnative';
const eventEmitter = Platform.select({
ios: new NativeEventEmitter(ZetaClient.bridge),
android: DeviceEventEmitter,
});
const identityListener = eventEmitter?.addListener(
ZetaCoreEvents.IdentityDelegate,
(event) => {
console.log('Identity updated. BSIN:', event.bsin);
}
);
// Request the current BSIN; the listener above receives the result.
ZetaClient.getCachedBSIN();Call setIdentityDelegate() once after SDK initialization, on both iOS and Android, to receive automatic updates whenever the BSIN changes:
ZetaClient.user.setIdentityDelegate();Important: Register the listener before calling
getCachedBSIN(), and callidentityListener?.remove()when the owning component unmounts.
Set advertising and vendor identifiers
Pass the device's advertising identifier (IDFA on iOS, GAID on Android) and the vendor/app-set identifier to enable cross-device identity resolution:
ZetaClient.user.setIdentifierForAdvertiser(idfaString);
ZetaClient.user.setIdentifierForVendor(idfvString);Track location
Pass location coordinates along with a foreground/background flag. The provided location is cached in memory and automatically attached to subsequent events as a property:
const location = {
latitude: 40.7128,
longitude: -74.006,
isForeground: true, // Indicates if collected while app is in foreground
};
ZetaClient.user.updateLocation(location);Configure unique client IDs
The SDK supports providing a unique_client_id to ZMP for advanced profile-merge scenarios. Before using it, review these conditions:
- Profile Merging: No two profiles may have the same
unique_client_idname:value pair. If a profile is updated with aunique_client_idmatching another profile, the profiles are merged. - Value Constraints: A
unique_client_idpair is discarded if the same key already exists with a different value. - Coordination: Enabling support for a unique client ID requires site-configuration updates. Coordinate with your Zeta account team to ensure the configuration is correct.
ZetaClient.user.setUniqueClientId('custom_client_key', 'custom_client_value');Track custom and screen events
Auto-tracked lifecycle events
The SDK automatically tracks the following core lifecycle events:
app_installed: Fired on the very first launch.app_opened: Fired when the app transitions from the background to the foreground.app_closed: Fired when the app transitions from the foreground to the background.app_terminated: Fired when the app is fully closed (iOS only).
Screen name tracking
Use trackScreenName() to track user screen navigation. The provided screen name is cached in memory and attached to subsequent events as a property:
ZetaClient.events.trackScreenName('ProductDetailScreen', 'myapp://product/123', {
category: 'electronics',
});Custom events
Send custom events by passing an event name and a dictionary of properties. Properties must be JSON-serializable:
ZetaClient.events.send('purchase_completed', {
item_id: 'sku_12345',
price: 99.99,
currency: 'USD',
tags: ['promo', 'summer_sale'],
});Important: If any property value is not serializable to JSON, the entire event data is silently discarded.
Next
Now that you can identify users and track events, continue to configure messaging channels:
- Push Notifications — Register device tokens and configure native push setups.
- In-App Messaging — Foreground messages and email collection.
- App Inbox — A persistent, queryable message store.
- User Guide: User Properties — Standard and custom properties in ZMP.
- User Guide: Identity Resolution — How profiles merge in ZMP.
See also
- Platform support -- feature availability by platform and SDK version.

