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

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.

IdentifierDescriptioniOSAndroidReact NativeFlutter
uidPrimary user identifier set by your app.0.1.00.1.00.1.00.1.0
emailIdEmail treated as the unique identifier (populates ZMP Identifiers).0.1.00.1.00.1.00.1.0
UCLIDClient-defined unique identifier for identity resolution.0.2.00.2.00.2.00.2.0

Important: If you set uid to an email address in the same build call, the emailId value is ignored.

Identity resolution behavior

When your app sets user identity properties, ZMP follows this sequence:

  1. Check for existing profile. ZMP looks for a profile matching the provided uid, emailId, or UCLID.
  2. 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.
  3. 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

PropertyTypeDescription
uidStringPrimary user identifier set by your app.
nameStringDisplay name.
firstNameStringFirst name.
lastNameStringLast name.
sourceStringAcquisition source (e.g., "organic", "campaign_xyz").

Lifecycle

PropertyTypeDescription
signedUpAtStringISO 8601 date-time (UTC) when the user signed up.

Contact

PropertyTypeDescription
emailZTUserEmailEmail as a contact with optional additional properties (preferences, subscription status).
phoneZTUserPhonePhone as a contact with optional additional properties.
emailIdStringEmail as the unique identifier. Only accepted if uid is not an email address.

Device

PropertyTypePlatformDescription
Push tokenData (iOS) / String (Android)AllDevice token for push notification delivery.
IDFAStringiOS onlyIdentifier for Advertisers. Your app handles ATT prompting.
IDFVStringiOS onlyIdentifier for Vendors.
GAIDStringAndroid onlyGoogle Advertising ID. Requires user consent under relevant privacy frameworks.
App Set IDStringAndroid onlyScoped to the developer's apps on the device. Does not require user consent.

Location

PropertyTypeDescription
latitudeDoubleLatitude coordinate.
longitudeDoubleLongitude coordinate.
isForegroundBool (iOS) / Boolean (Android)Whether the location was collected with the app in the foreground.

System

PropertyTypeDescription
BSINStringRead-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, never SignupSource).
  • 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