SkillhabitDocs

Sync Manual Groups

Keep Skillhabit manual groups aligned with HR or CRM membership using the External API.

What This Is For

Your system owns departments, cohorts, or partner lists. You want matching manual groups in Skillhabit so visibility, managers, and reporting stay in sync—without asking admins to edit membership by hand.

This is API-driven manual group sync, not Entra Graph sync or SCIM. For directory push provisioning, see User Provisioning and Sync Users With SCIM.

Who This Is For

Integration developers with an API key. Admins decide which groups Skillhabit should mirror.

Outcome

  • Stable Skillhabit groupId values stored in your system.
  • Members added and removed as joiners and leavers appear in HR.
  • Optional managers on those groups.
  1. Map once — create the Skillhabit group (or look it up), store groupId next to your department id.
  2. Ensure users exist — create or look up each person (POST /users is idempotent on email).
  3. Reconcile membership — add missing members; remove people who left the department.
  4. Archive leavers (optional) — when someone leaves the company entirely, archive the Skillhabit user.

Do not recreate the group on every sync. Reuse the stored groupId.

Steps

{BASE} = https://customer-api.baloolearning.com/v1 (or your host).

1. Create the Manual Group (First Time)

POST {BASE}/groups
Authorization: Bearer {your-api-credential}
Content-Type: application/json
{
  "name": "Sales Nordics",
  "members": [
    "7f9c2a1e-4b8d-4f6a-9c2e-1d3b5a7e9c01",
    "c0a8012e-8f3d-4b6a-a2d9-3e5f7a9b1c02"
  ],
  "managers": [
    "a7a1c0de-2b6f-4f2d-8d8e-9f0a2b3c4d5e"
  ]
}

members and managers are optional. Example response (201):

{
  "groupId": "7d6b7a10-2b2a-4a30-8a2e-39ad8e4f2b11"
}

Save groupId. Rename later with POST /groups/{groupId}/rename if the department name changes.

List existing groups with GET /groups when you need to discover ids already created in the UI.

2. Ensure Each Person Has a User Id

For every email in the HR department list:

POST {BASE}/users
{
  "email": "sam@example.com",
  "firstName": "Sam",
  "lastName": "Seller",
  "language": "EN",
  "sendWelcomeEmail": false
}

Keep the returned userId. Creating again with the same email returns the existing id (newUser: false).

3. Add Members on the Sync Run

POST {BASE}/groups/7d6b7a10-2b2a-4a30-8a2e-39ad8e4f2b11/members
Authorization: Bearer {your-api-credential}
Content-Type: application/json
{
  "userIds": [
    "7f9c2a1e-4b8d-4f6a-9c2e-1d3b5a7e9c01",
    "c0a8012e-8f3d-4b6a-a2d9-3e5f7a9b1c02"
  ]
}

Managers use the same body shape on POST /groups/{groupId}/managers.

4. Remove Members Who Left the Department

DELETE {BASE}/groups/7d6b7a10-2b2a-4a30-8a2e-39ad8e4f2b11/members/7f9c2a1e-4b8d-4f6a-9c2e-1d3b5a7e9c01
Authorization: Bearer {your-api-credential}

List current members first with GET /groups/{groupId}/members if you reconcile by diff.

5. Archive Someone Who Left the Company

POST {BASE}/users/7f9c2a1e-4b8d-4f6a-9c2e-1d3b5a7e9c01/archive
Authorization: Bearer {your-api-credential}

Archiving is separate from removing a group membership—do both when the person should leave Skillhabit entirely.

Pseudocode for a Nightly Job

for each department D in HR:
  groupId = lookupOrCreateSkillhabitGroup(D)
  desired = userIds for people currently in D
  current = GET /groups/{groupId}/members
  POST /groups/{groupId}/members with (desired - current)
  for each userId in (current - desired):
    DELETE /groups/{groupId}/members/{userId}

Create users before you add them as members.

Assign Learning to the Group

Once the group is stable, assign courses to the group rather than to each user: Assign Content to a Group.