Pagination

The Security Module search endpoints use offset-based paging. Unlike the token-paged Employee and OU endpoints, you ask for an explicit window of records by their position in the result set, and the response tells you the total number of records that matched.

This applies to three endpoints:

  • GET v1/roles — search security roles
  • GET v1/categories — search security categories
  • GET v1/roles/{roleId}/dynamicAssignments — a role's OU and user filters

The paging window

Four query parameters control the window and its order. All four are optional and have defaults.

ParameterTypeDefaultDescription
startRecordinteger11-based index of the first record to return.
endRecordinteger201-based index of the last record to return.
sortByinteger1Column to sort by (endpoint-specific meaning).
sortDirectioninteger1Sort direction (endpoint-specific meaning).

startRecord and endRecord are inclusive positions, so startRecord=1&endRecord=20 returns the first 20 records and startRecord=21&endRecord=40 returns the next 20.

Reading a page

Request the first page of roles:

GET /services/api/x/security-module/v1/roles?startRecord=1&endRecord=20
HTTP/1.1
Host: {your portal}.csod.com
Authorization: Bearer {your oauth2 token}

The response wraps the records in a domain-named collection (roles here, categories for the category search) and carries a totalRecords count:

{
  "totalRecords": 143,
  "roles": [
    {
      "roleID": 5001,
      "title": "LMS Administrator",
      "description": "Full learning admin",
      "categoryID": 101,
      "cannotRemove": false,
      "cannotAssign": false,
      "canManage": true,
      "hasChildren": true,
      "parentId": 0,
      "isActive": true,
      "roleRef": "role-lms-admin"
    }
  ]
}

totalRecords is the count of every record that matches your filter, independent of the window. Use it to decide whether more pages remain: after a window ending at endRecord, there is more to fetch while endRecord < totalRecords.

Walking the pages

To read the next page, advance both bounds by the page size:

GET /services/api/x/security-module/v1/roles?startRecord=21&endRecord=40

Repeat until endRecord reaches or exceeds totalRecords.

Keep the window and filters stable

Change only startRecord and endRecord as you page. If you change the filter or sort between requests, the underlying result set shifts and positions no longer line up, so you may skip or repeat records.

Paging dynamic assignments

GET v1/roles/{roleId}/dynamicAssignments returns a role's OU filters and user filters together. The same startRecord/endRecord/sortBy/sortDirection parameters apply, but the two collections are paged independently and each reports its own total:

GET /services/api/x/security-module/v1/roles/5001/dynamicAssignments?startRecord=1&endRecord=20
{
  "roleId": 5001,
  "ouFilters": [
    { "filterId": 11, "ouId": 42, "includeSubs": true, "typeId": 2 }
  ],
  "ouTotalRecords": 1,
  "userFilters": [
    { "filterId": 73, "userId": 9001, "includeSubs": false }
  ],
  "userTotalRecords": 1
}

The single window applies to both collections, so compare ouTotalRecords and userTotalRecords against your window separately: one collection may have more pages to fetch while the other is already complete.