List all courses statistics: Migration guide

We've combined the getCoursesStats, getUserCourseStats and getCourseStats endpoints from API v1 into a single, more efficient endpoint in API v2: List all courses statistics.

This guide outlines the key differences you'll encounter when moving to API v2:

  • From getCoursesStats
  • From getUserCourseStats
  • From getCourseStats

💡

Key changes

  • Pagination: The v2 endpoint is paginated and returns 500 courses statistics per page.

getCoursesStats migration

Documentation links

Here are the links to the API reference for:

Endpoint mapping

Here's the direct correlation between the v1 and v2 endpoint URLs:

  • API v1: /api/v2/courses/stats
  • API v2: /api/v1/courses/stats

Behavior changes

Thanks to API v2 pagination mechanism, there is no more limitation on the number of statistics to be fetched through this endpoint.

Input changes

This section details the specific alterations to the input requirements between API versions.

API v1 input example

curl --location -g 'https://{{host}}/api/v1/courses/stats?company={{company}}&apiKey={{apiKey}}'

API v2 input example

curl --request GET \
     --url https://app.staging.360learning-dev.com/api/v2/courses/stats \
     --header '360-api-version: v2.0' \
     --header 'accept: application/json'

Main input differences

Change typeAPI v1API v2
Modified
Query parameters
createdAtBefore / createdAtAfter (Optional): Timestamp filters, in the formatYYYY-MM-DDTHH:mm:ss.sssZ.completedAt (Optional): Modified name, functionality, syntax, and date format. Now, this single filter combines the functionalities of completedAtBefore and completedAtAfter. It filters courses by completion date range using the LHS bracket notation. The date format is now YYYY-MM-DD.
Removed
Query parameters
firstActivityAtBefore / firstActivityAtAfter (Optional): Removed and not replaced in v2.-
Removed
Query parameters
lastActivityAtBefore / lasstActivityAtAfter (Optional): Removed and not replaced in v2.-

Output changes

This section details the specific alterations to the successful output returned between API versions.

API v1 output example

[
  {
    "course": {
      "_id": "62e29a923c24c589a7f21aa5",
      "name": "Welcome to the team!"
    },
    "stats": [
      {
        "attempts": [
          {
            "_id": "63a430d158dedd7933ef84c1",
            "progress": 0,
            "firstActivity": "2022-12-22T10:26:25.648Z",
            "lastActivity": "2022-12-22T10:45:26.896Z",
            "path": "639af419b8a1da7e76278f4e",
            "pathSession": "63a430ae7901ab0524815225",
            "globalTime": 1133849
          }
        ],
        "user": {
          "_id": "62bdbc00291a605543f24386",
          "mail": "[email protected]"
        }
      }
    ]
  }
]

API v2 output example

[
  {
    "_id": "507f1f77bcf86cd799439011",
    "versionNumber": 0,
    "lang": "bg",
    "firstActivityAt": "2025-06-30T13:23:56.059Z",
    "lastActivityAt": "2025-06-30T13:23:56.059Z",
    "timeSpent": 0,
    "progress": 0,
    "score": 0,
    "completedAt": "2025-06-30T13:23:56.059Z",
    "pathId": "507f1f77bcf86cd799439011",
    "pathSessionId": "507f1f77bcf86cd799439011",
    "courseId": "507f1f77bcf86cd799439011",
    "userId": "507f1f77bcf86cd799439011"
  }
]

Main output differences

API v2 output has been flattened: no more sub-objects in the response body, you only get raw attempts.

API v2 introduces pagination for the List all courses statistics endpoint. Instead of returning all stats in a single response, it now returns a maximum of 500 course statistics per page. To retrieve subsequent pages, you need to follow the URL provided in the Link header of the response.

Change typeAPI v1API v2
Removed
Output property
course.name: Removed and not replaced in v2.-
Removed
Output property
user.mail: Removed and not replaced in v2.-
Added
Output property
-score : (Optional) Score of the attempt (if applicable)
Added
Output property
-lang : (Optional) Language of the course attempted by the learner (if applicable)
Added
Output property
-versionNumber : (Optional) Version of the course attempted by the learner (if applicable)
Modified
Output property
course._id: Course unique identifier.courseId: (Required) Course unique identifier.
Modified
Output property
user._id: User unique identifier.userId: (Required) User unique identifier.
Modified
Output property
path: Path unique identifier.pathId: (Optional) Path unique identifier.
Modified
Output property
pathSession: Path session unique identifier.pathSessionId: (Optional) Path session unique identifier.
Modified
Output property
globalTime: Time spent (in millis) by the learner on this attempt.timeSpent: (Required) Time spent (in millis) by the learner on this attempt.


getUserCoursesStats migration

Documentation links

Here are the links to the API reference for:

Endpoint mapping

Here's the direct correlation between the v1 and v2 endpoint URLs:

  • API v1: /api/v1/courses/:course_id/stats/:user_email
  • API v2: /api/v1/courses/stats

Behavior changes

Thanks to API v2 pagination mechanism, there is no more limitation on the number of statistics to be fetched through this endpoint.

How to identify users in v2

A key update in v2 is the standardized method for identifying users. For improved security and consistency, you must now use the user's unique internal ID when referencing a user.

  • If you already have the internal ID, you can use it directly.
  • If you only have the user's email address, you'll need to fetch their internal ID first.

To get the user ID based on their email address:

  1. Retrieve and cache all users:
    Call List all users to retrieve the full list of users in your organization. To ensure your application is performant, this data should be stored in a local database or cache that is updated periodically.
  2. Find the user and get their ID:
    Find the user object where the mail field matches the email you are searching for.
    Copy the value of their _id. This is the internal ID.

Input changes

This section details the specific alterations to the input requirements between API versions.

API v1 input example

curl --location -g 'https://{{host}}/api/v1/courses/5757ea89c3f509b18c8624d1/stats/[email protected]?company={{company}}&apiKey={{apiKey}}'

API v2 input example

curl --request GET \
     --url 'https://app.staging.360learning-dev.com/api/v2/courses/stats?courseId[eq]=507f1f77bcf86cd799439011&userId[eq]=507f1f77bcf86cd799439011' \
     --header '360-api-version: v2.0' \
     --header 'accept: application/json'

Main input differences

Change typeAPI v1API v2
Modified
Query parameters
createdAtBefore / createdAtAfter (Optional): Timestamp filters, in the formatYYYY-MM-DDTHH:mm:ss.sssZ.completedAt (Optional): Modified name, functionality, syntax, and date format. Now, this single filter combines the functionalities of completedAtBefore and completedAtAfter. It filters courses by creation date range using the LHS bracket notation. The date format is now YYYY-MM-DD.
Removed
Query parameters
firstActivityAtBefore / firstActivityAtAfter (Optional): Removed and not replaced in v2.-
Removed
Query parameters
lastActivityAtBefore / lasstActivityAtAfter (Optional): Removed and not replaced in v2.-
Modified
Path parameters
user_email (Path parameter, Required): Could be the email or the ID of the user. This parameter email was part of the URL path.userId (Optional): user's internal ID. An email is no longer accepted here, and userId has to be passed through a query param.
See Behavior changes (section above) for how to get the ID from an email.
Modified
Path parameters
course_id (Path parameter, Required): Course unique ID. This parameter was part of the URL path.courseId (Optional): course's internal ID, has to be passed through a query param.

Output changes

This section details the specific alterations to the successful output returned between API versions.

API v1 output example

{
  "attempts": [
    {
      "_id": "61af1d7011ee6c4786002f2a",
      "progress": 100,
      "score": 75,
      "completedAt": "2021-12-15T15:46:50.326Z",
      "firstActivity": "2021-12-07T08:38:08.474Z",
      "globalTime": 50892,
      "lastActivity": "2021-12-15T15:46:50.306Z"
    }
  ]
}

API v2 output example

[
  {
    "_id": "507f1f77bcf86cd799439011",
    "versionNumber": 0,
    "lang": "bg",
    "firstActivityAt": "2025-06-30T13:23:56.059Z",
    "lastActivityAt": "2025-06-30T13:23:56.059Z",
    "timeSpent": 0,
    "progress": 0,
    "score": 0,
    "completedAt": "2025-06-30T13:23:56.059Z",
    "pathId": "507f1f77bcf86cd799439011",
    "pathSessionId": "507f1f77bcf86cd799439011",
    "courseId": "507f1f77bcf86cd799439011",
    "userId": "507f1f77bcf86cd799439011"
  }
]

Main output differences

API v2 output has been flattened: no more sub-objects in the response body, you only get raw attempts.

API v2 introduces pagination for the List all courses statistics endpoint. Instead of returning all groups in a single response, it now returns a maximum of 500 course statistics per page. To retrieve subsequent pages, you need to follow the URL provided in the Link header of the response.

Change typeAPI v1API v2
Added
Output property
-score : (Optional) Score of the attempt (if applicable)
Added
Output property
-lang : (Optional) Language of the course attempted by the learner (if applicable)
Added
Output property
-versionNumber : (Optional) Version of the course attempted by the learner (if applicable)
Added
Output property
-courseId: (Required) Course unique identifier.
Added
Output property
-userId: (Required) User unique identifier.
Modified
Output property
path: Path unique identifier.pathId: (Optional) Path unique identifier.
Modified
Output property
pathSession: Path session unique identifier.pathSessionId: (Optional) Path session unique identifier.
Modified
Output property
globalTime: Time spent (in millis) by the learner on this attempt.timeSpent: (Required) Time spent (in millis) by the learner on this attempt.



getCourseStats migration

Documentation links

Here are the links to the API reference for:

Endpoint mapping

Here's the direct correlation between the v1 and v2 endpoint URLs:

  • API v1: /api/v1/courses/:courseId/stats
  • API v2: /api/v1/courses/stats

Behavior changes

Thanks to API v2 pagination mechanism, there is no more limitation on the number of statistics to be fetched through this endpoint.

Input changes

This section details the specific alterations to the input requirements between API versions.

API v1 input example

curl --location -g 'https://{{host}}/api/v1/courses/62e29a923c24c589a7f21aa5/stats?company={{company}}&apiKey={{apiKey}}'

API v2 input example

curl --request GET \
     --url 'https://app.staging.360learning-dev.com/api/v2/courses/stats?courseId[eq]=507f1f77bcf86cd799439011' \
     --header '360-api-version: v2.0' \
     --header 'accept: application/json'

Main input differences

Change typeAPI v1API v2
Modified
Query parameters
createdAtBefore / createdAtAfter (Optional): Timestamp filters, in the formatYYYY-MM-DDTHH:mm:ss.sssZ.completedAt (Optional): Modified name, functionality, syntax, and date format. Now, this single filter combines the functionalities of completedAtBefore and completedAtAfter. It filters courses by creation date range using the LHS bracket notation. The date format is now YYYY-MM-DD.
Removed
Query parameters
firstActivityAtBefore / firstActivityAtAfter (Optional): Removed and not replaced in v2.-
Removed
Query parameters
lastActivityAtBefore / lasstActivityAtAfter (Optional): Removed and not replaced in v2.-
Modified
Path parameters
courseId (Path parameter, Required): Course unique ID. This parameter was part of the URL path.courseId (Optional): course's internal ID, has to be passed through a query param.

Output changes

This section details the specific alterations to the successful output returned between API versions.

API v1 output example

[
  {
    "attempts": [
      {
        "_id": "62f244ffb4ccfd37306abbe7",
        "progress": 9,
        "completedAt": "2022-08-11T09:07:37.371Z",
        "firstActivity": "2022-08-09T11:29:03.498Z",
        "lastActivity": "2022-08-09T11:30:08.658Z",
        "globalTime": 51190
      },
      {
        "_id": "6307bb41627414ebe6fa4a96",
        "progress": 100,
        "score": 75,
        "completedAt": "2022-08-25T18:11:55.650Z",
        "firstActivity": "2022-08-25T18:11:14.238Z",
        "lastActivity": "2022-08-25T18:11:55.628Z",
        "path": "6307bb2f66977c8e2316d6d5",
        "pathSession": "6307bb305ab5e0ebdb1138e8",
        "globalTime": 41390
      }
    ],
    "user": {
      "_id": "62bdbc00291a605543f24386",
      "mail": "[email protected]"
    }
  }
]

API v2 output example

[
  {
    "_id": "507f1f77bcf86cd799439011",
    "versionNumber": 0,
    "lang": "bg",
    "firstActivityAt": "2025-06-30T13:23:56.059Z",
    "lastActivityAt": "2025-06-30T13:23:56.059Z",
    "timeSpent": 0,
    "progress": 0,
    "score": 0,
    "completedAt": "2025-06-30T13:23:56.059Z",
    "pathId": "507f1f77bcf86cd799439011",
    "pathSessionId": "507f1f77bcf86cd799439011",
    "courseId": "507f1f77bcf86cd799439011",
    "userId": "507f1f77bcf86cd799439011"
  }
]

Main output differences

API v2 output has been flattened: no more sub-objects in the response body, you only get raw attempts.

API v2 introduces pagination for the List all courses statistics endpoint. Instead of returning all groups in a single response, it now returns a maximum of 500 course statistics per page. To retrieve subsequent pages, you need to follow the URL provided in the Link header of the response.

Change typeAPI v1API v2
Removed
Output property
user.mail: Removed and not replaced in v2.-
Added
Output property
-score : (Optional) Score of the attempt (if applicable)
Added
Output property
-lang : (Optional) Language of the course attempted by the learner (if applicable)
Added
Output property
-versionNumber : (Optional) Version of the course attempted by the learner (if applicable)
Modified
Output property
user._id: User unique identifier.userId: (Required) User unique identifier.
Modified
Output property
path: Path unique identifier.pathId: (Optional) Path unique identifier.
Modified
Output property
pathSession: Path session unique identifier.pathSessionId: (Optional) Path session unique identifier.
Modified
Output property
globalTime: Time spent (in millis) by the learner on this attempt.timeSpent: (Required) Time spent (in millis) by the learner on this attempt.