User attribute targeting

3 min readUpdated 2026-05-19

How user attributes work

When you call window.zenstep.identify(), you pass user properties as the second argument:

window.zenstep.identify("user-123", {
  plan: "grow",
  role: "admin",
  createdAt: "2026-01-15",
  company: "Acme Corp",
  seatsUsed: 3,
});

Zenstep stores these attributes for the session and uses them to evaluate targeting rules in real time. Attributes are not persisted server-side — they must be sent fresh on every page load.

Supported attribute types

| Type | Examples | | ----------- | ----------------------------------------------------------- | | String | "grow", "admin", "en-US" | | Number | 3, 42.5 | | Boolean | true, false | | Date | ISO 8601 string: "2026-01-15" or "2026-01-15T10:30:00Z" |

String operators

| Operator | Matches when | | ---------------- | ------------------------------------------- | | equals | Exact match (case-insensitive) | | does not equal | Not an exact match | | contains | Attribute includes the value as a substring | | starts with | Attribute starts with the value | | is set | Attribute exists and is not null/undefined | | is not set | Attribute is missing or null |

Number operators

| Operator | Matches when | | ----------------------- | ------------------- | | equals | Exact numeric match | | greater than | Attribute > value | | less than | Attribute < value | | greater than or equal | Attribute ≥ value | | less than or equal | Attribute ≤ value |

Date operators

| Operator | Matches when | | ----------------- | -------------------------------------------- | | before | Attribute date is before the specified date | | after | Attribute date is after the specified date | | within the last | Attribute date is within N days/hours of now | | more than ago | Attribute date is more than N days/hours ago |

Relative date targeting is the most useful pattern for onboarding. Example — show a welcome tour to users who signed up in the last 3 days:

createdAt  within the last  3 days

Boolean operators

| Operator | Matches when | | ---------- | ------------------------------- | | is true | Attribute is exactly true | | is false | Attribute is false or not set |

Practical examples

Show to admin users only:

role  equals  admin

Show to users on the free plan:

plan  equals  free

Show to new users (signed up in last 7 days):

createdAt  within the last  7 days

Show to power users:

seatsUsed  greater than  5

Show only when a custom attribute is set:

betaFeatureEnabled  is true

Attribute names are case-sensitive

plan and Plan are different attributes. Make sure the attribute name in your targeting rule exactly matches what you pass in identify().

Attributes are session-only

Zenstep evaluates attributes from the most recent identify() call in the current session. If a user's plan changes and they haven't re-authenticated (which would trigger a new identify() call), the old attribute value is used.

For critical targeting (e.g., limiting a feature to paid users), always call identify() with fresh data on every login — not just on first sign-up.

⚠️

Never use user attributes as a security gate. Targeting is client-side — it controls what Zenstep shows, not what your app allows. Use server-side authorization for access control.

Was this helpful?