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 for your activity provider and need assistance, please let us know and we will be glad to help.

This guide consists of 4 sections:

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).


Get a list of people

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

Request Parameters

None.

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

Response

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

Please note: 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

Details

parentDepth

Integer

(optional)

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.

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

Details

persona

persona object

(required)

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.

parentDepth

Integer

(optional)

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.

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

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

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 (the person id is included in the url).

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

Details

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

Details

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
Have more questions? Submit a request

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