> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zeotap.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Track User Identities

> Persistently identify users by associating various identifiers with their activity.

<Warning>
  **Important:** Please ensure your CMP configuration includes new **Vendor ID 1469** for 1st Party data tracking. Additionally, include **Vendor ID 301** if cookie sync is enabled. [Learn more](/articles/sdks/web-js/configurations/consent-options#shouldcheckzeotapvendorconsent)
</Warning>

The `setUserIdentities` method is used to identify users by associating them with specific identifiers (like email, phone number, or your own internal IDs). This is crucial for cross-session user tracking and building comprehensive user profiles.

**Why use it?**

* **User Stitching:** Allows Zeotap to link user activity across different sessions or devices when a known identifier is provided.
* **Data Enrichment:** Provides key identifiers needed for potential data enrichment processes.
* **Audience Building:** Enables creating audiences based on specific known identifiers.

<Tip>
  **Persistence**

  Identifiers set using `setUserIdentities()` are persisted and automatically included in the `user` node of the payload for all subsequent events sent during the user's session(s).
</Tip>

## Syntax

```java theme={null}
Collect.getInstance().setUserIdentities(Map<String, String> identities, SDKCallback callback)
```

## Parameters

| Parameter  | Type                  | Required | Description                                    |
| ---------- | --------------------- | -------- | ---------------------------------------------- |
| identities | `Map<String, String>` | Yes      | A map containing user identity key-value pairs |
| callback   | `SDKCallback`         | Optional | Callback to handle function response           |

## Understanding Identifier Types

You can send different categories of identifiers:

1. **Personal Identifiable Information (PII):** Standardized identifiers like email or phone number. These can be sent raw or pre-hashed.
2. **Custom Identities:** Your own first-party identifiers (e.g., `crmId`, `loyaltyId`). Hashing configurations don't apply to these.

## Choosing Your Hashing Strategy

Before using `setUserIdentities`, you must decide how PII (like email and phone numbers) will be handled regarding hashing. This choice affects your SDK configuration and the keys you use in the `setUserIdentities` call. Click on each scenario below for details:

<div style={{"display": "flex", "alignItems": "baseline", "gap": "15px"}}>
  ### Sending Raw Identifiers
</div>

<details style={{marginLeft: "1rem"}}>
  <summary><strong>Scenario 1: Sending Raw Identifiers (Implementation Steps)</strong></summary>
  <p>This approach involves sending the user's actual, readable identifiers (like email or phone number) directly to the Zeotap SDK. It's often the simplest method as you don't handle hashing yourself; Zeotap's backend takes care of processing.</p>

  **Implementation Steps:**

  1. **Configure the SDK Initialization:**
     To use this scenario, you **must** explicitly tell the SDK *not* to perform hashing itself and confirm that the data you will provide is *not* already hashed:

     ```java title="SDK Initialization for Raw Identifiers" theme={null}
     CollectOptions options = CollectOptions.builder(this)
         .credential("YOUR_WRITE_KEY")
         .hashIdentities(false)      // Crucial: Tells the SDK *NOT* to hash the values itself.
         .areIdentitiesHashed(false) // Crucial: Confirms the values you'll provide are *NOT* already hashed.
         .build();

     Collect.init(options);
     ```

  2. **Send Identifiers Using Standard Keys and Raw Values:**

       <details style={{marginLeft: "1rem"}}>
         <summary><strong>Email (Raw)</strong></summary>

         ```java title="Sending Raw Email" theme={null}
         Map<String, String> identities = new HashMap<>();
         identities.put("email", "example@gmail.com");

         Collect.getInstance().setUserIdentities(identities);
         ```

         The email will be passed in the payload:

         ```json title="Identities in payload" {9-9} theme={null}
             "events": [
                 {
                 "event": {
                     "eventName": "goToHome",
                     "eventTimestamp": 1745959356443
                 },
                 "user": {
                     "zi": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
                     "email": "example@gmail.com"
                 },
                 "page": { /* ... */ },
                 "version": "2.2.8"
                 }
             ]
         ```
       </details>

       <details style={{marginLeft: "1rem"}}>
         <summary><strong>Cell phone (Raw)</strong></summary>
         <p>To send the user's raw cell phone number:</p>

         <ul>
           <li>Use the standard key: <code>cellno</code>.</li>
           <li>Provide the actual, unhashed phone number string as the value.</li>
           <li><strong>Recommended Format:</strong> Use <code>'\[code]-\[number]'</code> (e.g., <code>'1-1234567890'</code>).</li>
         </ul>

         ```java title="Sending Raw Cell Phone" theme={null}
         Map<String, String> identities = new HashMap<>();
         identities.put("cellno", "1-1234567890");

         Collect.getInstance().setUserIdentities(identities);
         ```

         The `cellno` will be passed in the payload:

         ```json title="Identities in payload" {9-9} theme={null}
             "events": [
                 {
                 "event": {
                     "eventName": "pageView",
                     "eventTimestamp": 1745960123456
                 },
                 "user": {
                     "zi": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
                     "cellno": "1-1234567890" // Raw cellno sent
                 },
                 "page": { /* ... */ },
                 "version": "2.2.11"
                 }
             ]
         ```
       </details>

       <details style={{marginLeft: "1rem"}}>
         <summary><strong>Login ID (Raw)</strong></summary>

         ```java title="Sending Raw Login ID" theme={null}
         Map<String, String> identities = new HashMap<>();
         identities.put("loginid", "testuser");

         Collect.getInstance().setUserIdentities(identities);
         ```

         The `loginid` will be passed in the payload:

         ```json title="Identities in payload" {6-6} theme={null}
             "events": [
                 {
                  "event": { /* ... */ },
                  "user": {
                     "zi": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
                     "loginid": "testuser" // Raw loginid sent
                  },
                  "page": { /* ... */ }
                 }
             ]
         ```
       </details>
</details>

<div style={{"display": "flex", "alignItems": "baseline", "gap": "15px"}}>
  ### Sending Pre-Hashed Identifiers
</div>

<details style={{marginLeft: "1rem"}}>
  <summary><strong>Scenario 2: Sending Pre-Hashed Identifiers (Implementation Steps)</strong></summary>

  <p>In this scenario, your application hashes PII *before* sending it to the SDK. You must use specific keys corresponding to the hash type you generated.</p>

  **Implementation Steps:**

  1. **Configure the SDK Initialization:**

     ```java title="SDK Initialization for Pre-Hashed Identifiers" theme={null}
     CollectOptions options = CollectOptions.builder(this)
         .credential("YOUR_WRITE_KEY")
         .hashIdentities(false)
         .areIdentitiesHashed(true)
         .build();

     Collect.init(options);
     ```

  2. **Send Identifiers using `setUserIdentities`:**

       <details style={{marginLeft: "1rem"}}>
         <summary><strong>Email (Hashed)</strong></summary>

         ```java title="Sending Pre-Hashed Email (SHA-256 Lowercase)" theme={null}
         Map<String, String> identities = new HashMap<>();
         identities.put("email_sha256_lowercase", "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2");

         Collect.getInstance().setUserIdentities(identities);
         ```

         The specific hashed email key and value will be passed in the payload:

         ```json title="Identities in payload" {6-6} theme={null}
             "events": [
                 {
                  "event": { /* ... */ },
                  "user": {
                     "zi": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
                     "email": { "sha256_lowercase": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2" }
                  },
                  "page": { /* ... */ }
                 }
             ]
         ```
       </details>

       <details style={{marginLeft: "1rem"}}>
         <summary><strong>Cell Phone (Hashed)</strong></summary>

         ```java title="Sending Pre-Hashed Cell Phone (SHA-256)" theme={null}
         Map<String, String> identities = new HashMap<>();
         identities.put("cellno_with_country_code_sha256", "f6e5d4c3b2a1a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c9d8e7f6a5b4");
         identities.put("cellno_without_country_code_sha256", "f6e5d4c3b2a1a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c9d8e7f6a5b4");

         Collect.getInstance().setUserIdentities(identities);
         ```

         The specific hashed cell phone key and value will be passed in the payload:

         ```json title="Identities in payload" {8-9} theme={null}
             "events": [
                 {
                  "event": { /* ... */ },
                  "user": {
                     "zs": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                     "zi": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
                     "zi_domain": ".zeotap.com",
                     "cellno_with_country_code": {"sha256": "f6e5d4c3b2a1a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c9d8e7f6a5b4"},
                     "cellno_without_country_code": {"sha256": "f6e5d4c3b2a1a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c9d8e7f6a5b4"}
                  },
                  "page": { /* ... */ }
                 }
             ]
         ```
       </details>

       <details style={{marginLeft: "1rem"}}>
         <summary><strong>Login ID (Hashed)</strong></summary>

         ```java title="Sending Pre-Hashed Login ID (SHA-256 Lowercase)" theme={null}
         Map<String, String> identities = new HashMap<>();
         identities.put("loginid_sha256_lowercase", "g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2a3b4c5d6e7f8");

         Collect.getInstance().setUserIdentities(identities);
         ```

         The specific hashed login ID key and value will be passed in the payload:

         ```json title="Identities in payload" {6-6} theme={null}
             "events": [
                 {
                  "event": { /* ... */ },
                  "user": {
                     "zi": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
                     "loginid": {"sha256_lowercase": "g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2a3b4c5d6e7f8"}
                  },
                  "page": { /* ... */ }
                 }
             ]
         ```
       </details>
</details>

<div style={{"display": "flex", "alignItems": "baseline", "gap": "15px"}}>
  ### SDK Performs Hashing
</div>

<details style={{marginLeft: "1rem"}}>
  <summary><strong>Scenario 3: SDK Performs Hashing (Client-Side Implementation)</strong></summary>

  <p>In this scenario, you provide raw PII to the SDK function, but configure the SDK to hash these values *before* sending the data over the network.</p>

  **Implementation Steps:**

  1. **Configure the SDK Initialization:**

     ```java title="SDK Initialization for SDK Hashing" theme={null}
     CollectOptions options = CollectOptions.builder(this)
         .credential("YOUR_WRITE_KEY")
         .hashIdentities(true)
         .areIdentitiesHashed(false)
         .build();

     Collect.init(options);
     ```

  2. **Send Identifiers using `setUserIdentities`:**

       <details style={{marginLeft: "1rem"}}>
         <summary><strong>Email (Raw - SDK Hashes)</strong></summary>

         ```java title="Sending Raw Email (SDK will hash)" theme={null}
         Map<String, String> identities = new HashMap<>();
         identities.put("email", "user@example.com");

         Collect.getInstance().setUserIdentities(identities);
         ```

         The SDK will hash the email and send multiple hash variants in the payload:

         ```json title="Identities in payload (SDK Hashed)" {6-13} theme={null}
             "events": [
                 {
                  "event": { /* ... */ },
                  "user": {
                     "zi": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
                     "email": {
                         "sha256_lowercase": "sha256_hash_of_user@example.com",
                         "sha256_uppercase": "sha256_hash_of_USER@EXAMPLE.COM",
                         "md5_lowercase": "md5_hash_of_user@example.com",
                         "md5_uppercase": "md5_hash_of_USER@EXAMPLE.COM",
                         "sha1_lowercase": "sha1_hash_of_user@example.com",
                         "sha1_uppercase": "sha1_hash_of_USER@EXAMPLE.COM"
                     }
                  },
                  "page": { /* ... */ }
                 }
             ]
         ```
       </details>

       <details style={{marginLeft: "1rem"}}>
         <summary><strong>Cell Phone (Raw - SDK Hashes)</strong></summary>

         ```java title="Sending Raw Cell Phone (SDK will hash)" theme={null}
         Map<String, String> identities = new HashMap<>();
         identities.put("cellno", "1-1234567890");

         Collect.getInstance().setUserIdentities(identities);
         ```

         The SDK will generate multiple hashes (SHA-256, MD5, SHA-1) for each representation (without country code, with country code, E.164) and send them in the payload:

         ```json title="Identities in payload (SDK Hashed - Cellno)" {6-20} theme={null}
             "events": [
                 {
                  "event": { /* ... */ },
                  "user": {
                     "zi": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
                     "cellno_without_country_code": {
                         "sha256": "sha256_hash_of_1234567890",
                         "md5": "md5_hash_of_1234567890",
                         "sha1": "sha1_hash_of_1234567890"
                     },
                     "cellno_with_country_code": {
                         "sha256": "sha256_hash_of_11234567890",
                         "md5": "md5_hash_of_11234567890",
                         "sha1": "sha1_hash_of_11234567890"
                     },
                     "cellphone_number_e164": {
                         "sha256": "sha256_hash_of_11234567890",
                         "md5": "md5_hash_of_11234567890",
                         "sha1": "sha1_hash_of_11234567890"
                     }
                  },
                  "page": { /* ... */ }
                 }
             ]
         ```
       </details>

       <details style={{marginLeft: "1rem"}}>
         <summary><strong>Login ID (Raw - SDK Hashes)</strong></summary>

         ```java title="Sending Raw Login ID (SDK will hash)" theme={null}
         Map<String, String> identities = new HashMap<>();
         identities.put("loginid", "UserLogin123");

         Collect.getInstance().setUserIdentities(identities);
         ```

         The SDK will generate multiple standard hashes (SHA-256, MD5, SHA-1, lower/upper case) and send them nested under the `loginid` key in the payload:

         ```json title="Identities in payload (SDK Hashed - Login ID)" {6-12} theme={null}
             "events": [
                 {
                  "event": { /* ... */ },
                  "user": {
                     "zi": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
                     "loginid": {
                         "sha256_lowercase": "hash_of_userlogin123",
                         "sha256_uppercase": "hash_of_USERLOGIN123",
                         "md5_lowercase": "md5_hash_of_userlogin123",
                         "md5_uppercase": "md5_hash_of_USERLOGIN123",
                         "sha1_lowercase": "sha1_hash_of_userlogin123",
                         "sha1_uppercase": "sha1_hash_of_USERLOGIN123"
                     }
                  },
                  "page": { /* ... */ }
                 }
             ]
         ```
       </details>
</details>

### PII Identifier Key Reference

| PII Property   | Key to Use if Sending RAW <br /> *(Scenarios 1 & 3)* | Key to Use if Sending PRE-HASHED <br /> *(Scenario 2 Only)*                                                                                                                                                    | Description & Important Notes                                                                                                        |
| :------------- | :--------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------- |
| **Email**      | `email`                                              | `email_sha256_lowercase`,`email_sha256_uppercase`, `email_md5_lowercase`, `email_md5_uppercase`, `email_sha1_lowercase`, `email_sha1_uppercase`                                                                | User's email address. Use the `email` key for raw input. Use one of the specific hashed keys if you provide a pre-hashed value.      |
| **Cell Phone** | `cellno`                                             | `cellno_without_country_code_sha256`, `cellno_without_country_code_md5`, `cellno_without_country_code_sha1`, `cellno_with_country_code_sha256`, `cellno_with_country_code_md5`,`cellno_with_country_code_sha1` | User's cell phone number. <br /> **For Raw:** Use `cellno`. <br /> **For Pre-Hashed:** Use the specific key matching your hash type. |
| **Login ID**   | `loginid`                                            | `loginid_sha256_lowercase`,`loginid_sha256_uppercase`, `loginid_md5_lowercase`, `loginid_md5_uppercase`, `loginid_sha1_lowercase`, `loginid_sha1_uppercase`                                                    | User's login ID. Use the `loginid` key for raw input. Use one of the specific hashed keys if you provide a pre-hashed value.         |

## Custom Identities

```java theme={null}
Map<String, String> identities = new HashMap<>();
identities.put("email", "user@example.com");
identities.put("crmId", "12345-ABC");
identities.put("visitorId", "analytics_client_id_here");

Collect.getInstance().setUserIdentities(identities);
```

## Set User identities with callbacks

```java theme={null}
Map<String, String> identities = new HashMap<>();
identities.put("email", "user@example.com");

Collect.getInstance().setUserIdentities(identities, (response) -> {
    // {status: "SUCCESS", message: "User identities set successfully"}
});
```

## Removing User identities

This method is used to remove user identities that are set by the `setUserIdentities` method. This will remove all the identities from the storage as well from all subsequent events that made by SDK.

```java theme={null}
Collect.getInstance().unSetUserIdentities();
```

## Best Practices

1. **Call Early**: Set user identities as soon as they are available, typically after user login or app launch if the user is already authenticated.

2. **Use Consistent Identifiers**: Ensure the same identifiers are used across all platforms (Web, iOS, Android) for the same user.

3. **Include Multiple Identities**: Provide multiple identity types when available to improve user matching accuracy.

4. **Handle Privacy**: Ensure you have proper user consent before collecting and sending personal identifiers.

## Error Handling

The method will fail silently if:

* The SDK is not initialized
* Invalid data types are provided
* Network connectivity issues occur (data will be queued for later transmission)
