User (StatsigUser) Object
Reference for the StatsigUser object used by SDKs, including fields like userID, email, country, custom properties, and private attributes.
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
//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
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 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
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.
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();
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.
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-serverSDK v1.6.0 and later: supports DateTime fields inISO_INSTANTformatgoSDK v1.12.1 and later: supports DateTime fields inRFC3339formatpythonSDK: supports epoch time in seconds. Thetime.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:
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:
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.
Partial rollout with regression checks before full rollout: Pass an ID in every
checkGate,getConfig, andgetExperimentcall, as well as in anylogEventcalls. Without an ID, Statsig cannot attribute logged events to the correct users or calculate metrics accurately.A/B experiment to decide whether to ship a feature: Pass persistent user IDs, for the same reason as case 2.
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.
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.
Was this helpful?