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

# User Identity

> Associate user context with Grantiva for personalized flags and feedback

By default, Grantiva identifies devices anonymously. You can optionally associate a user identity for:

* **Feature flags** targeted by user properties
* **Feedback** that persists across devices for the same user
* **Analytics** grouped by user rather than device

## Identify a user

```swift theme={null}
await grantiva.identify(UserContext(
    userId: "user_123",
    properties: [
        "plan": "premium",
        "country": "US",
        "beta_tester": "true"
    ]
))
```

Or with just a user ID:

```swift theme={null}
await grantiva.identify("user_123")
```

All services (feedback, flags) automatically use this context after identification. Caches are cleared on identity change so services re-fetch with the new context.

## UserContext

```swift theme={null}
UserContext(
    userId: String,
    properties: [String: String] = [:]
)
```

| Field        | Type               | Description                           |
| ------------ | ------------------ | ------------------------------------- |
| `userId`     | `String`           | Stable unique identifier for the user |
| `properties` | `[String: String]` | Custom key-value pairs for targeting  |

Properties are used for feature flag targeting and segmentation. Common examples:

* `"plan"`: `"free"`, `"pro"`, `"business"`
* `"country"`: `"US"`, `"DE"`, `"JP"`
* `"beta_tester"`: `"true"`
* `"company_size"`: `"50"`

## Subject ID (subscription sharing unit)

Separate from user identity, `setSubjectId` links the device to a **sharing unit** (family/household) for [subscription entitlement claims](/concepts/subscription-claims) (SDK 2.1.0+, Enterprise):

```swift theme={null}
// A stable UUID string your app mints per household
grantiva.setSubjectId(familyId)

// When the device leaves the household
grantiva.clearSubjectId()

// Read back
let current = grantiva.subjectId
```

The id rides the next attestation or token refresh; the backend then projects `custom_claims.subscription` into the JWT for every device sharing the same id. Use the identical value as the StoreKit `appAccountToken` and Stripe `client_reference_id`.

Don't confuse the two:

|             | `identify(_:)`                      | `setSubjectId(_:)`                                         |
| ----------- | ----------------------------------- | ---------------------------------------------------------- |
| Scopes      | The individual user                 | The paying household                                       |
| Drives      | Flag targeting, feedback, analytics | The `subscription` JWT claim                               |
| Cardinality | One per person                      | One per sharing unit — same value on every member's device |

## Device context (automatic)

The SDK automatically collects device context — you don't need to set this:

```swift theme={null}
grantiva.currentUserContext?.device.appBundleId    // "com.yourapp"
grantiva.currentUserContext?.device.appVersion      // "2.1.0"
grantiva.currentUserContext?.device.deviceModel     // "iPhone15,2"
grantiva.currentUserContext?.device.osVersion       // "18.0"
grantiva.currentUserContext?.device.locale          // "en_US"
grantiva.currentUserContext?.device.environment     // "device" or "simulator"
```

## Clear identity

Call on user logout:

```swift theme={null}
await grantiva.clearIdentity()
```

Services fall back to device-based identity. Feedback submitted before logout remains associated with the user.

## Read current identity

```swift theme={null}
grantiva.currentUserId       // String? — current user ID
grantiva.currentUserContext   // UserContext? — full context
```
