Applies To:
-
Pinnacle Series Administrators.
Common Causes/Issues:
- The Pinnacle Series API enables secure, programmatic access to user activity, content usage, learning progress, and assessment results.
Solution Overview:
Pinnacle Series API Reporting Guide
The Pinnacle Series API empowers organizations to:
- Build advanced dashboards
- Automate reporting
- Derive actionable insights to optimize user engagement and learning ROI
This guide explains how to use Pinnacle Series APIs to extract data for reporting on users, content, assignments, KnowledgeSmart results, and usage activity.
Who is this guide for?
This guide supports developers, data analysts, and LMS administrators in accessing and using Pinnacle Series APIs effectively.
Permissions:
- To action API calls, you will need either the reporting administrator or reporting manager permission.
- Reporting Admins have full visibility into all reporting data across the organization.
- Reporting Managers can only see data for the groups they are assigned as Owner or Manager, including any child groups within those assignments.
Base URL: https://reporting.pinnacleapis.com/api/swagger/ui
Authentication Flow
- API Key: Contact Eagle Point Support.
- Tenant Info: GET /authinfo?email={yourEmail}
-
Bearer Token: POST /authorize with:
- Email (required)
- Password (required)
- TenantId (required)
- Language (optional)
- TimeOffset (optional)
- TimezoneName (optional)
- ReturnLongLivedToken (optional)
-
Required Headers:
authorization: Bearer {token}
Bearing tokens are session-based and may expire. Store securely during session lifetime.
Authentication Step-by-Step and Try It Out in Swagger
-
With your API Key copied to your clipboard select 'Authorize' and within the Available authorizations window paste your API Key as shown below.
-
Click the /authinfo endpoint to expand it.
-
Select Try it out. Enter your email address and click Execute.
- Click Try it out.
5. Observe the "200" response and retrieve your "tenantID" (Copy to your Clipboard).
6. Expand the /authorize endpoint, click Try it out, and paste the tenantId and other values - see formatting example for mandatory fields below.
7. Click Execute, copy the bearerToken from the response.
8. At the top right of Swagger, click Authorize.
9. Paste in your bearerToken within the Authorization (apiKey) section as shown below and click Authorize.
10. Navigate to any /reporting endpoint, click Try it out, enter parameters, and click Execute.
HTTP Status Codes Explained
| HTTP Status Code | Meaning | Recommended Action |
|---|---|---|
| 200 OK | Request successful | No action needed |
| 400 Bad Request | Malformed request | Check JSON, required fields |
| 403 Forbidden | No permission | Check API role or tenant ID |
| 500 Internal Server Error | Unexpected server error | Retry or contact support |
Summary Table of API Calls
| API | Category | Use Case |
|---|---|---|
| /reporting/registeredUsers | User Management | Identify active vs. deleted users |
| /reporting/searches | Discoverability | See what users are searching for |
| /reporting/resourcesAccessed | Item Interaction Analytics | Measure which resources are being used |
| /reporting/courseEnrollments | Learning Engagement | Track assignment and completion progress |
| /reporting/content | Content Analytics | Returns all content metadata for audit |
Registered Users API – POST /reporting/registeredUsers
This API returns all user records, including account creation, deletion/anonymization flags, org context, and lifetime login counts. Use it for lifecycle tracking, adoption trends, and segmenting by attributes, groups, and managers.
Sample Response:
{ "data": [ { "login_id": "string", "tenant_id": "string", "user_id": "string", "display_name": "string", "email": "string", "attributes": [ "string" ], "groups": [ "string" ], "managers": [ "string" ], "login_date": "2025-07-29T09:42:02.195Z", "logout_date": "2025-07-29T09:42:02.195Z", "pinnacle_version": "string", "device": "string", "ip_address": "string" } ], "totalCount": 0 }
Field Descriptions:
| Data Point | Data Type | Value |
|---|---|---|
| user_id | Text | Unique identifier for the user; primary key for joins to logins, enrollments, and content access. |
| tenant_id | Text | Organization/tenant identifier; use for multi-tenant filters and RLS. |
| display_name | Text | User’s full display name (for UI/reporting). |
| Text | User’s email; useful for lookups/notifications. Prefer user_id for joins. |
|
| attributes | Array<Text> | Free-form user attributes (e.g., ["Job Profile: Architect","Region: EMEA"]) for segmentation and slicers. |
| groups | Array<Text> | Group memberships (e.g., ["EMEA > UK > London","BIM Managers"]) for visibility and rollups. |
| managers | Array<Text> | Manager identifiers (names/emails) for hierarchy reporting. |
| created_date | DateTime (ISO 8601) | When the account was created (e.g., 2025-09-11T10:23:46.902Z). |
| deleted_date | DateTime (ISO 8601, nullable) | When the account was marked for deletion (blank if active). |
| is_deleted | Boolean |
true if the account is deleted/inactive. |
| is_anonymized | Boolean |
true if PII has been anonymized (e.g., GDPR/data retention). |
| number_of_logins | Int | Lifetime login count as of extract time. |
| totalCount | Int (top-level) | Total users matching the query; appears alongside data for paging. |
Handling Array Fields (attributes & groups) in the Fact Table
- Create helper columns for quick filtering: attributes_concat and groups_concat.
- Use pipe-wrapped tokens joined by a stable delimiter to avoid substring collisions, e.g.
|Architect|;|Region: EMEA|and|EMEA > UK > London|;|BIM Managers|. - For scalable slicing/hierarchies, build bridge tables: User × Attribute, User × GroupPath, related to Users via
user_id.
Power Query (M) pattern for concatenated helpers
// Attributes → attributes_concat
= Table.AddColumn(Source, "attributes_concat", each
let
L = if Value.Is([attributes], type list) then [attributes]
else try Json.Document([attributes]) otherwise {},
wrapped = List.Transform(L, each "|" & Text.From(_) & "|")
in
Text.Combine(wrapped, "|;|"), type text)
// Groups → groups_concat
= Table.AddColumn(PreviousStep, "groups_concat", each
let
L = if Value.Is([groups], type list) then [groups]
else try Json.Document([groups]) otherwise {},
wrapped = List.Transform(L, each "|" & Text.From(_) & "|")
in
Text.Combine(wrapped, "|;|"), type text)
Joins & Filters
-
Join key:
user_id→ Logins, CourseEnrollments, ResourcesAccessed. -
Common filters:
created_datebetween Start/End; optionalis_deleted = false; optionaltenant_idfor multi-tenant. -
Paging: use
totalCountto iterate pages and display overall counts.
Logins API – POST /reporting/logins
Returns login and logout records for each user session, including device type, Pinnacle version, and timestamped activity. Useful for auditing access patterns, identifying peak usage windows, and troubleshooting device-related issues.
Sample Response:
{ "data": [ { "login_id": "string", "tenant_id": "string", "user_id": "string", "display_name": "string", "email": "string", "attributes": [ "string" ], "groups": [ "string" ], "managers": [ "string" ], "login_date": "2025-07-29T09:42:02.195Z", "logout_date": "2025-07-29T09:42:02.195Z", "pinnacle_version": "string", "device": "string", "ip_address": "string" } ], "totalCount": 0 }
Field Descriptions:
| Data Point | Data Type | Value |
|---|---|---|
| login_id | Text | Unique identifier for this login session; supports user auditing and login tracking |
| tenant_id | Text | Organization ID; used to filter login activity by customer |
| user_id | Text | Internal user ID; allows joining login activity to user metadata |
| display_name | Text | Full name of the user; useful for dashboards and user recognition |
| Text | User’s email address; allows filtering or reporting by user | |
| attributes | Array of Text | Metadata describing user profile (e.g., department, job role) |
| groups | Array of Text | Lists user groups during login; supports group-level engagement reporting |
| managers | Array of Text | Associated managers at time of login; useful for roll-up reporting |
| login_date | DateTime (ISO 8601) | Timestamp of user login (e.g., 2025-07-29T09:42:02.195Z) |
| logout_date | DateTime (ISO 8601) | Timestamp of logout; useful for tracking session duration and logout patterns |
| pinnacle_version | Text | Version of the Pinnacle platform accessed; helps track adoption and upgrade impact |
| device | Text | User device or browser details; helpful for usage and troubleshooting analysis |
| ip_address | Text | IP address at login; supports location insights, auditing, and security |
| totalCount | Int | Total number of matching login records; returned outside the data array for pagination |
Searches API – POST /reporting/searches
Returns all search events triggered by users. Use this to monitor platform discoverability, evaluate search effectiveness, and identify knowledge gaps based on search intent.
Sample Response:
{ "data": [ { "search_id": "string", "tenant_id": "string", "user_id": "string", "display_name": "string", "email": "string", "attributes": ["string"], "groups": ["string"], "managers": ["string"], "search_date": "2025-07-16T15:50:12.146Z", "search_term": "string" } ], "totalCount": 0 }
Field Descriptions:
| Data Point | Data Type | Value |
|---|---|---|
| search_id | Text | Unique identifier for the search event; useful for auditing and tracking search patterns |
| tenant_id | Text | Organization ID; allows filtering by customer account or tenant |
| user_id | Text | Unique ID of the user performing the search |
| display_name | Text | Full name of the user; useful for reporting and admin dashboards |
| Text | User's email address; used for filtering or user-specific reporting | |
| attributes | Array of Text | Metadata tags like department, job role, or skill set; useful for analyzing search behavior |
| groups | Array of Text | User's assigned groups at time of search; allows group-based usage reporting |
| managers | Array of Text | Associated managers; enables filtering and hierarchy-based reporting |
| search_date | DateTime (ISO 8601) | Timestamp of when the search occurred (e.g., 2025-07-25T09:05:51.405Z) |
| search_term | Text | The exact term or phrase entered in the search field |
| totalCount | Int | Total number of search records matching the query; appears outside the data array and supports pagination |
Resources Accessed API – POST /reporting/resourcesAccessed
Returns detailed records of each user interaction with content, including the user’s metadata, content type, categories, and the method of access. Ideal for measuring content effectiveness, identifying popular resources, and analyzing user journeys.
Sample Response:
{ "data": [ { "access_id": "string", "tenant_id": "string", "user_id": "string", "display_name": "string", "email": "string", "attributes": [ "string" ], "groups": [ "string" ], "managers": [ "string" ], "accessed_date": "2025-07-29T10:17:41.167Z", "content_id": "string", "content_name": "string", "content_type": "string", "publisher": "string", "topics": [ "string" ], "subtopics": [ "string" ], "libraries": [ "string" ], "referred_by": "string" } ], "totalCount": 0 }
Field Descriptions:
| Data Point | Data Type | Value |
|---|---|---|
| access_id | Text | Unique identifier for this access event; critical for auditing and troubleshooting |
| tenant_id | Text | Organization ID; used to segment or filter access data by customer |
| user_id | Text | Unique ID of the user accessing the content |
| display_name | Text | Full name of the user for reporting and analysis |
| Text | User’s email address; useful for communication and filtering | |
| attributes | Array of Text | User metadata (e.g., job role, department); enables segmentation and advanced reporting |
| groups | Array of Text | Lists user group memberships at the time of access |
| managers | Array of Text | IDs or names of the user’s managers; supports hierarchy-based reporting |
| accessed_date | DateTime (ISO 8601) | Date and time of access; format: YYYY-MM-DDTHH:mm:ss.sssZ (e.g., 2025-07-25T09:05:51.412Z) |
| content_id | Text | Unique ID of the accessed content |
| content_name | Text | Name or title of the accessed content |
| content_type | Text | Type of content (e.g., Document, Video, Workflow) |
| publisher | Text | Publisher or owner of the content |
| topics | Array of Text | High-level categories for the content |
| subtopics | Array of Text | More granular content categorization |
| libraries | Array of Text | Libraries that house the content; used for segmentation and filtering |
| referred_by | Text | Indicates the source of referral (e.g., search, direct link) |
| totalCount | Int | Total number of item interactions. Returned outside the data array; used for paging through large results |
Enrollments API – POST /reporting/courseEnrollments
Returns detailed records of course enrollments, including user info, assignment details, time metrics, SCORM/personalized flags, quiz results, and progress. Ideal for compliance tracking, progress analysis, and training strategy optimization.
Sample Response:
{ "data": [ { "enrollment_id": "string", "tenant_id": "string", "assigned_to_user_id": "string", "assigned_to_display_name": "string", "assigned_to_email": "string", "assigned_date": "2025-07-29T09:43:58.376Z", "assigned_by_user_id": "string", "assigned_by_display_name": "string", "attributes": ["string"], "groups": ["string"], "managers": ["string"], "course_id": "string", "course_version": "string", "topics": ["string"], "subtopics": ["string"], "libraries": ["string"], "course_duration_minutes": 0, "assigned_minutes": 0, "viewed_minutes": 0, "publisher": "string", "percent_reviewed": 0, "learning_path_id": "string", "learning_path": "string", "status": "string", "quiz_status": "string", "due_date": "2025-07-29T09:43:58.376Z", "completed_date": "2025-07-29T09:43:58.376Z", "dropped_date": "2025-07-29T09:43:58.376Z", "is_self_enrolled": true, "has_due_date": true, "is_completed": true, "is_dropped": true, "is_scorm": true, "is_personalized": true, "assessment": "string" } ], "totalCount": 0 }
Field Descriptions:
| Data Point | Data Type | Value |
|---|---|---|
| enrollment_id | Text | Unique identifier for each enrollment record; used for tracking and referencing |
| tenant_id | Text | Organization ID; enables filtering by customer organization |
| assigned_to_user_id | Text | Unique ID of the user receiving the assignment |
| assigned_to_display_name | Text | Full display name of the assigned user; improves reporting readability |
| assigned_to_email | Text | Email address of the assigned user; used for communication and filtering |
| assigned_date | DateTime (ISO 8601) | Timestamp of assignment (e.g., 2025-07-25T08:44:33.849Z) |
| assigned_by_user_id | Text | Unique ID of the assignor |
| assigned_by_display_name | Text | Full name of the person who made the assignment; provides audit trail context |
| attributes | Array of Text | Custom user metadata (e.g., job role, discipline); enables filtering and personalized reporting |
| groups | Array of Text | Groups the user belongs to; used for managing assignments and visibility |
| managers | Array of Text | Names or IDs of assigned managers; allows filtering by reporting structure |
| course_id | Text | Unique identifier for the assigned course |
| course_version | Text | Indicates the version of the assigned course |
| topics | Array of Text | Course-related topics; used for filtering, recommendations, and analytics |
| subtopics | Array of Text | More granular categorization under topics |
| libraries | Array of Text | Lists which libraries the course belongs to; used to segment and organize content |
| course_duration_minutes | Int | Total course length in minutes; supports time investment tracking |
| assigned_minutes | Int | Total minutes assigned to the user; helps gauge training workload |
| viewed_minutes | Int | Minutes the user has spent viewing the content |
| publisher | Text | The name of the content publisher |
| percent_reviewed | Int | The percentage of the enrollment completed |
| learning_path_id | Text | Unique ID of the learning path containing the course |
| learning_path | Text | Name of the associated learning path |
| status | Text | Current enrollment status (e.g., Assigned, In Progress, Completed) |
| quiz_status | Text | Status of associated quiz (e.g., Pass, Fail, Not Attempted) |
| due_date | DateTime (ISO 8601) | Due date for enrollment completion |
| completed_date | DateTime (ISO 8601) | Date the user completed the enrollment |
| dropped_date | DateTime (ISO 8601) | Date the user dropped the enrollment |
| is_self_enrolled | Boolean | True if the user self-enrolled into the course |
| has_due_date | Boolean | True if the enrollment has a due date |
| is_completed | Boolean | True if the course was completed |
| is_dropped | Boolean | True if the enrollment was dropped |
| is_scorm | Boolean | True if the course is a SCORM package |
| is_personalized | Boolean | True if the enrollment is part of a personalized learning path |
| assessment | Text | The assessment name linked to the enrollment |
| totalCount | Int | Total number of enrollment records; returned outside the data array |
Content API – POST /reporting/content
Returns all content metadata for inventory, categorization, and audit reporting.
Sample Response:
{ "data": [ { "content_id": "string", "content_name": "string", "content_type": "string", "courses": ["string"], "learning_paths": ["string"], "topics": ["string"], "subtopics": ["string"], "libraries": ["string"], "url": "string", "duration_minutes": 0, "calculated_duration": 0, "video_duration": "string", "difficulty": "string", "publisher": "string", "created_date": "2025-07-25T11:19:45.838Z", "created_by": "string", "modified_date": "2025-07-25T11:19:45.838Z", "modified_by": "string", "last_accessed_date": "2025-07-25T11:19:45.838Z", "last_accessed_by": "string", "learning_tags": ["string"], "command_tags": ["string"], "keywords": ["string"], "folder": "string", "parent_folder": "string", "folder_path": "string" } ], "totalCount": 0 }
Field Descriptions:
| Data Point | Data Type | Value |
|---|---|---|
| content_id | Text | Unique identifier for the content item; used for joins and tracking |
| content_name | Text | Title of the content (e.g., course name, video title) |
| content_type | Text | Type of content (e.g., Document, Video, Workflow, Course) |
| courses | Array of Text | Lists courses this content is associated with; supports training structure analysis |
| learning_paths | Array of Text | Lists learning paths this content belongs to; helps track structured learning |
| topics | Array of Text | High-level categorization of content |
| subtopics | Array of Text | More granular categories under each topic |
| libraries | Array of Text | Libraries where this content is stored; helps control visibility and access |
| url | Text | Direct link to launch or preview the content |
| duration_minutes | Int | Manually entered duration (if provided by the content author) |
| calculated_duration | Int | System-estimated duration (based on length of video or workflow steps) |
| video_duration | Text | Actual video duration in hh:mm:ss format (if applicable); useful for media analysis |
| difficulty | Text | Content difficulty level (e.g., Beginner, Intermediate, Advanced) |
| publisher | Text | Name of the person or team who published the content |
| created_date | DateTime (ISO 8601) | When the content was created |
| created_by | Text | Username or ID of the user who created the content |
| modified_date | DateTime (ISO 8601) | When the content was last modified |
| modified_by | Text | Username or ID of the person who last modified the content |
| last_accessed_date | DateTime (ISO 8601) | Last date/time the content was accessed by a user |
| last_accessed_by | Text | Name or ID of the last user to access this content |
| learning_tags | Array of Text | Tags that link content to skill areas or job profiles; enhances search and automation |
| command_tags | Array of Text | Used for linking content to specific software commands or tools |
| keywords | Array of Text | Searchable keywords to improve discoverability |
| folder | Text | Immediate folder where content is stored |
| parent_folder | Text | Parent folder of the current folder |
| folder_path | Text | Full path of the folder hierarchy (e.g., Training > Civil 3D > Workflows) |
| totalCount | Int | Total number of content records returned. totalCount is outside the data array and helps with pagination. |
Models Section – Understanding API Response Structure
The Models section in Swagger UI documents the exact structure of the data objects that underpin these API responses. These models reflect the way Pinnacle Series stores this information and serve as a reference so technical teams can plan integrations with confidence, knowing exactly what fields, data types, and structures to expect.
Why this matters:
- These models help developers understand exactly what information will come back in API responses.
- They serve as a schema blueprint so teams can efficiently parse, store, and integrate this data into their own systems (e.g., databases, reporting tools, dashboards).
- The models also ensure that integrations handle fields like arrays (e.g.,
topics,groups,managers) and dates (accessed_date) properly.
How you might use this:
- To design integrations that expect consistent field names and data types.
- To map API response fields to internal reporting structures or analytics platforms.
- To identify what data points are available for building dashboards or reports before writing queries or building connectors.
- You don’t need to reference or use these model names directly — they serve as documentation aids, not API input requirements.
- Field names and types in these models match what you receive in API responses, making it easier to plan integrations, parsing, and data joins.






