Groups API

 Hint: It is normally preferable to import groups as a CSV file (possibly via the CSV Upload API), rather than directly interacting with the Groups API.

The Watershed Groups API is used by activity providers to create groups of people. These groups can be assigned permissions and you can aggregate data by group in reports. Many Watershed clients use groups to represent their organization’s hierarchy. This guide outlines the functional components of the API and provides an example.

As groups are comprised of people, the Groups API builds on the concepts of the People API. Make sure you are familiar with People before working with Groups. You will need to have people loaded into your organization before assigning them to groups.

Who can use this feature?
 User Types
Only Global Adminscan create API credentials required to interact with the API.
 Pricing
Available on CLO, and Enterprise plans.
 Expertise
Only experts can use the API.

 Please note: This guide is designed to compliment a conversation with us. If you're looking to implement the Groups API and need assistance, please let us know and we will be glad to help.

Concepts

Groups

Groups are collections of people and other groups. They provide a way to model organization hierarchies, group users by roles or locations, define permissions, and filter report data. Groups have some associated metadata like name and type.

Group Types

Group Types allow you to define relationships between groups. Groups can be used for anything from representing hierarchies to defining learners' job roles to showing location of learners, so it's useful to define a Group Type for reporting and organization purposes. For instance, if you have groups for "Managers," "Directors," and "VPs," you make all of their Group Type be "Job Role." Each group has a group type and you need to create group types before creating groups of that type.

API

Batch Updates

Whenever changes to groups and people are made that affect reporting, Watershed updates it's record of interaction data to reflect these changes. If you are making a lot of changes in rapid succession, it is better to queue up these changes and send them in a batch.

To cause a groups or people change to be queued, add the parameter batch with a value of true to each request you want to queue. Then, to process all pending people and group changes in the queue, sent a batch update request as outlined below:

Request URL: /api/organizations/[org-id]/groups/finish-batch-updates
Method: POST
Expected response code: 204 No Content

 Please note: For smaller continuous updates, batching should not be used. Only use batching when making bulk updates.

Get a list of Group Types

Request URL: /api/organizations/[org-id]/group-types
Method: GET
Expected response code: 200 OK

Response:

Returns a Collection object containing an array of Group Type objects.

Get a Group Type by Id

Request URL: /api/organizations/[org-id]/group-types/[group-type-id]
Method: GET
Expected response code: 200 OK

Response:

Returns a Group Type object matching the requested id.

Create a Group Type

Request URL: /api/organizations/[org-id]/group-types
Method: POST
Expected response code: 200 OK

Request content:

A Group Type JSON object. Only the name property is required.

Response:

Returns the complete Group Type object created with all properties populated.

Update a Group Type

Request URL: /api/organizations/[org-id]/group-types/[group-type-id]
Method: PUT
Expected response code: 204 No Content

Request content:

A Group Type JSON object. Only the name property is required.

Response:

No content.

Delete a Group Type

Request URL: /api/organizations/[org-id]/group-types/[group-type-id]
Method: DELETE
Expected response code: 204 No Content

Response:

Returns the complete Group Type object deleted.

Get a List of Groups

Request URL: /api/organizations/[org-id]/groups
Method: GET
Expected response code: 200 OK

Request Parameters

Parameter

Type

Description

rootOnly

Boolean

If true, only includes top level groups, i.e. those that have no parent.

Response

Returns a Collection object containing an array of matching Group objects.

Get a Group by Id

Request URL: /api/organizations/[org-id]/groups/[group-id]
Method: GET
Expected response code: 200 OK

 Hint: you can also get a group by their custom id using the request url /api/organizations/[org-id]/groups/?customId=[custom-id]

Request Parameters

Parameter

Type

Description

childDepth

Integer

Defaults to zero. If a value other than zero is provided, the response will include data for child groups down to the depth specified, for example for a childDepth of 2, data about children of the group and those children’s children will be included. Use a childDepth of -1 to include all data.

Please note: a complete list of child group ids will always be included in the response; use this parameter to get the data about those child groups without having to make additional API calls.

parentDepth

Integer

Defaults to zero. If a value other than zero is provided, the response will include data for parent groups up to the depth specified, for example for a parentDepth of 2, data about parent of the group and that parent’s parent will be included. Use a parentDepth of -1 to include all data.

Please note: a complete list of parent group ids will always be included in the response; use this parameter to get the data about those parent groups without having to make additional API calls.

Response

Returns a Group object matching the requested id.

Get Multiple Groups by ID

Request URL: /api/organizations/[org-id]/groups/multi
Method: GET
Expected Response: 200 OK

Request Parameters

Parameter

Type

Description

ids

Array

A list of the group ids you want to retrieve.

customIds

Array

A list of the group customIds that you want to retrieve. This can be used as an alternative to providing ids.

Response

Returns a Collection object containing an array of Group objects that match the ids passed as parameters.

Get Members by Group Id

Request URL: /api/organizations/[org-id]/groups/[group-id]/members
Method: GET
Expected response code: 200 OK

Response

Returns a Collection object containing an array of Person objects that belong to the group or child groups.

Create a Group

Request URL: /api/organizations/[org-id]/groups
Method: POST
Expected response code: 200 OK

Request Content

A JSON formatted Group object. This group object does not need to include ids or created timestamps.

Response

Returns the complete Group object created with all properties populated.

Update a Group

Request URL: /api/organizations/[org-id]/groups/[group-id]
Method: PUT
Expected response code: 204 No Content

 Hint: you can also update a group by their custom id using the request url /api/organizations/[org-id]/groups/?customId=[custom-id]

Request content

A Group JSON object. This group object does not need to include ids or created timestamps.

Request Parameters

Parameter

Type

Description

action=metadata_update

-

This parameter should be added to a query string when you just want to update the groups metadata (name, description, image) without changing it's membership or hierarchy information.

Response

No content.

Update Multiple Groups

Request URL: /api/organizations/[org-id]/groups/multi
Method: PUT
Expected Response: 204 No Content

Request Content

A list of Group JSON objects. These group objects do not need to include ids or created timestamps.

Request Parameters

Parameter

Type

Description

batch

Boolean

Defaults to false. Controls whether you want to update the groups as a batch.

Response

No content.

Delete a Group

Request URL: /api/organizations/[org-id]/groups/[group]
Method: DELETE
Expected response code: 204 No Content

 Hint: you can also delete a group by their custom id using the request url /api/organizations/[org-id]/groups/?customId=[custom-id]

Response

Returns the complete Group object deleted.

Entity Model

This section outlines the objects used in interacting with the Groups API.

Group Type

An object representing a type of group.

Property

Type

Description

id

Integer

Watershed’s id for the group type.

created

ISO 8601 timestamp

When the group type was created.

name

String

The display name of the Group Type e.g. “Job Role”.

displayOrder

Integer

The order the group type will be displayed in relative to other group types in a list.

Group

An object representing a group.

Property

Type

Description

id

Integer

Watershed’s id for the group.

customId

String

A custom identifier for the Group, e.g. an identifier used in another system. Must be unique.

created

ISO 8601 timestamp

When the group type was created.

name

String

The display name of the Group e.g. “Accountant”.

description

String

A longer description for the group.

type

GroupType

The type of Group

imageUrl

URI

A url for an image associated with this group.

childGroupIds

Array

A list of group ids of the groups that are direct descendants of this group.

childGroupCustomIds

Array

A list of customIds of the groups that are direct children of this group.

childGroups

Array

A list of complete group objects for the groups that are direct children of this group. This property is read-only and only populated when requested via the childDepth query parameter.

parentGroupIds

Array

A list of group ids of the groups that are direct parents of this group.

parentGroupCustomIds

Array

A list of customIds of the groups that are direct parents of this group.

parentGroups

Array

A list of complete group objects for the groups that are direct parents of this group. This property is read-only and only populated when requested via the parentDepth query parameter.

peopleIds

Array

A list of person ids of people that are direct members of this group. People belonging to groups that are children of this group are not included.

See Get Members by Group Id above for details of how to get a list of all people included in the group, both directly and indirectly.

peopleCustomIds

Array

A list of person customIds of people that are direct members of this group.

people

Array

A list of complete person objects for people that are direct members of this group. This property is read-only and only populated when requested via the childDepth query parameter.

Example

Below we'll show some API interactions that correspond to an example scenario in which a simple organization hierarchy is impliented, along with another group outside of the hierarchy. Lets say we have a collection of ten people, within one organization, working under two divisions, development and sales.

Here's an example of one person, our friend Bob:

POST /people
{
  "name": "Bob",
  "personas": [{
    "name": "Bob",
    "mbox": "bob@example.com"
  },{
    "name": "Bobby",
    "account": {
      "homePage": "http://example.com",
      "name": "bobby"
    }
  }]
}

Please note: A person entity will be created automatically for each unique xAPI agent which is referenced in statements sent to the LRS. In such case, a single persona is associated with the person, which corresponds to the xAPI agent object present in the statement.

Assume we've created our ten people in the API and can now reference thi via ID. Let's create our three hierarchy groups, Company , Sales , and Development , with sales and development as child groups of company , and our ten people within the sales and development groups. We'll also create a group type called Team to categorize these groups as organizational hierarchy groups.

Before we create our groups, let's create the group type they will all use, which we'll call "Team"

POST /group-types
{
  "name": "Team"
}

And now we can use that type as we create our groups (assuming our new group type has id 301):

POST /groups
{
  "name": "Sales",
  "type": { "id": 301 },
  "peopleIds": [ 1, 2, 3, 4 ]
}
POST /groups
{
  "name": "Development",
  "type": { "id": 301 },
  "peopleIds": [ 5, 6, 7, 8, 9, 10 ]
}

Assuming the prior groups were given IDs 1 and 2 on creation, we can reference thi as child groups when creating the top level group:

POST /groups
{
  "name": "Company",
  "type": { "id": 301 },
  "childGroupIds": [ 101, 102 ]
}

We've created a small hierarchy, and we can now take a look at the whole thing in total by looking at the top level group and using the childDepth parameter, passing the value of all :

GET /groups/103?childDepth=all
{
  "id": 103,
  "name": "Company",
  "type": {
    "id": 301,
    "name": "Team"
  },
  "childGroupIds": [ 101, 102 ],
  "childGroups": [{
    "id": 101,
    "name": "Sales",
    "type": {
      "id": 301,
      "name": "Team"
    },
    "parentGroupIds": [ 103 ],
    "peopleIds": [ 1, 2, 3, 4 ],
    "people": [{
      "id": 1,
      "name": "Bob",
      "personas": [{
        "id": 1001,
        "name": "Bob",
        "mbox": "bob@example.com"
      },{
        "id": 1002,
        "name": "Bobby",
        "account": {
          "homePage": "http://example.com",
          "name": "bobby"
        }
      }]
    },{
      ... (more people entities) ...
    }]
  },{
    "id": 102,
    "name": "Development",
    "type": {
      "id": 301,
      "name": "Team"
    },
    "parentGroupIds": [ 103 ],
    "peopleIds": [ 5, 6, 7, 8, 9, 10 ],
    "people": [{
      ... (more people entities here) ...
    }]
  }]
}

We'll also create another group, which we'll call book-club . This group is another top level group which exists outside of the organization hierarchy, and includes people which are part of the company book club:

POST /group-types
{
  "name": "Club",
}
POST /groups
{
  "name": "Book Club",
  "type": { "id": 302 },
  "peopleIds": [ 1, 4, 7, 8 ]
}

As a final example, let's look at a single person and see their group ancestory, by using the parentDepth parameter:

GET /people/1
{
  "id" 1,
  "name": "Bob",
  "personas": [{
    "id": 1001,
    "name": "Bob",
    "mbox": "bob@example.com"
  },{
    "id": 1002,
    "name": "Bobby",
    "account": {
      "homePage": "http://example.com",
      "name": "bobby"
    }
  }],
  "parentGroups": [{
    "id": 101,
    "name": "Sales",
    "type": {
      "id": 301,
      "name": "Team"
    },
    "parentGroupIds": [ 1 ],
    "parentGroups": [{
      "id": 1,
      "name": "Company",
      "type": "team",
      "childGroupIds": [ 1, 2 ]
    }]
  },{
    "id": 104,
    "name": "Book Club",
    "type": {
      "id": 302,
      "name": "Club"
    },
    "peopleIds": [ 1, 4, 7, 8 ]
  }]
}
Was this article helpful?
0 out of 0 found this helpful

If you can't find what you need or you want to ask a real person a question, please contact customer support.