Group Hierarchy
Model multi-level account structures in Accoil using nested group calls with parent relationships. Supports Account, Workspace, and Project levels.
Many B2B products have account structures with more than one level. A company might contain multiple workspaces. A workspace might contain multiple projects. Accoil supports these multi-level structures through group hierarchy -- nested group calls that establish parent-child relationships between accounts.
When you need hierarchy
Use group hierarchy when your product has a structure like:
- Company > Workspace > Project (project management tools)
- Organization > Team (collaboration platforms)
- Account > Site > Environment (infrastructure or developer tools)
- Company > Department > Sub-team (enterprise products)
If your product has a flat account structure (one company = one account), you do not need hierarchy. A single group call is sufficient.
How it works
Each level in the hierarchy is a separate group entity with its own groupId. Parent-child relationships are established by including a parent reference in the traits of the child group.
Company: Acme Corp (groupId: "acme_123")
├── Workspace: Engineering (groupId: "ws_eng_456", parent: "acme_123")
├── Workspace: Marketing (groupId: "ws_mkt_789", parent: "acme_123")
│ └── Project: Q1 Campaign (groupId: "proj_q1_012", parent: "ws_mkt_789")
└── Workspace: Sales (groupId: "ws_sales_345", parent: "acme_123")Setting up the hierarchy
Step 1: Create the top-level account
The top-level group has no parent. This is typically the company or organization.
{
"groupId": "acme_123",
"traits": {
"name": "Acme Corp",
"created_at": "2023-01-15T12:00:00Z",
"status": "paid",
"plan": "enterprise",
"mrr": 250000
},
"timestamp": "2025-01-28T12:00:00Z"
}Step 2: Create child groups with a parent trait
Each child group includes a parent_group_id trait that references its parent.
{
"groupId": "ws_eng_456",
"userId": "user_12345",
"traits": {
"name": "Engineering",
"parent_group_id": "acme_123",
"created_at": "2023-02-01T12:00:00Z"
},
"timestamp": "2025-01-28T12:00:00Z"
}{
"groupId": "ws_mkt_789",
"userId": "user_67890",
"traits": {
"name": "Marketing",
"parent_group_id": "acme_123",
"created_at": "2023-03-10T12:00:00Z"
},
"timestamp": "2025-01-28T12:00:00Z"
}Step 3: Add deeper levels
For a third level (e.g., projects within a workspace), the child references its immediate parent.
{
"groupId": "proj_q1_012",
"userId": "user_67890",
"traits": {
"name": "Q1 Campaign",
"parent_group_id": "ws_mkt_789",
"created_at": "2025-01-05T12:00:00Z"
},
"timestamp": "2025-01-28T12:00:00Z"
}Full example: server-side setup
Here is a practical example of a function that sends group calls for a multi-level structure when a new workspace is created:
const API_BASE = "https://in.accoil.com";
const API_KEY = process.env.ACCOIL_API_KEY;
async function sendGroup(payload) {
await fetch(`${API_BASE}/v2/group`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${API_KEY}`,
},
body: JSON.stringify(payload),
});
}
// When a new workspace is created under an existing company
async function onWorkspaceCreated(company, workspace, createdByUser) {
// Ensure the parent company group exists and is up to date
await sendGroup({
groupId: company.id,
traits: {
name: company.name,
status: company.status,
plan: company.plan,
mrr: company.mrrCents,
created_at: company.createdAt,
},
timestamp: new Date().toISOString(),
});
// Create the workspace as a child group
await sendGroup({
groupId: workspace.id,
userId: createdByUser.id,
traits: {
name: workspace.name,
parent_group_id: company.id,
created_at: workspace.createdAt,
},
timestamp: new Date().toISOString(),
});
}User association in a hierarchy
When a user works within a child group (e.g., a workspace), associate them with that specific group by including userId in the group call. Accoil will attribute activity to both the child group and its parent through the hierarchy.
{
"groupId": "ws_eng_456",
"userId": "user_12345",
"traits": {
"name": "Engineering",
"parent_group_id": "acme_123"
},
"timestamp": "2025-01-28T12:00:00Z"
}Best practices
- Use stable IDs at every level. Each group in the hierarchy needs its own unique, immutable identifier.
- Always set
parent_group_id. Without it, child groups appear as independent accounts with no relationship to their parent. - Create parents before children. While not strictly required (Accoil processes asynchronously), sending the parent group call first ensures the hierarchy is established cleanly.
- Keep hierarchy shallow. Two or three levels is typical. Deep nesting adds complexity without proportional analytical value.
- Apply revenue traits at the right level. Typically,
mrrandplanbelong on the top-level account, not on individual workspaces or projects.
Related
- Group Call -- the fundamentals of account identification
- Snapshot Metrics -- sending usage counts at each level of the hierarchy
- How Accoil Works -- the three-call model overview
Track Call
The track call records user actions in Accoil. Only the event name is accepted -- no properties. Use Object_Verb naming in Title_Case.
Snapshot Metrics
Track what exists in your product (counts, states, totals) using scheduled group calls. Complements event tracking for a complete picture of account health.