Skip to content

User Context ​

This page documents the ChWebSdk user-context API: fetching the current viewer with ChWebSdk.Context.User() and looking up community members with the ChWebSdk.User.* methods. All run as the visiting user, authorized by the community session cookie.

TIP

Prefer these SDK methods over a Connector for user data — they use the browser session and need no server-side secrets.

Context: Current Viewer ​

Context.User() ​

Fetches the current user for the active session. This is the direct replacement for reading inSidedData.user.

Returns: Promise<User>

  • Resolves to a User object for an authenticated visitor.
  • For an unauthenticated (guest) visitor, resolves to the guest projection — a User object with userId: null and username: "guest". It is never null; branch on userId to tell guest from member.
  • Throws if called outside a browser environment or if the network request fails.

Takes no parameters. rank, badges, and profileFields are always hydrated on every response.

No private data on the current viewer

Context.User() is readable by any script on the community page, so it never exposes private data — even for the authenticated viewer. Email address, private-message counts, subscription count, and login/registration source are not included in the response.

Checking authenticated vs. guest: branch on userId, not on null.

javascript
ChWebSdk.onReady(async () => {
  const me = await ChWebSdk.Context.User()

  if (me.userId === null) {
    // Guest — show a login prompt or public-only content
    return
  }

  // Authenticated — personalize the UI
  console.log(me.username)        // 'janedoe'
  console.log(me.userId)          // 101
  console.log(me.rank?.name)      // 'Regular'
  console.log(me.badges)          // [{ id: 100, title: 'First post', url: '/badge/first-post' }]
  console.log(me.profileFields)   // [{ id: 3, title: 'Seniority', value: 'senior', ... }]
})

User: Lookup and Listing Methods ​

All methods below are browser-only and operate on the community user directory. They return the public User shape — no private data (email, private-message counts, login source) is exposed by any of them.

User.getById(id) ​

Fetch a single user by numeric ID.

Returns: Promise<User | null> — resolves to null if the ID does not resolve.

ParameterTypeDescription
idnumber | stringUser ID. Numeric strings are accepted and coerced.
javascript
const user = await ChWebSdk.User.getById(101)
if (user) {
  console.log(user.username, user.rank?.name)
}

User.getUsersById(ids) ​

Fetch multiple users by an array of IDs in one request (batch lookup). Unresolved IDs are silently omitted — the result array may be shorter than the input.

Up to 100 IDs per request. IDs beyond the hundredth are dropped, not refused.

Returns: Promise<User[]> — array of resolved users. Order is not guaranteed to match the input; match results by userId (e.g. with .find()), not by position. Each item is a User object.

ParameterTypeDescription
idsArray<number | string>User IDs to fetch. Numeric strings are accepted.
javascript
const users = await ChWebSdk.User.getUsersById([101, 202, 303])
// users.length may be less than 3 if any ID did not resolve
users.forEach((u) => console.log(u.userId, u.username))

User.list(options?) ​

List and filter community members with pagination, sorting, and filtering. Returns a paginated result.

Returns: Promise<{ totalItems: number, items: User[] }>

  • totalItems: total number of users matching the filters (before pagination).
  • items: users on the requested page. Defaults to 25 per page (max 100) when size is omitted.
  • Every row is a fully hydrated User (rank, badges, profileFields included), so a full page of 100 is a heavier payload — request only the size you need.
OptionTypeDefaultDescription
searchstring—Substring match on username. An authenticated caller may also pass an email address here; a guest who does gets a 403 (guests can still search by username).
rolenumber[]—Filter by main role ID(s). OR semantics.
joinDateDateFilter—Filter on registration date.
lastActivityDateFilter—Filter on last activity date.
lastVisitDateFilter—Filter on last visit (login) date.
topicsNumberFilter—Filter on topics created.
repliesNumberFilter—Filter on replies created.
pointsNumberFilter—Filter on points.
pagenumber11-indexed page number.
sizenumber25Page size (1–100).
sortUserSortField'userId'Sort field.
order'asc' | 'desc''desc'Sort direction.

Role, badge, and profile-field IDs used in the filters and examples below are specific to each community. Find your community's values in its admin settings (the Roles, Badges, and Profile Fields sections) instead of reusing the sample IDs.

DateFilter — ISO-8601 datetime, ISO-8601 duration relative to now (e.g. 'P3D' = last 72 h), or { from?, to? } range:

javascript
// Users who joined in the last 7 days
const { items } = await ChWebSdk.User.list({ joinDate: 'P7D' })

// Users who joined in a specific range
const { items } = await ChWebSdk.User.list({
  joinDate: { from: '2024-01-01T00:00:00Z', to: '2024-12-31T23:59:59Z' }
})

NumberFilter — exact integer or { eq?, gt?, gte?, lt?, lte? } range:

javascript
// Users with 10 or more topics
const { items } = await ChWebSdk.User.list({ topics: { gte: 10 } })

UserSortField values: 'userId' | 'username' | 'replies' | 'topics' | 'points' | 'lastVisit' | 'joinDate' | 'lastActivity'

Example — list moderators sorted by last visit:

javascript
ChWebSdk.onReady(async () => {
  const { totalItems, items } = await ChWebSdk.User.list({
    role: [7],
    sort: 'lastVisit',
    order: 'desc',
    size: 20
  })
  console.log(`${items.length} of ${totalItems} moderators`)
  items.forEach((u) => console.log(u.username, u.lastVisit))
})

Example — paginate through all users:

javascript
ChWebSdk.onReady(async () => {
  const size = 100
  let page = 1
  let total = Infinity

  while ((page - 1) * size < total) {
    const result = await ChWebSdk.User.list({ page, size })
    total = result.totalItems
    result.items.forEach((u) => console.log(u.userId, u.username))
    page++
  }
})

User.getRecentlyActive(limit?) ​

Convenience wrapper around list(). Returns users sorted by lastVisit descending.

Returns: Promise<User[]>

ParameterTypeDefaultDescription
limitnumber10Maximum users to return.
javascript
const recentUsers = await ChWebSdk.User.getRecentlyActive(5)
recentUsers.forEach((u) => console.log(u.username, u.lastVisit))

User.getByRole(role, options?) ​

List users that hold one or more specified roles.

Returns: Promise<{ totalItems: number, items: User[] }> — defaults to 25 per page (max 100), same as list().

ParameterTypeDescription
rolenumber | number[]Role ID or array of IDs. OR semantics.
optionsobjectSame pagination and sort options as list() (minus role).
javascript
// Users with role id 7, first page
const { totalItems, items } = await ChWebSdk.User.getByRole(7, { size: 50 })

// Users with any of these roles
const { items } = await ChWebSdk.User.getByRole([7, 9])

User.search(query) ​

Search users by a query string. Returns a reduced field set optimized for mention/autocomplete UIs — use User.list() when you need the full user object.

Requires an authenticated session — a guest calling search() receives a 403 (this is a different endpoint from list(), and it is not open to guests at all).

Returns: Promise<UserSearchResult[]> — up to 25 users. This limit is fixed; search() takes no size parameter.

ParameterTypeDescription
querystringNon-empty search query

UserSearchResult object shape:

FieldTypeNotes
userIdnumberCanonical user ID.
usernamestringDisplay username.
profileUrlstring | nullRelative URL to the profile page.
avatarstringAvatar URL, or "" when none.
userTitlestringDisplay title.
reputationnumber | nullReputation score.
isBannedbooleantrue if the user holds the banned role.
badgesBadge[]Hydrated badges, without id.
rankRank | nullHydrated rank, without id.
javascript
const results = await ChWebSdk.User.search('jane')
results.forEach((u) => console.log(u.userId, u.username, u.avatar))

User Object Shape ​

All methods above return objects conforming to the unified User model.

Core identity fields ​

FieldTypeNotes
userIdnumber | nullCanonical user ID. null only on the guest projection. Use this in new code.
idnumber | nullDeprecated mirror of userId. Kept for backward compatibility; migrate to userId.
usernamestringDisplay username. "guest" on the guest projection.
namestringDeprecated alias of username.
firstNamestring | nullOften null due to visibility settings.
lastNamestring | null
avatarstringAvatar URL, or empty string "" when none.
profileUrlstring | nullRelative URL to the user's profile page (e.g. "/user/janedoe").
signaturestring | nullUser signature.
userTitlestringDisplay title (custom title or rank name; empty string if hidden).
companyIdstring | nullCompany identifier.

Role and moderation fields ​

FieldTypeNotes
isBannedbooleantrue if the user holds the banned role.
isModeratorbooleantrue if the user holds any moderator role.
rolenumber | nullMain role ID as an integer.
mainRolestring | nullMain role slug (e.g. "moderator", "roles.guest").
customRolesnumber[]Custom role IDs.

Rank fields ​

FieldTypeNotes
rankIdnumber | nullRank ID. null when the user has no rank.
rankRank | nullHydrated rank with display styling. The property is always present; the value is null when the user has no rank.

Rank object shape:

FieldTypeNotes
idnumberRank ID
namestringRank display name (e.g. "Regular")
colorstring | nullHex color for the rank name (e.g. "#3366ff")
isBoldbooleanWhether the rank name should be bold
isItalicbooleanWhether the rank name should be italic
isUnderlinebooleanWhether the rank name should be underlined
iconstring | nullIcon identifier
iconUrlstring | nullURL to the rank icon image
avatarIconstring | nullAvatar icon identifier
avatarIconUrlstring | nullURL to the avatar icon image

Badge fields ​

FieldTypeNotes
badgesBadge[]Hydrated badges. Always present. Unresolvable badge IDs are dropped — the array only contains objects.

Badge object shape:

FieldTypeNotes
idnumberBadge ID
titlestringBadge display name (e.g. "First post")
urlstring | nullRelative URL to the badge page (e.g. "/badge/first-post")

Group and profile fields ​

FieldTypeNotes
groupsnumber[]Group IDs the user belongs to.
profileFieldsProfileField[]Structured custom profile fields. Always hydrated.

ProfileField object shape:

FieldTypeNotes
idnumberProfile field ID
titlestringProfile field label (e.g. "Seniority")
typestringField type: 'text', 'textarea', 'select', 'radio', 'check', 'multiselect', 'date', etc.
valuestring | number | boolean | string[] | object | nullThe user's value for this field. null when unset.
visibilitynumberVisibility level of the field, as an integer.

Activity and engagement fields ​

FieldTypeNotes
topicsnumberTopics created.
repliesnumberReplies created.
pointsnumberPoints.
solvednumberBest-answer / solved count.
reputationnumber | nullReputation score. null if the reputation feature is disabled.
likesReceivednumberLikes received.
likesGivennumberLikes given.
followersnumberFollower count.
followingnumberFollowing count.

Date fields ​

FieldTypeNotes
joinDatestringRegistration timestamp as ISO-8601 datetime (e.g. "2022-04-12T09:23:18Z"). Not a Unix timestamp — the legacy inSidedData.user.joindate was a Unix int; this is a string.
lastActivitystring | nullLast activity timestamp (ISO-8601). May be null when no activity has been recorded.
lastVisitstring | nullLast visit/login timestamp (ISO-8601).

No private fields

The User object never carries private data — no email address, private-message counts, subscription count, login/registration source, or email-campaign opt-in. These are stripped on the server for every method, including Context.User() for the authenticated viewer. Obtain private data server-side through a Connector if a widget genuinely needs it.


Guest Handling ​

When an unauthenticated visitor calls ChWebSdk.Context.User(), it resolves to the guest projection — a User object with userId: null, username: "guest", and zeroed counts. It is never null, so always branch on me.userId === null before treating the viewer as a member.

For ChWebSdk.User.list() and related methods, guests get the public field set. Email-based search requires an authenticated session (guests receive a 403).

Private communities

On a private community, unauthenticated requests are redirected to the login page instead of returning data, so the SDK call rejects rather than resolving. Wrap calls in try/catch and treat a rejection as "not signed in."


Field Availability by Method ​

User.search() returns a reduced set optimized for autocomplete. Every other method — Context.User(), getById(), getUsersById(), list(), getByRole(), getRecentlyActive() — returns the full public User shape. No method exposes private data.

Field groupContext.User()Other User.* lookupssearch()
Base scalars (userId, username, avatar, …)✅✅Partial
rank✅✅✅ (without id)
badges✅✅✅ (without id)
profileFields✅✅❌
Private data (email, PM counts, subscriptions, login/register source, email-campaign opt-in)❌❌❌

Legacy Field Migration ​

If you are migrating code that reads inSidedData.user, use this table to find the canonical field name:

Legacy fieldCanonical field
userid (int)userId
nameusername
urlprofileUrl
userLevelreputation
rankName, rankIconrank.name, rank.iconUrl
topicsCounttopics
repliesCountreplies
solvedCountsolved
likeslikesReceived
likes_givenlikesGiven
joindate (Unix int)joinDate (ISO-8601 string — different type)

Legacy inSidedData.user fields carrying private data — email, pmUnreadCount, pmTotalCount, subscriptions, loginSource, registerSource — have no canonical equivalent. They are not exposed by any SDK method; read them server-side through a Connector if required.

joinDate type change

inSidedData.user.joindate was a Unix timestamp (integer). The canonical joinDate is an ISO-8601 datetime string. If you compare or format dates, update your parsing logic.


Error Handling ​

All methods throw on failure. Wrap calls in try/catch:

javascript
ChWebSdk.onReady(async () => {
  try {
    const me = await ChWebSdk.Context.User()
    if (me.userId === null) {
      // Guest — handle gracefully
      return
    }
    // Use me.username, me.rank, etc.
  } catch (err) {
    console.error('Failed to fetch user context:', err.message)
  }
})

Common error conditions:

ScenarioCause
"Context.User can only be called in a browser environment"Called outside a browser (e.g. during SSR or in Node).
HTTP 400Invalid filter operator, an unsupported sort field (e.g. sort=email), or an unsupported filter passed to list().
HTTP 403A guest called User.search() (authenticated-only), or passed an email-address term to list({ search }). Guest username search via list() is allowed.
HTTP 5xxA server error occurred. Retry after a brief delay.
Rejected call (private community)Unauthenticated requests are redirected to a login page instead of returning data; catch it and treat as "not signed in."

The SDK surfaces these as a rejected promise (a thrown Error), not as a structured status code you can switch on — the "Scenario" column describes the underlying cause, not a machine-readable field. Branch on whether the call rejected, and inspect err.message for detail; there is no reliable err.status to implement per-code handling.


Next Steps ​

  • Examples — runnable, copy-paste code for Context.User() and the User.* methods
  • Methods and Constructors — full reference for all SDK namespaces
  • Web SDK — availability and quick start
  • Passing User Context — use server-side template variables when building Connectors that need the viewer's identity

Gainsight CC Developer Portal