People API

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

The Watershed People API is used by activity providers to associate multiple personas as a single person. This guide outlines the functional components of the API and provides an example.

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

Concepts

Actors and Personas

Actors are the entities that are part of xAPI statements. They ultimately tie the xAPI data that powers Watershed to the people who are in your organization. As per the xAPI API specification, actors may be identified in several ways, from email addresses to accounts on any arbitrary system. These identifiers are referred to in this document as personas.

For example, the email addresses bob@example.com and bobby@example.net are both personas, which may refer ultimately to the same person, Bob. Another example might be bob12 at twitter.com, which would be considered an "account on a system".

People

People are collections of personas. They represent individuals in reporting data, and members that can be organized into groups. A person can be identified using any of the personas which have been related to them.

Important note about people behavior:

  • Personas can be associated with people by creating or updating a person with that persona.
  • When a persona is associated with a person, if that persona was already associated with another person, it will be removed from the original.

Relationship between personas and people

Each persona can only belong to one person, and each person must have one or more personas. If you attach a persona that is already in use to a new or existing person, that persona will no longer be associated to the person it was previously attached to. If this results in a person having no personas, that person will be deleted.

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. Each persona created in this way will always belong to a person and cannot be deleted. If a persona that’s included in statement data is removed from a person, a new person will automatically be created for that persona.

API

This section outlines the allowed resources and methods of the People API. In order to interact with the people API, you will need authentication credentials and an organization id (org id).

 Hint: The Using Watershed's Administration APIs article provides important information on using the People API such as details on collections, paging, searching and sorting results.

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 let Watershed accumulate these changes and process them all at once after all of the changes have been submitted.

To delay the processing of groups or people changes until after all changes have been applied, add the parameter batch with a value of true to each request in the entire set of changes. Then, to process all pending people and group changes, send a batch update request as outlined below. The finish-batch-updates request should only be sent once, after all groups and people changes have been requested.

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

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

Get a list of people

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

Request Parameters

Parameter

Type

Description

Required

_limit

Integer

Determines how many results will be included in the response object.  The default is 100 and the max is 1000.  If there are more results, pagination is required.

Optional 

_offset

Integer

The number of records to offset.  For example, if you've fetched the first 100 records then the next 100 can be obtained with _offset=100.

Optional

is_not_null

String 

This parameter allows filtering on the results to only retrieve records where a field is not blank.  For example, if you only wanted persons where the custom ID was populated you would use is_not_null=customId.

Optional

is_null

String

Works the opposite of is_not_null.  To obtain a list of everyone missing a customId you would use is_null=customId. 

Optional

forceDBSearch

N/A

There is a 10,000 person limit on the search executed from the People API call. If you need to list passed the 10,000th person, append &forceDBSearch (without any values) to get around this limit.

Optional

 Please note: The parentDepth parameter cannot be used with this request.

Response

 Please note: There is a 10,000 person limit on the search executed from this API call. If you need to list passed the 10,000th person, append&forceDBSearchto your query to force a different kind of search that can get around this limit.

A successful request will return a JSON object with count and results properties. results contains an array of person objects (see below); count contains the length of that array.

Get a person by their id

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

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

Request Parameters

Parameter

Type

Description

Required

parentDepth

Integer

How many levels up the hierarchy tree of parent groups should be included in the response.

Defaults to 0. Set to -1 to return all data.

Please note: parent group ids will always be included in the request; use this parameter to get full group data without making additional calls to the Groups API.

 Optional

Response

A successful request will return a single person object (see below) matching the person id provided in the URL.

Get a person by a matching persona

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

Request Parameters

Parameter

Type

Description

Required

persona

Persona Object

Persona to match against. This does not need to be a complete persona object, so long as it contains an inverse functional identifier. In fact, the object must not include a created property.

Required 

parentDepth

Integer 

How many levels up the hierarchy tree of parent groups should be included in the response.

Defaults to 0. Set to -1 to return all data.

Please note: parent group ids will always be included in the request; use this parameter to get full group data without making additional calls to the Groups API.

 

Optional

Response

A successful request will return a single person object (see below) matching the persona provided in the persona parameter.

Add a person

Request URL: /api/organizations/[org-id]/people/
Method: POST
Expected response code: 201 Created

Request Content

The request should contain a JSON formatted person object (see below). This person object does not need to include ids or created timestamps.

Response

A successful request will return a complete person object including id and created timestamps.

Update a person

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

Request Parameters

Parameter

Type

Description

Required

customId

Persona Object

Use this parameter to update a person using their custom ID, rather than there Watershed ID

Optional 

Response

No content.

Delete a person

Request URL: /api/organizations/[org-id]/people/[person-id]
Method: Delete
Expected response code: 204 No Content

Request Parameters

Parameter

Type

Description

Required

customId

Persona Object

Use this parameter to update a person using their custom ID, rather than there Watershed ID

Optional 

deleteStatementData

Boolean

If true all statement data about the person will also be deleted. This supports the requirements under GDPR for removing all (learner) PII from Watershed.

Optional

Response

No content.

Entity model

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

Persona

An object representing an individual persona of a person. This has the same properties as an Agent or Group object defined in the xAPI specification. When returned by Watershed in response to a GET result, the persona object has two additional properties:

Property

Type

Description

id

Integer

Watershed’s id for the persona.

created

ISO 8601 timestamp

When the persona was created.

Person

Not to be confused with the Person object defined in the xAPI specification, the Watershed Person object has the following properties.

Property

Type

Description

id

Integer

Watershed’s id for the person. Used in a number of API calls relating to the person.

customId

String

A custom identifier for the person. Must be unique.

This is used by some Watershed clients to store an id from another system that may or may not be represented as a persona.

created

ISO 8601 timestamp

When the person was created.

name

String

Name of the person to be used by Watershed. For example, a learner might have personas named “Mike” and “Michael”; the person name is what Watershed will use.

imageUrl

URI

Link to a profile image for a person. If not provided and one of the personas contains an email address linked to a Gravatar account, the Gravatar image will be used.

personas

Array

List of persona objects associated with the person.

parentGroupIds

Array

List of integer ids of groups the person belongs to.

parentGroupCustomIds

Array 

List of custom ids of groups the person belongs to. Can be used instead of parentGroupIds when updating a person's memberships.

parentGroups

Array

List of group objects for groups the person belongs to. This may not be a complete list; see the parentDepth request parameter above.

Example

Below are some API interactions corresponding to an example scenario in which some personas are associated as people. In our example scenario, our organization has two learners, Bob and Sue. Both Bob and Sue have learning activities to complete where they will be identified by their SCORM Cloud account and their email address. Bob has already completed the learning and therefore has data already in Watershed; Sue has not.

First, let’s see what people are already listed in the organization:

GET /api/organizations/1234/people

This returns:

{
  "count": 2,
  "results": [
    {
      "id": 1,
      "name": "Bob Smith",
      "personas": [
        {
          "name": "Bob Smith",
          "id": 1,
          "mbox": "mailto:bob.smith@example.com",
          "created": "2015-02-26T18:29:22.000+0000"
        }
      ],
      "parentGroupIds": [],
      "parentGroupCustomIds": [],
      "created": "2015-02-26T18:29:18.000+0000"
    },
    {
      "id": 2,
      "name": "Bob Smith",
      "personas": [
        {
          "name": "Bob Smith",
          "id": 2,
          "account": {
            "homePage": "http://cloud.scorm.com/",
            "name": "W74TDQ7PZG|251479"
          },
          "created": "2015-04-29T13:00:42.000+0000"
        }
      ],
      "parentGroupIds": [],
      "parentGroupCustomIds": [],
      "created": "2015-04-29T13:00:42.000+0000"
    }
  ]
}

Bob is currently represented as two people and Sue is not present at all. Let’s edit person Bob Smith 1 to include both of Bob’s personas; this will cause person Bob Smith 2 to be removed.

PUT /api/organizations/1234/people/1

{
  "id": 1,
  "name": "Bob Smith",
  "personas": [
    {
      "name": "Bob Smith",
      "id": 1,
      "mbox": "mailto:bob.smith@example.com"
    },
    {
      "name": "Bob Smith",
      "id": 2,
      "account": {
        "homePage": "http://cloud.scorm.com/",
        "name": "W74TDQ7PZG|251479"
      }
    }
  ],
  "parentGroupIds": [],
  "parentGroupCustomIds": []
}

Our organization now has one person and two personas, but what about Sue? There’s no exciting person for Sue, so let’s create one.

POST /api/organizations/1234/people/
{
  "name": "Sue Jones",
  "personas": [
    {
      "name": "Sue Jones",
      "mbox": "mailto:sue.jones@example.com"
    },
    {
      "name": "Sue Jones",
      "account": {
        "homePage": "http://cloud.scorm.com/",
        "name": "W74TDQ7PZG|145897"
      }
    }
  ],
  "parentGroupIds": [],
  "parentGroupCustomIds": []
}

Great! Now everything’s loaded. Some time later we need to retrieve the data from Watershed. We know that Bob’s person id was 1 and that Sue’s email is sue.jones@example.com. Let’s fetch Bob’s record first. We’ll also retrieve any group data associated with Bob.

GET /api/organizations/1234/people/1?parentDepth=-1

That returns Bob’s record. Now Sue. This time we only want to know about groups Sue is directly in, not any groups containing those groups.

/api/organizations/1234/people/with-persona?parentDepth=1&persona={"mbox":"mailto:sue.jones@example.com"}

Perfect! We’ve now got Sue’s record too!

Now that Bob and Sue are represented as single persons in Watershed, find out how to use the Groups API to create and manage groups and how to use the Permissions API to control what data people can see.

Was this article helpful?
1 out of 1 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.