User identity and properties
How ZMP identifies users, resolves identities, and stores standard and custom properties across all Zeta SDKs.
This page is for developers integrating user identity into their app. It explains how the Zeta Marketing Platform (ZMP) identifies users, describes the standard and custom property model, and covers UCLID -- the client-defined unique identifier used for identity resolution.
On this page
- User identification in ZMP
- Identity resolution behavior
- Standard user properties
- Custom properties
- Unique client ID (UCLID)
- Best practices
- Security considerations
User identification in ZMP
ZMP supports three primary identifiers for user profiles. Your app provides these through the SDK and ZMP uses them to resolve the user to an existing or new profile.
| Identifier | Description | iOS | Android | React Native | Flutter |
|---|---|---|---|---|---|
uid | Primary user identifier set by your app. | 0.1.0 | 0.1.0 | 0.1.0 | 0.1.0 |
emailId | Email treated as the unique identifier (populates ZMP Identifiers). | 0.1.0 | 0.1.0 | 0.1.0 | 0.1.0 |
| UCLID | Client-defined unique identifier for identity resolution. | 0.2.0 | 0.2.0 | 0.2.0 | 0.2.0 |
Important: If you set
uidto an email address in the samebuildcall, theemailIdvalue is ignored.
Identity resolution behavior
When your app sets user identity properties, ZMP follows this sequence:
- Check for existing profile. ZMP looks for a profile matching the provided
uid,emailId, or UCLID. - Attach session or create new profile. If a match is found, ZMP attaches the current device session to the existing profile. If no match is found, ZMP creates a new profile.
- Generate BSIN. ZMP assigns a BSIN (Zeta's unique user identifier) to every profile. The BSIN is generated internally -- your app does not set it. You can read the cached BSIN through the SDK after initialization.
Setting uid or emailId starts the user identity session. Call clear() when the user signs out or switches accounts to detach the device session from the current profile.
iOS (Swift)
ZetaClient.shared.user?.build { user in
user.uid = "user-123"
user.emailId = "[email protected]"
}
ZetaClient.shared.user?.clear()
For Objective-C, see iOS Getting Started.
Android (Kotlin)
ZetaClient.user.builder()
.setUid("user-123")
.setEmailId("[email protected]")
.submit()
ZetaClient.user.clear()
For Java, see Android Getting Started.
Standard user properties
Update user properties through the builder pattern. The following table lists all standard properties.
Identity
| Property | Type | Description |
|---|---|---|
uid | String | Primary user identifier set by your app. |
name | String | Display name. |
firstName | String | First name. |
lastName | String | Last name. |
source | String | Acquisition source (e.g., "organic", "campaign_xyz"). |
Lifecycle
| Property | Type | Description |
|---|---|---|
signedUpAt | String | ISO 8601 date-time (UTC) when the user signed up. |
Contact
| Property | Type | Description |
|---|---|---|
email | ZTUserEmail | Email as a contact with optional additional properties (preferences, subscription status). |
phone | ZTUserPhone | Phone as a contact with optional additional properties. |
emailId | String | Email as the unique identifier. Only accepted if uid is not an email address. |
Device
| Property | Type | Platform | Description |
|---|---|---|---|
| Push token | Data (iOS) / String (Android) | All | Device token for push notification delivery. |
| IDFA | String | iOS only | Identifier for Advertisers. Your app handles ATT prompting. |
| IDFV | String | iOS only | Identifier for Vendors. |
| GAID | String | Android only | Google Advertising ID. Requires user consent under relevant privacy frameworks. |
| App Set ID | String | Android only | Scoped to the developer's apps on the device. Does not require user consent. |
Location
| Property | Type | Description |
|---|---|---|
latitude | Double | Latitude coordinate. |
longitude | Double | Longitude coordinate. |
isForeground | Bool (iOS) / Boolean (Android) | Whether the location was collected with the app in the foreground. |
System
| Property | Type | Description |
|---|---|---|
| BSIN | String | Read-only. ZMP-generated unique user identifier. Retrieved via getCachedBSIN() (iOS) or observed via the setOnBsinChange() callback (Android). |
Custom properties
Use additionalProperties to attach arbitrary key-value pairs to the user profile. These appear under User Properties in ZMP.
iOS (Swift)
ZetaClient.shared.user?.build { user in
user.uid = "user-123"
user.additionalProperties = [
"plan": "premium",
"signup_source": "referral",
"preferences": ["email", "push"]
]
}
For Objective-C, see iOS Getting Started.
Android (Kotlin)
ZetaClient.user.builder()
.setUid("user-123")
.setAdditionalProperties(mapOf(
"plan" to "premium",
"signup_source" to "referral",
"preferences" to listOf("email", "push")
))
.submit()
For Java, see Android Getting Started.
Values must be JSON-encodable: strings, numbers, booleans, arrays, and dictionaries. All date-time values must be in ISO 8601 format, UTC.
Unique client ID (UCLID)
UCLID is a client-defined unique identifier used for identity resolution. It is not a custom property -- it has its own dedicated API and identity-merging behavior.
Before using UCLID, review these conditions:
- No two profiles may have the same UCLID name:value pair. If a profile is updated with a UCLID matching another profile, the profiles are merged.
- A UCLID pair is discarded if the same key already exists with a different value.
- Enabling UCLID requires site-configuration updates. Coordinate with your account team to ensure the configuration is correct. Using an incorrect or mismatched client ID name may result in errors.
iOS (Swift)
ZetaClient.shared.user?.setUniqueClientId("loyalty-id-456", forKey: "loyalty_id")
For Objective-C, see iOS Getting Started.
Android (Kotlin)
ZetaClient.user.setUniqueClientId(name = "loyalty_id", value = "loyalty-id-456")
For Java, see Android Getting Started.
Best practices
- Use consistent keys. Property keys are case-sensitive. Use the same casing across platforms and sessions (e.g., always
signup_source, neverSignupSource). - Use meaningful values. Avoid abbreviations or codes that are not self-explanatory in ZMP reporting.
- Do not store sensitive data. Never pass passwords, payment card numbers, health records, or government-issued IDs as user properties or custom properties.
- Test in staging. Verify identity resolution and property updates in a non-production ZMP site before going live.
- Call
clear()on sign-out. Failing to clear the session when the user changes causes events and properties to be attributed to the wrong profile.
Security considerations
Important: The SDK transmits user properties over HTTPS. Your app is responsible for ensuring it does not pass sensitive personal data (e.g., passwords, payment details, health records) through the SDK. Review the properties you send in your staging environment before enabling in production.
See also
- Event model -- auto-tracked events, custom events, screen tracking.
- Opt-in and opt-out -- tracking consent and opt-out behavior.
- Platform support -- feature availability by platform and SDK version.
