VoidhashDocs
DevelopersHelp centerGuidesAPI reference
voidhash.comOpen Studio
Get started
Introduction
Quickstart
How Voidhash works
Glossary
Versions and releases
Concepts
Teams, projects and environments
API keys
Products and perks
Offers
Subscription lifecycle
People and identity
Groups
Events
Features
Paywalls in your app
Feature flags and A/B tests
Paywall components
Push notifications
Ad attribution in your app
Client SDKs
React Native
Swift
Kotlin
Web
Your backend
Node.js
PHP
Go
Rust
Other languages
Payment sources
Forward store notifications
Developer tools
CLI
MCP server
Query analytics with VoidQL
Swift SDK
Swift quickstart
Display a paywall
Make and restore purchases
Check access
Identify users
Evaluate feature flags
Capture analytics
Groups
Track screens
Development mode
Swift SDK reference
Errors
Diagnostic codes
Troubleshooting
Theme

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(type:key:properties:) with the group type, the group's key and, optionally, its properties, for example after sign-in or when the user switches workspace:

await voidhash.group(
    type: "company",
    key: "acme",
    properties: ["name": .string("Acme"), "plan": .string("pro"), "seats": .number(40)]
)
await voidhash.group(type: "team", key: "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 group again with another key moves them.
  • Properties are strings, numbers or booleans; other values are left out with a warning. name is what Studio shows as the group's name.

group never throws: an invalid type or key is ignored and reported through onWarning.

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:

await voidhash.setGroups([
    "company": VoidhashGroup(
        id: "acme",
        properties: ["name": .string("Acme"), "plan": .string("pro"), "seats": .number(40)]
    ),
    "team": "acme-design",
])
  • A VoidhashGroup has the group's id and, optionally, its properties. A string literal is a group with that ID and no properties.
  • A type you leave out is dropped. An empty dictionary does what resetGroups() does.
  • Types and IDs follow the rules of group. An entry that breaks them is ignored and reported through onWarning.

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 and stores nothing.

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:

await voidhash.capture("report_shared", properties: [
    "$groups": .object(["team": .string("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

let groups = await voidhash.groups // ["company": "acme", "team": "acme-design"]
await voidhash.resetGroups() // later events carry no groups

Groups 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 restart, groups is empty, and group, setGroups and resetGroups wait for the stored identity, in the order you called them.

Next steps

  • Groups
  • Capture analytics
  • Reference

Something wrong or missing on this page? Tell us by email or on Discord.

PreviousCapture analyticsNextTrack screens
© 2026 Voidhash s.r.o.
voidhash.comPricingTermsPrivacyDiscord

On this page

Put the user in a groupSet every group at onceWhat the SDK sendsRead and clear groupsNext steps