
## Introduction to the StatsigUser object

The StatsigUser object is the sole input you provide to SDKs to target gates and assign users to experiments. To target on an attribute, add it to your user object. Assembling this data is an important part of SDK setup. Provide as much information as practical, because each additional field can enrich your analyses and expand targeting options. Statsig also infers some information about each user from other traits (for example, Statsig resolves IP addresses into countries).

## Usage example in Node.js

{% codetabs %}
```jsx Node.js Example
//Create a user object
const user = new StatsigUser({ userID: "12345", email: "vincent@statsig.com"});
//Use it in getExperiment()
const my_experiment = statsig.getExperiment(user, "my_experiment_name") //<- any attribute you pass, you can target on
```
{% /codetabs %}

### I passed that attribute before: why do I need to pass it again?

You can view a specific user's historical attributes for analytics purposes through [User Profiles](/product-analytics/users-tab) in the Statsig console.

Historical attributes can't be used for targeting or gate/experiment evaluation at runtime. Statsig evaluates gates and experiment buckets based **only on the information you provide at the time of the check.** Millisecond evaluation performance depends on having all information available at request time, rather than querying historical data or storing large amounts of state in memory.

## User attributes

{% tabs %}
{% tab title="Client SDKs" %}
All user attributes can be explicitly supplied, and some can be inferred from a user's device or connection. Supplying one always overrides an inferred value.

| Key                 | Description                                                                                                                                                                                                                                                                                  | Example                                                                                                                    | Client SDK Support | Auto-infer |
|---------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------|--------------------|------------|
| `userID`            | ID representing a unique user. Statsig uses this ID to guarantee targeting consistency for Feature Gates and Experiments and to evaluate experiment results. If `User ID` doesn't exist yet, leave this empty; Statsig uses a `Stable ID` persisted locally for evaluations. | `your_user_id`                                                                                                             | All                |            |
| `email`             | Email of the user.                                                                                                                                                                                                                                                                           | `marcos@statsig.com`                                                                                                       | All                |            |
| `userAgent`         | User agent of the browser. The SDK decodes this to determine the Browser and Operating System of the user's context. The SDK infers this if not provided.                                                                                                                                       | `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.40 Safari/537.36` | Web                | ✔          |
| `ip`                | IP address of the user. Inferred from the request to /initialize if not provided                                                                                                                                         | `192.168.1.101`                                                                                                            | All                | ✔          |
| `country`           | 2-letter country code of the user. This can be supplied or inferred, and you can target based on the country code in both cases. When inferred, the country code follows ISO-3166.                                                                                                            | `US`                                                                                                                       | All                | ✔          |
| `locale`            | Locale of the user. When using the Android or iOS SDK, the SDK infers this if not provided.                                                                                                                                                                                                | `en_US`                                                                                                                    | Mobile             | ✔          |
| `appVersion`        | Version of the app the user is using. When using the Android or iOS SDK, the SDK infers this if not provided.                                                                                                                                                                              | `1.0.1`                                                                                                                    | Mobile             | ✔          |
| `systemName`        | When using the Android/iOS SDKs, the SDK automatically assigns this, but you can also provide an explicit operating system to override.                                                                                                                                                     | `Android`                                                                                                                  | All                | ✔          |
| `systemVersion`     | When using the Android/iOS SDKs, the SDK automatically assigns this, but you can also provide an explicit OS version to override.                                                                                                                                                           | `15.4`                                                                                                                     | All                | ✔          |
| `browserName`       | When using the Web SDK, the SDK automatically assigns this, but you can also provide an explicit Browser Name to override.                                                                                                                                                                  | `Chrome`                                                                                                                   | Web                | ✔          |
| `browserVersion`    | When using the Web SDK, the SDK automatically assigns this, but you can also provide an explicit Browser Version to override.                                                                                                                                                               | `45.0`                                                                                                                     | Web                | ✔          |
| `custom`            | Dictionary that can contain key/value pairs that can be used for Feature Gate targeting. Statsig stores this dictionary and makes it available after targeting.                                                                                                                        | `{subscriber: "yes", ...}`                                                                                         | All                |            |
| `privateAttributes` | Dictionary that can contain key/value pairs that can be used for Feature Gate targeting. Statsig does **not** store this dictionary after using it for targeting, and removes it from any `log_event` calls.                                                                | `{sensitive_field: "sensitive_information", ...}`                                                                          | All                |            |
| `customIDs`         | Dictionary that can contain key/value pairs used as the randomization unit ID for experiments that are set up using these IDs instead of the `User ID`.                                                                                                                                      | `{account_id: "23456555", company_id: "company_xyz"}`                                                                      | All                |            |

### How to override the stable ID

Client SDKs generate a `stableID` for logged-out or device-level targeting. If you already manage a durable device identifier, override the SDK-generated value before or during initialization so Statsig uses your identifier for stable ID-based evaluations.

{% tabs %}
{% tab title="JavaScript" %}
```tsx
import { StatsigClient, StatsigUser } from '@statsig/js-client';

const user: StatsigUser = {
  userID: 'a-user',
  customIDs: {
    stableID: 'my-custom-stable-id',
  },
};

const client = new StatsigClient('client-sdk-key', user);
await client.initializeAsync();
```
{% /tab %}

{% tab title="Android" %}
```kotlin
val options = StatsigOptions(overrideStableID = "my-custom-stable-id")
Statsig.initialize(app, "client-sdk-key", user, options = options)
```
{% /tab %}

{% tab title="iOS" %}
```swift
let options = StatsigOptions(overrideStableID: "my-custom-stable-id")
Statsig.initialize(sdkKey: "client-sdk-key", user: user, options: options)
```
{% /tab %}
{% /tabs %}

{% callout type="note" %}
When you override the Stable ID in a client SDK, the SDK persists that value locally and reuses it on later sessions unless local storage is cleared or the app is reinstalled.
{% /callout %}
{% /tab %}

{% tab title="Server SDKs" %}
All user attributes can be explicitly supplied, and some can be inferred from a provided IP Address or User Agent. Supplying one always overrides an inferred value.

| Attributes          | Description                                                                                                                                                                                                          | Example                                                                                                                    | Auto Infer |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |------------|
| `userID`            | ID representing a unique user. Statsig uses this ID to guarantee targeting consistency for Feature Gates and Experiments and to evaluate experiment results.                                         | `your_user_id`                                                                                                             |            |
| `email`             | Email of the user                                                                                                                                                                                                    | `marcos@statsig.com`                                                                                                       |            |
| `userAgent`         | User agent of the browser. The SDK decodes this to determine the Browser and Operating System of the user's context                                                                                                  | `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.40 Safari/537.36` |            |
| `ip`                | IP address of the user                                                                                                                                                                                               | `192.168.1.101`                                                                                                            |            |
| `country`           | 2 letter country code of the user                                                                                                                                                                                    | `US`                                                                                                                       | ✔, from IP |
| `locale`            | Locale of the user                                                                                                                                                                                                   | `en_US`                                                                                                                    | ✔, from IP |
| `appVersion`        | Version of the app the user is using                                                                                                                                                                                 | `1.0.1`                                                                                                                    |
| `custom`            | Dictionary that can contain key/value pairs that can be used for Feature Gate targeting. Statsig stores this dictionary and makes it available after targeting                                                 | `{skill_level: "5", is_subscriber:"false" ...}`                                                                                         |
| `privateAttributes` | Dictionary that can contain key/value pairs that can be used to evaluate feature gate conditions and segment conditions. Statsig does **not** store this dictionary after using it for targeting, and removes it from any log\_event calls | `{sensitive_field: "sensitive_information", ...}`                                                                          |
| `customIDs`         | Dictionary that can contain key/value pairs used as the randomization unit ID for experiments that are set up using these IDs instead of the `User ID`                                                               | `{account_id: "23456555", company_id: "company_xyz"}`                                                                      |

### How to override "Operating System" and "Browser" explicitly

Operating system and browser are two default targeting options in Statsig. When you set the `userAgent` field, server SDKs parse the OS and browser information from it. To set these values explicitly, provide them either at the top level of the user object (which some language type systems may not allow) or inside the `custom` object, using these keys:

* Operating System: os\_name
* OS Version: os\_version
* Browser Name: browser\_name
* Browser Version: browser\_version

You can set these values either of the following ways in the user object:

{% codetabs %}
```json Example
{
  "userID": "uuid",
  "os_name": "Android", // top level
  "custom": {
    "os_name": "iOS"
  }
}
```
{% /codetabs %}

If you explicitly set either of these fields, it takes precedence over the value inferred from the `userAgent` field.
{% /tab %}
{% /tabs %}

### Have sensitive user PII data that shouldn't be logged?

The StatsigUser object includes a `privateAttributes` field, which is a key/value dictionary for setting private user attributes. Statsig uses attributes in `privateAttributes` only for evaluation and targeting, and removes them from any logs before sending them to the Statsig server.

For example, if you have feature gates that should only pass for users with emails ending in "@statsig.com" but don't want to log email addresses to Statsig, add the key-value pair `{ email: "my_user@statsig.com" }` to `privateAttributes` on the user.

### Time-based conditions

All SDKs (server and client-side) support Unix timestamps in milliseconds to evaluate time-based conditions (After time, Before time). Convert your DateTime field to a standard format before evaluation.

Statsig has added ISO timestamp support to some server SDKs:

* `java-server` SDK v1.6.0 and later: supports [DateTime fields in `ISO_INSTANT` format](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_INSTANT)
* `go` SDK v1.12.1 and later: supports [DateTime fields in `RFC3339` format](https://pkg.go.dev/time#pkg-constants)
* `python` SDK: supports epoch time in seconds. The `time.time()` function may include sub-second components, so round the value to an integer.

For server SDKs supported by server core (Java, Python, PHP, Rust, Node), ISO timestamp support covers:

* [DateTime fields in `ISO_INSTANT` format](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_INSTANT)
* [DateTime fields in `RFC3339` format](https://pkg.go.dev/time#pkg-constants)

### Why is an ID always required for server SDKs?

In server SDKs, a StatsigUser with a `userID` (or `customID`) is required for `checkGate`, `getConfig`, and `getExperiment`. Pass the user ID whenever it's available: users get a stable experience, and events are attributed to the correct users so you can accurately measure downstream metrics.

Guidance for cases where you can't pass an ID:

1. **On/off feature gates or non-percent-based rules (such as country targeting):** Pass any non-empty identifier or a hardcoded string. If you do not have the actual user ID, use **a random ID under 100** as a placeholder. Do not use a purely random ID, because this prevents event deduplication, inflates event volume, and increases your Statsig bill.

2. **Partial rollout with regression checks before full rollout:** Pass an ID in every `checkGate`, `getConfig`, and `getExperiment` call, as well as in any `logEvent` calls. Without an ID, Statsig cannot attribute logged events to the correct users or calculate metrics accurately.

3. **A/B experiment to decide whether to ship a feature:** Pass persistent user IDs, for the same reason as case 2.

4. **No logged-in user (for example, optimizing the login flow):** Set a stable identifier as a cookie or in local storage and pass it with each Statsig call. Client SDKs provide a stable ID automatically.

For use cases not covered here, reach out in the [Slack community](https://statsig.com/slack).

### Pass all IDs when you have them

A common mistake is accidentally exposing users without a `userID` to a user-ID-based experiment. All such users are bucketed into the same group (wherever the null `userID` hashes to), which skews results. If you run experiments on multiple ID types, pass every available identifier.
