Groups
Tie a user's events to their company, workspace or team, and describe those groups.
Groups are what your users belong to, such as the company or workspace they use your app as part of. Once the SDK knows a user's group, every event carries it, so Studio can count active companies, split charts by plan and list who in a company uses your app.
Put the user in a group
Call group with the group type, the group's key and, optionally, its properties, for example after
sign-in or when the user switches workspace:
voidhash.group("company", "acme", mapOf("name" to "Acme", "plan" to "pro", "seats" to 40))
voidhash.group("team", "acme-design")- A group type is a key such as
company: a lower-case letter, then up to 63 lower-case letters, digits or underscores. A project keeps up to 5 types. - A group key is your own ID for the group, 1 to 256 characters.
- The user belongs to one group of each type: calling
groupagain with another key moves them. - Properties are strings, numbers or booleans; other values are left out with a warning.
nameis what Studio shows as the group's name.
group returns at once and never throws: an invalid type or key is ignored with a warning, which
debug = true logs. Java callers use group(type, key) and group(type, key, properties).
Set every group at once
When your app knows all of a user's groups, pass them to setGroups in one call. It replaces the
whole set, so you don't track which group the user joined or left:
import com.voidhash.sdk.VoidhashGroup
voidhash.setGroups(
mapOf(
"company" to VoidhashGroup("acme", mapOf("name" to "Acme", "plan" to "pro", "seats" to 40)),
"team" to VoidhashGroup("acme-design"),
),
)- A
VoidhashGrouphas the group'sidand, optionally, itsproperties. - A type you leave out, or map to
null, is dropped. An empty map does whatresetGroups()does. - Types and IDs follow the rules of
group. An entry that breaks them is left out with a warning.
Call it whenever the groups might have changed, such as on every launch or after your user data
refreshes. Calling it again with the same groups sends nothing. Like group, it returns at once.
What the SDK sends
Every event captured after group returns carries the user's groups in its $groups property, such
as {"company": "acme", "team": "acme-design"}. The groups are stamped when the event is queued, so
an event that waits for the network still names the groups it happened in. A group an event names
itself wins for its type:
voidhash.capture("report_shared", mapOf("\$groups" to mapOf("team" to "acme-sales")))group also sends a $groupidentify event, which sets the group's properties, when you pass
properties or when the user's group of that type changed. setGroups sends one only for a group
whose ID changed or whose properties differ from the ones it last sent; leaving a group sends
nothing. A later change of a property wins.
A group and its properties are what your app says about the user, not what the user did, so they
are sent whatever the analytics consent. While consent is not granted, the $groupidentify goes
out at once on its own, with only the group's type, ID and properties: no session or device
details. It is not retried if it fails; the next setGroups call sends it again. The $groups
property still travels only on events, which need consent.
Properties you know on your server are better set from there, with
groupIdentify.
Read and clear groups
val groups = voidhash.groups // {company=acme, team=acme-design}
voidhash.resetGroups() // later events carry no groupsGroups are stored on the device with the user's distinct ID, so they last across launches and
identify keeps them. signOut() and reset() clear them with the identity whenever they act;
the $sign_out event still carries the groups of the user who signed out. Before the device is
first unlocked after a reboot, groups is empty, and group, setGroups and resetGroups are
held and applied once the SDK's storage can be read, in the order you called them.
Next steps
Something wrong or missing on this page? Tell us by email or on Discord.