openapi: 3.0.0
info:
title: Tovuti REST API
version: 1.66.3
termsOfService: https://www.tovutilms.com/terms
contact:
name: Tovuti Support Page
url: https://help.tovutilms.com
email: support@tovutiteam.com
license:
name: Tovuti LMS End User License
url: https://www.tovutilms.com/end-user-license
servers:
- url: https://{host}/api/v1
variables:
host:
default: api.tovuti.io
security:
- sanctumToken: []
tags:
- name: Assignments
- name: Assessments
- name: Assessment Question Banks
- name: Assessment Questions
- name: Audit
- name: Awards
- name: Checklists
- name: Community Groups
- name: Courses
- name: Course Categories
- name: Course Progress
- name: Custom Fields
- name: Events
- name: Instructors
- name: Learning Paths
- name: Learning Path Categories
- name: Learning Path Progress
- name: Learning Path Subcategories
- name: Lessons
- name: Media Categories
- name: Media Items
- name: Meetings
- name: Objects
- name: Object Types
- name: Payments
- name: Profile Fields
- name: Promo Codes
- name: Purchase Orders
- name: Quizzes
- name: Reports
- name: Subscriptions
- name: Surveys
- name: Teams
- name: Transactions
- name: Users
- name: User Groups
paths:
/audit/admin:
get:
tags:
- Audit
summary: Read Admin Audit Log
parameters:
- in: query
schema:
type: integer
name: cursor
description: >
Retrieve all log entries after this ID. Cursor paging walks entries in
ascending id order, so it cannot be combined with `sortBy` / `sortDir`;
a request that sends both is rejected with HTTP 400.
- in: query
schema:
type: string
format: date
description: Limit results to log entries before this date
example: 2023-01-12
name: before
- in: query
schema:
type: string
format: date
description: Limit results to log entries after this date
example: 2023-01-12
name: after
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
name: auditTypeId
schema:
type: integer
description: Filter to entries whose audit type id (foreign_table) matches this value. Required when itemId is supplied.
- in: query
name: itemId
schema:
type: integer
description: Filter to entries whose target record id (foreign_id) matches this value. Must be paired with auditTypeId since item ids are only unique within a single audit type.
- in: query
name: userId
schema:
type: integer
description: Filter to entries logged for actions performed by this user id.
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Audit"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_admin_audit_log
/audit/auth:
get:
tags:
- Audit
summary: Read User Authentication log
parameters:
- in: query
schema:
type: integer
name: cursor
description: >
Retrieve all log entries after this ID. Cursor paging walks entries in
ascending id order, so it cannot be combined with `sortBy` / `sortDir`;
a request that sends both is rejected with HTTP 400.
- in: query
schema:
type: string
format: date
description: Limit results to log entries before this date
example: 2023-01-12
name: before
- in: query
schema:
type: string
format: date
description: Limit results to log entries after this date
example: 2023-01-12
name: after
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/AuthAudit"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_user_authentication_log
/audit/types:
get:
tags:
- Audit
summary: Read Audit Action Types
parameters:
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/AuditActionType"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
description: 'Pagination note: this endpoint never returns total or last_page (includeTotal is not supported).'
operationId: read_audit_action_types
/assignment:
post:
tags:
- Assignments
summary: Create Assignment
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Assignment"
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Assignment"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_assignment
/assignment/{id}:
get:
tags:
- Assignments
summary: Read Assignment
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Assignment"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_assignment
patch:
tags:
- Assignments
summary: Update Assignment
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AssignmentUpdate'
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/Assignment'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_assignment
delete:
tags:
- Assignments
summary: Delete Assignment
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_assignment
/assignments:
get:
tags:
- Assignments
summary: Read Assignments
parameters:
- in: query
schema:
type: string
example: 1,2,3
name: assignmentIds
description: Comma separated list of assignment ids.
- in: query
name: startBefore
schema:
type: string
format: date
- in: query
name: startAfter
schema:
type: string
format: date
- in: query
name: endBefore
schema:
type: string
format: date
- in: query
name: endAfter
schema:
type: string
format: date
- in: query
name: dueBefore
schema:
type: string
format: date
- in: query
name: dueAfter
schema:
type: string
format: date
- in: query
name: createdBefore
schema:
type: string
format: date
- in: query
name: createdAfter
schema:
type: string
format: date
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/userIdsParam"
- in: query
$ref: "#/components/parameters/groupIdsParam"
- in: query
$ref: "#/components/parameters/teamIdsParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
- in: query
name: title
required: false
schema:
type: string
description: Filter by assignment title. Exact match unless % wildcards are included.
- in: query
name: assignmentFilterType
required: false
schema:
type: string
enum:
- users
- groups
description: Filter by assignment target type.
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Assignment"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_assignments
/award:
post:
tags:
- Awards
summary: Create Award
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Award"
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/Award'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_award
/award/{id}:
get:
tags:
- Awards
summary: Read Award
parameters:
- in: path
name: id
required: true
schema:
type: integer
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Award"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_award
patch:
tags:
- Awards
summary: Update Award
parameters:
- in: path
name: id
required: true
schema:
type: integer
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AwardUpdate'
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Award"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_award
delete:
tags:
- Awards
summary: Delete Award
parameters:
- in: path
name: id
required: true
schema:
type: integer
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_award
/award/{id}/deleteEarned:
delete:
tags:
- Awards
summary: Delete Earned Awards
parameters:
- in: path
name: id
required: true
schema:
type: integer
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_earned_awards
/awards:
get:
tags:
- Awards
summary: Read Awards
parameters:
- in: query
name: awardIds
schema:
type: string
- in: query
name: title
schema:
type: string
description: Filter by title. Exact match unless % wildcards are included.
- in: query
name: type
schema:
type: string
enum:
- badge
- milestone
- certificate
- in: query
name: createdBefore
schema:
type: string
format: date
- in: query
name: createdAfter
schema:
type: string
format: date
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Award"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_awards
/awards/sync:
patch:
tags:
- Awards
summary: Sync Awards
requestBody:
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/AwardSyncRequest"
anyOf:
- required:
- user_id
- required:
- award_id
description: At least one of user_id or award_id is required.
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/AwardSyncRequest"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: sync_awards
/checklist:
post:
tags:
- Checklists
summary: Create Checklist
requestBody:
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/Checklist"
required:
- title
- due_date
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/Checklist'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_checklist
/checklist/{id}:
get:
tags:
- Checklists
summary: Read Checklist
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Checklist"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_checklist
patch:
tags:
- Checklists
summary: Update Checklist
description: 'Checklist items can be updated by passing the id of the checklist item in the patch, for example: { "id": "1689003604CWilGr", "title": "Updated Title" }. If a checklist item needs to be deleted, include the delete flag and set it to true, for example: { "id": "1689003604CWilGr", "delete": true }.'
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Checklist"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/Checklist'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_checklist
delete:
tags:
- Checklists
summary: Delete Checklist
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_checklist
/checklist/{checklistId}/user/{userId}/item/{itemId}:
patch:
tags:
- Checklists
summary: Update Checklist Item Completion
description: 'Marks a single checklist item complete or incomplete for a user. When completing the final required item, the parent checklist is marked complete and any configured admin and user "checklist completed" notifications are sent. Item points are awarded (or reversed). Awards/badges tied to checklist completion are NOT granted by this call — call PATCH /awards/sync with the user_id afterward to evaluate them.'
parameters:
- in: path
name: checklistId
schema:
type: integer
required: true
- in: path
name: userId
schema:
type: integer
required: true
- in: path
name: itemId
description: The checklist item identifier (the item "id" from GET /checklist/{id}).
schema:
type: integer
required: true
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- is_complete
properties:
is_complete:
type: boolean
example: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
id:
type: integer
user_id:
type: integer
checklist_id:
type: integer
item_id:
type: string
item_name:
type: string
nullable: true
is_complete:
type: boolean
completed_at:
type: string
nullable: true
updated_at:
type: string
nullable: true
checklist_progress:
type: integer
"400":
description: Validation error (e.g. is_complete missing or not a boolean).
content:
application/json: {}
"404":
description: User, checklist, or checklist item not found.
content:
application/json: {}
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: update_checklist_item_completion
/checklists:
get:
tags:
- Checklists
summary: Read Checklists
parameters:
- in: query
schema:
type: string
description: Comma separated list of checklist ids.
example: 1,2,3
name: checklistIds
- in: query
schema:
type: string
example: ChecklistTitle
name: title
description: Filter by title. Exact match unless % wildcards are included.
- in: query
name: dueBefore
schema:
type: string
format: date
- in: query
name: dueAfter
schema:
type: string
format: date
- in: query
name: createdBefore
schema:
type: string
format: date
- in: query
name: createdAfter
schema:
type: string
format: date
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Checklist"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_checklists
/communityGroup:
post:
tags:
- Community Groups
summary: Create Community Group
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/CommunityGroup"
responses:
"201":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/CommunityGroup'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_community_group
/communityGroup/{id}:
get:
tags:
- Community Groups
summary: Read Community Group
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/CommunityGroup"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_community_group
patch:
tags:
- Community Groups
summary: Update Community Group
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CommunityGroupUpdate'
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/CommunityGroup'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_community_group
delete:
tags:
- Community Groups
summary: Delete Community Group
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_community_group
/communityGroups:
get:
tags:
- Community Groups
summary: Read Community Groups
parameters:
- name: id
in: query
schema:
type: integer
- name: name
in: query
schema:
type: string
- name: groupId
in: query
schema:
type: integer
description: A User group ID
- in: query
name: createdBefore
schema:
type: string
format: date
- in: query
name: createdAfter
schema:
type: string
format: date
- name: published
in: query
schema:
type: boolean
default: true
description: Filter by published state. Defaults to true - unpublished groups are hidden unless published=false is passed.
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/CommunityGroup"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_community_groups
/communityGroup/{id}/posts:
get:
tags:
- Community Groups
summary: Read Community Group Posts
description: |
Returns the top-level content of a community group, newest first: wall posts (`type=post`),
discussion topics (`type=discussion`) and published announcements (`type=announcement`).
Archived wall posts are excluded. Ids are only unique within a `type`; pass both to the
comments endpoint. Timestamps are UTC with one-second precision.
**Polling:** `timestampCreatedAfter` is exclusive, and several items can share a `created_at`
second (an item can also become visible slightly after the second it is stamped with). So
don't pass the latest `created_at` you have seen as-is: pass it minus an overlap window
(60 seconds is enough), and skip items you have already processed, keyed on `type` + `id`.
Passing the latest `created_at` unchanged will silently miss items created in that same second.
parameters:
- in: path
name: id
required: true
schema:
type: integer
description: Community Group ID
- in: query
$ref: "#/components/parameters/timestampCreatedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampCreatedAfterParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/CommunityGroupPost"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_community_group_posts
/communityGroup/post/{id}/comments:
get:
tags:
- Community Groups
summary: Read Community Group Post Comments
description: |
Returns the comments on a community group post, newest first. For a discussion these are
its replies. Announcements in private groups cannot be commented on and return an empty page.
Timestamps are UTC. To poll, use the same overlap-and-dedupe pattern as the posts endpoint,
keyed on the comment `id`.
parameters:
- in: path
name: id
required: true
schema:
type: integer
description: Post ID, as returned by the posts endpoint
- in: query
name: type
description: The `type` of the post the ID refers to.
schema:
type: string
enum: [post, discussion, announcement]
default: post
- in: query
$ref: "#/components/parameters/timestampCreatedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampCreatedAfterParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/CommunityGroupComment"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_community_group_post_comments
/course:
post:
tags:
- Courses
summary: Create Course
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Course"
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/Course'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_course
/course/{id}:
get:
tags:
- Courses
summary: Read Course
parameters:
- in: path
name: id
schema:
type: integer
required: true
- in: query
name: excludeRegistrants
schema:
type: boolean
description: When true, omits the registrants array from the response to improve performance.
- in: query
$ref: "#/components/parameters/excludeParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/Course"
- type: object
properties:
locked:
type: integer
description: 0 - Course is Unlocked, 1 - Course is Locked
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_course
patch:
tags:
- Courses
summary: Update Course
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CourseUpdate'
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Course"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_course
delete:
tags:
- Courses
summary: Delete Course
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_course
/courses:
get:
tags:
- Courses
summary: Read Courses
parameters:
- name: courseIds
in: query
schema:
type: string
- name: title
in: query
schema:
type: string
description: Filter by title. Exact match unless % wildcards are included.
- name: subCategoryIds
in: query
schema:
type: string
description: List of sub categories to search for.
example: "1,2,104"
- name: finalCourseSurveyId
in: query
schema:
type: integer
description: Id of the final course survey for this course.
- name: published
in: query
schema:
type: boolean
- in: query
name: createdBefore
schema:
type: string
format: date
- in: query
name: createdAfter
schema:
type: string
format: date
- in: query
name: modifiedBefore
schema:
type: string
format: date
- in: query
name: modifiedAfter
schema:
type: string
format: date
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
- name: modifyDate
in: query
description: Options include lt, gt, le, and ge for <, >, <=, and >=. Leave blank for =.
schema:
type: string
example: lt2022-16-15
- name: excludeRegistrants
in: query
schema:
type: boolean
description: When true, omits the registrants array from the response to improve performance.
- in: query
$ref: "#/components/parameters/excludeParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Course"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_courses
/courseCategory:
post:
tags:
- Course Categories
summary: Create Course Category
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/CourseCategory"
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/CourseCategory'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_course_category
/courseCategory/{id}:
get:
tags:
- Course Categories
summary: Read Course Category
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/CourseCategory"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_course_category
patch:
tags:
- Course Categories
summary: Edit Course Category
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CourseCategoryUpdate'
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/CourseCategory'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: edit_course_category
delete:
tags:
- Course Categories
summary: Delete Course Category
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_course_category
/courseCategories:
get:
tags:
- Course Categories
summary: Read Course Categories
parameters:
- name: courseCategoryIds
in: query
schema:
type: string
example: 1,2,3
- name: title
in: query
schema:
type: string
example: Course Title
description: Filter by title. Exact match unless % wildcards are included.
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/CourseCategory"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_course_categories
/courseProgress:
post:
tags:
- Course Progress
summary: Create Course Progress
requestBody:
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/CourseProgress"
required:
- user_id
- course_id
- language
responses:
'201':
description: Successfully created user course progress.
content:
application/json:
schema:
$ref: '#/components/schemas/CourseProgress'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_course_progress
/courseProgress/{id}:
get:
tags:
- Course Progress
summary: Read Course Progress
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Course progress record.
content:
application/json:
schema:
$ref: '#/components/schemas/CourseProgress'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_course_progress
patch:
tags:
- Course Progress
summary: Update Course Progress
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/CourseProgress"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/CourseProgress'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_course_progress
delete:
tags:
- Course Progress
summary: Delete Course Progress
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successfully deleted user course progress.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_course_progress
/courseProgresses:
get:
tags:
- Course Progress
summary: Read Course Progresses
description: All parameters can be used in either the query or the request body.
parameters:
- in: query
name: userId
schema:
type: integer
description: Search by user id.
- in: query
name: courseId
schema:
type: integer
description: Search by course id.
- in: query
name: lessonId
schema:
type: integer
- in: query
name: startBefore
schema:
type: string
- in: query
name: startAfter
schema:
type: string
- in: query
name: lastActivityBefore
schema:
type: string
- in: query
name: lastActivityAfter
schema:
type: string
- in: query
name: completedBefore
schema:
type: string
- in: query
name: completedAfter
schema:
type: string
description: Search by lesson id.
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/CourseProgress"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_course_progresses
/customField/{id}:
get:
deprecated: true
tags:
- Profile Fields
summary: "Read Profile Field - Deprecated, use /metadata/customFields?objectType=users&customFieldIds={id} instead"
description: >
Deprecated. User profile field definitions are now read from the Custom Fields
routes: GET /metadata/customFields?objectType=users&customFieldIds={id} returns
the same definition in the CustomFieldDefinition shape.
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/CustomField"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_profile_field
/customFields:
get:
deprecated: true
tags:
- Profile Fields
summary: "Read Profile Fields - Deprecated, use /metadata/customFields?objectType=users instead"
description: >
Deprecated. User profile field definitions are now read from the Custom Fields
routes: GET /metadata/customFields?objectType=users returns the same definitions
in the CustomFieldDefinition shape, with that endpoint's full filter set (type,
enabled and the timestamp filters) and its ordering.
parameters:
- in: query
name: customFieldIds
schema:
type: string
- in: query
name: name
schema:
type: string
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/CustomField'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_profile_fields
/event:
post:
tags:
- Events
summary: Create Event
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Event"
multipart/form-data:
schema:
$ref: "#/components/schemas/EventWithImage"
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/Event'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_event
/event/{id}:
get:
tags:
- Events
summary: Read Event
parameters:
- in: path
name: id
schema:
type: integer
required: true
- in: query
$ref: "#/components/parameters/excludeParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Event"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_event
post:
tags:
- Events
summary: Update Event (multipart)
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/EventWithImageUpdate'
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/Event'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_event_multipart
patch:
tags:
- Events
summary: Update Event.
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/EventUpdate'
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/Event'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_event
/event/{id}/register:
post:
tags:
- Events
summary: Register for Event
description: Only free events, with registration type = 0 or registration_type = 1 can be registered for at this time. Users are registered as individuals. Users must already exist in the system in order to be registered for an event.
parameters:
- in: path
name: id
schema:
type: integer
required: true
- in: query
name: userIds
required: true
schema:
type: string
example: 1620265,1620266
description: Comma-separated list of user ids.
- in: query
name: checkedIn
required: false
schema:
type: integer
enum:
- 0
- 1
description: Set to 1 to also check the users in while registering them.
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: register_for_event
/event/{id}/checkin:
post:
tags:
- Events
summary: Check Users into Event
parameters:
- in: path
name: id
schema:
type: integer
required: true
- in: query
name: userIds
required: true
schema:
type: string
example: 1620265,1620266
description: Comma-separated list of user ids.
- in: query
name: cancel
schema:
type: boolean
description: if set to true, checked_in will be set to 0.
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: check_users_into_event
/events:
get:
tags:
- Events
summary: Read Events
parameters:
- in: query
name: eventIds
schema:
type: string
- in: query
name: title
schema:
type: string
description: Filter by title. Exact match unless % wildcards are included.
- in: query
name: languages
schema:
type: string
description: Comma-separated list of languages. Event languages default to '*' which is all languages.
- in: query
name: startBefore
schema:
type: string
format: date
- in: query
name: startAfter
schema:
type: string
format: date
- in: query
name: endBefore
schema:
type: string
format: date
- in: query
name: endAfter
schema:
type: string
format: date
- in: query
name: registrationStartDateBefore
schema:
type: string
format: date
- in: query
name: registrationStartDateAfter
schema:
type: string
format: date
- in: query
name: cutoffDateBefore
schema:
type: string
format: date
- in: query
name: cutoffDateAfter
schema:
type: string
format: date
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/excludeParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Event"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_events
/locations:
get:
tags:
- Events
summary: Read - Locations
parameters:
- in: query
name: eventIds
schema:
type: string
- in: query
name: locationIds
schema:
type: string
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Location"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_locations
/events/categories:
get:
tags:
- Events
summary: Read Event Categories
parameters:
- in: query
name: parentId
schema:
type: integer
description: Filter by parent category ID
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/EventCategory"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_event_categories
/event/category/{id}:
get:
tags:
- Events
summary: Read Event Category
parameters:
- in: path
name: id
required: true
schema:
type: integer
description: Event Category ID
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/EventCategory"
"404":
description: Event Category not found
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_event_category
/instructors:
get:
tags:
- Instructors
summary: Read Instructors
parameters:
- name: userId
in: query
description: Filter by user ID.
schema:
type: integer
example: 123
- name: title
in: query
description: Filter by instructor display name (matches the response `name` field). Exact match unless % wildcards are included.
schema:
type: string
example: John Doe
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Instructor"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_instructors
/learningPath:
post:
tags:
- Learning Paths
summary: Create a Learning Path
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/LearningPath"
multipart/form-data:
schema:
$ref: "#/components/schemas/LearningPathWithImage"
responses:
"201":
description: Successful Response
content:
application/json:
schema:
$ref: "#/components/schemas/LearningPath"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_a_learning_path
/learningPath/{id}:
get:
tags:
- Learning Paths
summary: Read Learning Path
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response
content:
application/json:
schema:
$ref: "#/components/schemas/LearningPath"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_learning_path
patch:
tags:
- Learning Paths
summary: Update Learning Path
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/LearningPathUpdate'
responses:
'201':
description: Successful Response
content:
application/json:
schema:
$ref: "#/components/schemas/LearningPath"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_learning_path
post:
tags:
- Learning Paths
summary: Update Learning Path (multipart)
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/LearningPathWithImageUpdate'
responses:
'201':
description: Successful Response
content:
application/json:
schema:
$ref: "#/components/schemas/LearningPath"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_learning_path_multipart
delete:
tags:
- Learning Paths
summary: Delete Learning Path
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_learning_path
/learningPathProgress:
post:
tags:
- Learning Path Progress
summary: Create Learning Path Progress
description: >-
Completion side effects: when `progress` reaches 100% the learning path is marked
complete — `date_completed` is stamped automatically (and cleared if it later drops below
100%; a caller-supplied `date_completed` is only retained at 100%), and learning-path
completion **points** are awarded automatically (and reversed if it drops below 100%).
Completion **badges/awards are NOT granted by this endpoint**: to grant a badge whose
requirement is learning-path completion, call `PATCH /v1/awards/sync` for the user after
the path reaches 100%.
requestBody:
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/LearningPathProgress"
required:
- user_id
- learning_path_id
responses:
"201":
description: Learning path progress created successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/LearningPathProgress"
"400":
description: >-
Validation error (e.g. missing/invalid user_id or learning_path_id), or an active
progress record already exists for this user and learning path.
"403":
description: Access denied.
'401':
$ref: '#/components/responses/Unauthorized'
operationId: create_learning_path_progress
/learningPathProgress/{id}:
get:
tags:
- Learning Path Progress
summary: Read Learning Path Progress
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Learning path progress record.
content:
application/json:
schema:
$ref: "#/components/schemas/LearningPathProgress"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_learning_path_progress
patch:
tags:
- Learning Path Progress
summary: Update Learning Path Progress
description: >-
Completion side effects: when `progress` reaches 100% the learning path is marked
complete — `date_completed` is stamped automatically (and cleared if it later drops below
100%; a caller-supplied `date_completed` is only retained at 100%), and learning-path
completion **points** are awarded automatically (and reversed if it drops below 100%).
Completion **badges/awards are NOT granted by this endpoint**: to grant a badge whose
requirement is learning-path completion, call `PATCH /v1/awards/sync` for the user after
the path reaches 100%.
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/LearningPathProgress"
responses:
"200":
description: Updated learning path progress record.
content:
application/json:
schema:
$ref: "#/components/schemas/LearningPathProgress"
"400":
description: Validation error.
"403":
description: Access denied.
"404":
description: Learning path progress record not found.
'401':
$ref: '#/components/responses/Unauthorized'
operationId: update_learning_path_progress
delete:
tags:
- Learning Path Progress
summary: Delete Learning Path Progress
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successfully deleted learning path progress.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_learning_path_progress
/learningPathProgresses:
get:
tags:
- Learning Path Progress
summary: Read Learning Path Progresses
parameters:
- in: query
name: userIds
schema:
type: string
description: Comma separated list of user IDs.
example: "1,2,3"
- in: query
name: learningPathIds
schema:
type: string
description: Comma separated list of learning path IDs.
example: "1,2,3"
- in: query
name: startBefore
schema:
type: string
format: date
description: Limit results to those started before this date (Y-m-d).
example: "2023-01-12"
- in: query
name: startAfter
schema:
type: string
format: date
description: Limit results to those started after this date (Y-m-d).
example: "2023-01-12"
- in: query
name: lastActivityBefore
schema:
type: string
format: date
description: Limit results to those with last activity before this date (Y-m-d).
example: "2023-01-12"
- in: query
name: lastActivityAfter
schema:
type: string
format: date
description: Limit results to those with last activity after this date (Y-m-d).
example: "2023-01-12"
- in: query
name: completedBefore
schema:
type: string
format: date
description: Limit results to those completed before this date (Y-m-d).
example: "2023-01-12"
- in: query
name: completedAfter
schema:
type: string
format: date
description: Limit results to those completed after this date (Y-m-d).
example: "2023-01-12"
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/LearningPathProgress"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_learning_path_progresses
/learningPaths:
get:
tags:
- Learning Paths
summary: Read Learning Paths
parameters:
- name: title
in: query
schema:
type: string
example: All About Tovuti
description: "Exact match unless % wildcards are included."
- name: id
in: query
schema:
type: integer
example: 1
- name: user
in: query
schema:
type: integer
example: 1
description: Show learning paths that include the given user id in the view permission
- name: usergroup
in: query
schema:
type: integer
example: 1
description: Show learning paths that include the given user group id in the view permission
- name: accesslevel
in: query
schema:
type: integer
example: 1
description: Show learning paths that include the given access level id in the view permission
- name: courses
in: query
schema:
type: string
example: 1,3
description: "Comma separated list of course IDs"
- name: tags
in: query
schema:
type: string
example: 1,3
description: "Comma separated list of Tag IDs"
- name: subcategories
in: query
schema:
type: string
example: 1,3
description: "Comma separated list of subcategory IDs"
- in: query
schema:
type: string
format: date
description: Limit results to those created before this date
example: 2023-01-12
name: createdBefore
- in: query
schema:
type: string
format: date
description: Limit results to those created after this date
example: 2023-01-12
name: createdAfter
- in: query
schema:
type: string
format: date
description: Limit results to those created modified this date
example: 2023-01-12
name: modifiedBefore
- in: query
schema:
type: string
format: date
description: Limit results to those created modified this date
example: 2023-01-12
name: modifiedAfter
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
- in: query
name: published
required: false
schema:
type: boolean
description: Filter by published state.
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/LearningPath"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_learning_paths
/learningPaths/tags:
get:
tags:
- Learning Paths
summary: Read Learning Path Tags
parameters:
- name: title
in: query
schema:
type: string
example: A title
description: "Exact match unless % wildcards are included."
- name: id
in: query
schema:
type: integer
example: 1
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Tag"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_learning_path_tags
/learningPathCategory:
post:
tags:
- Learning Path Categories
summary: Create a Learning Path Category
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/LearningPathCategory"
responses:
"201":
description: Successful Response
content:
application/json:
schema:
$ref: "#/components/schemas/LearningPathCategory"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_a_learning_path_category
/learningPathCategory/{id}:
get:
tags:
- Learning Path Categories
summary: Read Learning Path Category
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response
content:
application/json:
schema:
$ref: "#/components/schemas/LearningPathCategory"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_learning_path_category
patch:
tags:
- Learning Path Categories
summary: Update Learning Path Category
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/LearningPathCategoryUpdate'
responses:
'201':
description: Successful Response
content:
application/json:
schema:
$ref: "#/components/schemas/LearningPathCategory"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_learning_path_category
delete:
tags:
- Learning Path Categories
summary: Delete Learning Path Category
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_learning_path_category
/learningPathCategories:
get:
tags:
- Learning Path Categories
summary: Read Learning Path Categories
parameters:
- name: title
in: query
schema:
type: string
example: All About Tovuti
description: "Exact match unless % wildcards are included."
- name: id
in: query
schema:
type: integer
example: 1
- name: subcategories
in: query
schema:
type: string
example: 1,3
description: "Comma separated list of subcategory IDs"
- in: query
schema:
type: string
format: date
description: Limit results to those created before this date
example: 2023-01-12
name: createdBefore
- in: query
schema:
type: string
format: date
description: Limit results to those created after this date
example: 2023-01-12
name: createdAfter
- in: query
schema:
type: string
format: date
description: Limit results to those modified before this date
example: 2023-01-12
name: modifiedBefore
- in: query
schema:
type: string
format: date
description: Limit results to those modified after this date
example: 2023-01-12
name: modifiedAfter
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
- in: query
name: published
required: false
schema:
type: boolean
description: Filter by published state.
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/LearningPathCategory"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_learning_path_categories
/learningPathSubcategory:
post:
tags:
- Learning Path Subcategories
summary: Create a Learning Path Subcategory
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/LearningPathSubcategory"
multipart/form-data:
schema:
$ref: "#/components/schemas/LearningPathSubcategoryWithImage"
responses:
"201":
description: Successful Response
content:
application/json:
schema:
$ref: "#/components/schemas/LearningPathSubcategory"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_a_learning_path_subcategory
/learningPathSubcategory/{id}:
get:
tags:
- Learning Path Subcategories
summary: Read Learning Path Subcategory
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response
content:
application/json:
schema:
$ref: "#/components/schemas/LearningPathSubcategory"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_learning_path_subcategory
patch:
tags:
- Learning Path Subcategories
summary: Update Learning Path Subcategory
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/LearningPathSubcategoryUpdate'
responses:
'201':
description: Successful Response
content:
application/json:
schema:
$ref: "#/components/schemas/LearningPathSubcategory"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_learning_path_subcategory
post:
tags:
- Learning Path Subcategories
summary: Update Learning Path Subcategory (multipart)
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/LearningPathSubcategoryWithImageUpdate'
responses:
'201':
description: Successful Response
content:
application/json:
schema:
$ref: "#/components/schemas/LearningPathSubcategory"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_learning_path_subcategory_multipart
delete:
tags:
- Learning Path Subcategories
summary: Delete Learning Path Subcategory
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_learning_path_subcategory
/learningPathSubcategories:
get:
tags:
- Learning Path Subcategories
summary: Read Learning Path Subcategories
parameters:
- name: title
in: query
schema:
type: string
example: All About Tovuti
description: "Exact match unless % wildcards are included."
- name: id
in: query
schema:
type: integer
example: 1
- name: categories
in: query
schema:
type: string
example: 1,3
description: "Comma separated list of category IDs"
- name: learningPaths
in: query
schema:
type: string
example: 1,3
description: "Comma separated list of learning path IDs"
- in: query
schema:
type: string
format: date
description: Limit results to those created before this date
example: 2023-01-12
name: createdBefore
- in: query
schema:
type: string
format: date
description: Limit results to those created after this date
example: 2023-01-12
name: createdAfter
- in: query
schema:
type: string
format: date
description: Limit results to those created modified this date
example: 2023-01-12
name: modifiedBefore
- in: query
schema:
type: string
format: date
description: Limit results to those created modified this date
example: 2023-01-12
name: modifiedAfter
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
- in: query
name: published
required: false
schema:
type: boolean
description: Filter by published state.
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/LearningPathSubcategory"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_learning_path_subcategories
/lesson:
post:
tags:
- Lessons
summary: Create Lesson
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/LessonInsert"
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/Lesson'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_lesson
/lesson/{id}:
get:
tags:
- Lessons
summary: Read Lesson
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Lesson"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_lesson
patch:
tags:
- Lessons
summary: Update Lesson
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/LessonInsertUpdate'
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Lesson"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_lesson
delete:
tags:
- Lessons
summary: Delete Lesson
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_lesson
/lessons:
get:
tags:
- Lessons
summary: Read Lessons
parameters:
- name: courseTitle
in: query
schema:
type: string
example: All About Tovuti
description: ""
- in: query
$ref: "#/components/parameters/courseIdsParam"
- name: language
in: query
schema:
type: string
example: en-GB
description: ""
- name: lessonIds
in: query
schema:
type: string
example: 1,3
description: ""
- name: lessonTitle
in: query
schema:
type: string
example: About Tovuti
description: ""
- name: published
in: query
schema:
type: boolean
example: 0|1
description: ""
- name: modifyDate
in: query
description: Options include lt, gt, le, and ge for <, >, <=, and >=. Leave blank for =.
schema:
type: string
example: lt2022-16-15
- name: teacherName
in: query
schema:
type: string
example: Salomon Arthur
description: ""
- name: isFinalCourseSurvey
in: query
schema:
type: boolean
- in: query
name: createdBefore
schema:
type: string
format: date
- in: query
name: createdAfter
schema:
type: string
format: date
- in: query
name: modifiedBefore
schema:
type: string
format: date
- in: query
name: modifiedAfter
schema:
type: string
format: date
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
- in: query
name: title
required: false
schema:
type: string
description: Filter by lesson title. Exact match unless % wildcards are included.
- in: query
name: createDate
required: false
schema:
type: string
format: date
description: Filter by creation date (YYYY-MM-DD).
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Lesson"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
description: Unlike sibling endpoints, invalid query parameters here return 422 with {"message", "errors"} rather than 400.
operationId: read_lessons
/mediaCategory:
post:
tags:
- Media Categories
summary: Create Media Category
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/MediaCategory"
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/MediaCategory'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_media_category
/mediaCategory/{id}:
get:
tags:
- Media Categories
summary: Read Media Category
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/MediaCategory"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_media_category
patch:
tags:
- Media Categories
summary: Update Media Category
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/MediaCategoryUpdate'
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/MediaCategory"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_media_category
delete:
tags:
- Media Categories
summary: Delete Media Category
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_media_category
/mediaCategories:
get:
tags:
- Media Categories
summary: Read Media Categories
parameters:
- name: title
in: query
schema:
type: string
example: category name
description: ""
description: Filter by title. Exact match unless % wildcards are included.
- name: mediaCategoryIds
in: query
schema:
type: string
example: 1,3
description: ""
- name: published
in: query
schema:
type: boolean
example: 0|1
description: ""
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/MediaCategory"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_media_categories
/mediaItem:
post:
tags:
- Media Items
summary: Create Media Item
requestBody:
content:
multipart/form-data:
schema:
$ref: "#/components/schemas/MediaItem"
application/json:
schema:
$ref: '#/components/schemas/MediaItemNoData'
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/MediaItem'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_media_item
/mediaItem/{id}:
post:
tags:
- Media Items
summary: Update Media Item With File Upload
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/MediaItemUpdate'
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/MediaItem'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_media_item_with_file_upload
get:
tags:
- Media Items
summary: Read Media Item
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/MediaItem"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_media_item
patch:
tags:
- Media Items
summary: Update Media Item Without File Upload
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/MediaItemNoDataUpdate'
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/MediaItem"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_media_item_without_file_upload
delete:
tags:
- Media Items
summary: Delete Media Item
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_media_item
/mediaItems:
get:
tags:
- Media Items
summary: Read Media Items
parameters:
- name: title
in: query
schema:
type: string
example: my video
description: ""
description: Filter by title. Exact match unless % wildcards are included.
- name: mediaItemIds
in: query
schema:
type: string
example: 1,3
description: ""
- name: published
in: query
schema:
type: boolean
example: 0|1
description: ""
- in: query
name: createdBefore
schema:
type: string
format: date
- in: query
name: createdAfter
schema:
type: string
format: date
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/MediaItem"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_media_items
/meeting:
post:
tags:
- Meetings
summary: Create Meeting
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Meeting"
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Meeting"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_meeting
/meeting/{id}:
get:
tags:
- Meetings
summary: Read Meeting
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Meeting"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_meeting
patch:
tags:
- Meetings
summary: Update Meeting
description: >
Not a partial update: `meetingName`, `meetingType`, `date` and
`timezone` must be sent on every request, even when they are not
changing, or the request is rejected with HTTP 400.
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Meeting"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Meeting"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_meeting
delete:
tags:
- Meetings
summary: Delete Meeting
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_meeting
/meetings:
get:
tags:
- Meetings
summary: Read Meetings
parameters:
- in: query
name: meetingIds
schema:
type: string
- in: query
name: meetingName
schema:
type: string
- in: query
name: meetingType
schema:
type: string
enum:
- tovuti
- zoom
- webex
- gotomeeting
- google
- joinme
- other
example: tovuti|zoom|webex|gotomeeting|google|joinme|other
- in: query
schema:
type: string
format: date
name: dateBefore
- in: query
schema:
type: string
format: date
name: dateAfter
- in: query
schema:
type: string
format: date
name: createdBefore
- in: query
schema:
type: string
format: date
name: createdAfter
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Meeting"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_meetings
/metadata/customField/{id}:
get:
tags:
- Custom Fields
summary: Read Custom Field
description: >
A single custom field definition. Custom fields carry extra structured data on
courses, events, purchase orders and user objects. `{id}` is always a metadata
custom field id: user profile field definitions have no single-record route
here - list them with GET /metadata/customFields?objectType=users, narrowing
with customFieldIds when one specific definition is wanted.
parameters:
- in: path
name: id
required: true
schema:
type: integer
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/CustomFieldDefinition"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_custom_field
/metadata/customField/{id}/values:
get:
tags:
- Custom Fields
summary: Read Values For Custom Field
description: >
Values recorded for a single custom field. Equivalent to
/metadata/customFields/values?fieldIds={id}, with one exception: this route
resolves the id first and returns 404 when the field definition has been deleted,
whereas the fieldIds filter returns the orphaned value rows.
Results are ordered by timestamp_modified, then id - descending by default,
ascending with sortBy=timestampModified&sortDir=asc.
Rows whose timestamp is NULL are excluded by any timestamp filter.
parameters:
- in: path
name: id
required: true
schema:
type: integer
- in: query
$ref: "#/components/parameters/objectIdsParam"
- in: query
name: objectType
description: >
Filter to values attached to this kind of object. Required whenever
objectIds is supplied, because object_id is only unique within an
object type - course 91 and event 91 are different objects.
schema:
type: string
enum: [courses, events, "purchase order", "user objects"]
example: courses
- in: query
name: type
description: Filter to values whose field definition has this type.
schema:
type: string
example: text
- in: query
name: enabled
description: >
Filter to values whose field definition has this enabled flag. Accepts
`1`/`0` or `true`/`false`. Omit to return both. Values whose definition
has been deleted match neither enabled state and are only returned when
this filter is omitted.
schema:
type: boolean
- in: query
$ref: "#/components/parameters/timestampCreatedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampCreatedAfterParam"
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/CustomFieldValueDetail"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_custom_field_values
/metadata/customFields:
get:
tags:
- Custom Fields
summary: Read Custom Fields
description: >
Custom field definitions for courses, events, purchase orders, user objects
and users. Results are ordered by timestamp_modified, then id - descending
by default, ascending with sortBy=timestampModified&sortDir=asc.
Rows whose timestamp is NULL are excluded by any timestamp filter.
`objectType=users` returns user profile field definitions - the
definitions behind the values that
GET /metadata/customFields/values?objectType=users reports. Omitting
objectType keeps the endpoint's original meaning: metadata custom field
definitions only, without user profile fields.
parameters:
- in: query
name: customFieldIds
description: >
Comma separated list of custom field ids. Field definitions are numbered
independently per object type family: with `objectType=users` these are
user field definition ids; otherwise they are metadata custom field ids.
schema:
type: string
example: 44,45
- in: query
name: name
description: Partial, case-insensitive match on the field name.
schema:
type: string
example: Cost Center
- in: query
name: type
description: >
Field type. With `objectType=users` this matches user profile field types
(text, textarea, select, list, radio, checkbox, country, gender, email,
time, date, url, birthdate, and `group` for section headers).
schema:
type: string
example: text
- in: query
name: objectType
description: >
Filter to definitions for this kind of object. `users` selects user
profile field definitions, which are stored separately from the other
object types and are only returned when requested explicitly.
schema:
type: string
enum: [courses, events, "purchase order", "user objects", users]
example: courses
- in: query
name: enabled
description: >
Filter on the field's enabled flag. Accepts `1`/`0` or `true`/`false`.
Omit to return both.
schema:
type: boolean
- in: query
$ref: "#/components/parameters/timestampCreatedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampCreatedAfterParam"
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/CustomFieldDefinition"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_custom_fields
/metadata/customFields/values:
get:
tags:
- Custom Fields
summary: Read Custom Field Values
description: >
Values recorded against custom fields, across all fields. object_id refers to a
course, event, purchase order, user object or user id, per object_type. Results are ordered by timestamp_modified, then id - descending by default, ascending with sortBy=timestampModified&sortDir=asc.
Rows whose timestamp is NULL are excluded by any timestamp filter.
`objectType=users` returns user profile custom field values - the data
embedded as `customFields` in user payloads (presented here in this
endpoint's detail shape, not the trimmed embed shape) - and is the way
to fetch it independently when calling the Users endpoints with
`exclude=customFields`.
parameters:
- in: query
name: fieldIds
description: >
Comma separated list of custom field ids. Field definitions are numbered
independently per object type family: for `objectType=users` these are user
field definition ids (as returned by GET /metadata/customFields?objectType=users); for every other
objectType they are metadata custom field ids (GET /metadata/customFields).
objectType is therefore required whenever fieldIds is supplied.
schema:
type: string
example: 44,45
- in: query
$ref: "#/components/parameters/objectIdsParam"
- in: query
name: objectType
description: >
Filter to values attached to this kind of object. For `users`, objectIds
takes user ids. Required whenever objectIds or fieldIds is supplied:
object_id is only unique within an object type - course 91 and event 91
are different objects - and field definitions are numbered independently
per object type family.
schema:
type: string
enum: [courses, events, "purchase order", "user objects", users]
example: courses
- in: query
name: type
description: Filter to values whose field definition has this type.
schema:
type: string
example: text
- in: query
name: enabled
description: >
Filter to values whose field definition has this enabled flag. Accepts
`1`/`0` or `true`/`false`. Omit to return both. Values whose definition
has been deleted match neither enabled state and are only returned when
this filter is omitted.
schema:
type: boolean
- in: query
$ref: "#/components/parameters/timestampCreatedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampCreatedAfterParam"
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/CustomFieldValueDetail"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_custom_fields_values
/object:
post:
tags:
- Objects
summary: Create Object
requestBody:
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/Object"
required:
- title
- type_id
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/Object'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_object
/object/{id}:
get:
tags:
- Objects
summary: Read Object
parameters:
- in: path
name: id
schema:
type: integer
required: true
- in: query
$ref: "#/components/parameters/excludeParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Object"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_object
patch:
tags:
- Objects
summary: Update Object
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Object"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Object"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_object
delete:
tags:
- Objects
summary: Delete Object
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_object
/objects:
get:
tags:
- Objects
summary: Read Objects
parameters:
- name: title
in: query
schema:
type: string
example: MyOrganization
description: ""
description: Filter by title. Exact match unless % wildcards are included.
- in: query
$ref: "#/components/parameters/customFieldsParam"
- in: query
name: objectIds
schema:
type: string
example: 1,2,3
- in: query
$ref: "#/components/parameters/timestampCreatedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampCreatedAfterParam"
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
- in: query
$ref: "#/components/parameters/excludeParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Object"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_objects
/objectType:
post:
tags:
- Object Types
summary: Create Object Type
requestBody:
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/ObjectType"
required:
- title
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/ObjectType'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_object_type
/objectType/{id}:
get:
tags:
- Object Types
summary: Read Object Type
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/ObjectType"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_object_type
patch:
tags:
- Object Types
summary: Update Object Type
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ObjectType"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/ObjectType"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_object_type
delete:
tags:
- Object Types
summary: Delete Object Type
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_object_type
/objectTypes:
get:
tags:
- Object Types
summary: Read Object Types
parameters:
- name: title
in: query
schema:
type: string
example: MyOrganization
description: ""
description: Filter by title. Exact match unless % wildcards are included.
- in: query
name: objectTypeIds
schema:
type: string
example: 3,4,5
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/ObjectType"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_object_types
/profileField:
post:
tags:
- Profile Fields
summary: Create Custom Profile Field
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ProfileField"
responses:
"201":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/ProfileField"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
description: Type-specific keys (options, date_format, min_characters, ...) are only honored for the matching field type; mismatched keys are silently dropped.
operationId: create_custom_profile_field
/profileField/{id}:
get:
tags:
- Profile Fields
summary: Read Custom Profile Field
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/ProfileField"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_custom_profile_field
patch:
tags:
- Profile Fields
summary: Update Custom Profile Field
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ProfileFieldUpdate'
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/ProfileField"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
description: The field type cannot be changed after creation (400). Type-specific keys are only honored for the matching field type.
operationId: update_custom_profile_field
delete:
tags:
- Profile Fields
summary: Delete Custom Profile Field
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_custom_profile_field
/profileFields:
get:
tags:
- Profile Fields
summary: Read Custom Profile Fields
parameters:
- in: query
name: profileFieldIds
schema:
type: string
description: A comma separated list of profile field ids
example: 10,80,219
- in: query
name: name
schema:
type: string
- in: query
name: type
schema:
type: string
enum: [text, textarea, select, list, radio, checkbox, country, gender, email, time, date, url, birthdate]
example: '[text, textarea, select, list, radio, checkbox, country, gender, email, time, date, url, birthdate]'
- in: query
name: visibility
schema:
type: string
example: '[personal, all, admin]'
enum: [personal, all, admin]
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/ProfileField'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_custom_profile_fields
/profileFields/group:
post:
tags:
- Profile Fields
summary: Create Custom Profile Field Group
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ProfileFieldGroup"
responses:
"201":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/ProfileFieldGroup"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_custom_profile_field_group
/profileFields/group/{id}:
get:
tags:
- Profile Fields
summary: Read Custom Profile Field Group
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/ProfileFieldGroup"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_custom_profile_field_group
patch:
tags:
- Profile Fields
summary: Update Custom Profile Field Group
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ProfileFieldGroupUpdate'
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/ProfileFieldGroup"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_custom_profile_field_group
delete:
tags:
- Profile Fields
summary: Delete Custom Profile Field Group
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_custom_profile_field_group
/profileFields/groups:
get:
tags:
- Profile Fields
summary: Read Custom Profile Field Groups
parameters:
- in: query
name: name
schema:
type: string
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/ProfileFieldGroup'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_custom_profile_field_groups
/profileFields/userGroupMapping:
post:
tags:
- Profile Fields
summary: Create Custom Profile Field Mapping
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/UserGroupMapping"
responses:
"201":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/UserGroupMappingResponse"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_custom_profile_field_mapping
/profileFields/userGroupMapping/{id}:
get:
tags:
- Profile Fields
summary: Read Custom Profile Field Mapping
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/UserGroupMappingResponse"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_custom_profile_field_mapping
patch:
tags:
- Profile Fields
summary: Update Custom Profile Field Mapping
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UserGroupMappingUpdate'
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/UserGroupMappingResponse"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_custom_profile_field_mapping
delete:
tags:
- Profile Fields
summary: Delete Custom Profile Field Mapping
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_custom_profile_field_mapping
/profileFields/userGroupMappings:
get:
tags:
- Profile Fields
summary: Read Custom Profile Field Mappings
parameters:
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/UserGroupMappingResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_custom_profile_field_mappings
/purchaseOrder/{id}:
get:
tags:
- Purchase Orders
summary: Read Purchase Order
parameters:
- in: path
name: id
required: true
schema:
type: integer
description: Purchase Order ID
- in: query
$ref: "#/components/parameters/excludeParam"
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/PurchaseOrder'
"404":
description: Purchase Order not found
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_purchase_order
/purchaseOrders:
get:
tags:
- Purchase Orders
summary: Read Purchase Orders
parameters:
- in: query
name: purchaseOrderIds
schema:
type: string
description: Comma-separated list of purchase order IDs
- in: query
name: title
schema:
type: string
description: Filter by title Exact match unless % wildcards are included.
- in: query
name: purchaseOrderNumber
schema:
type: string
description: Filter by purchase order number
- in: query
name: enabled
schema:
type: boolean
description: Filter by enabled status
- in: query
name: createdBefore
schema:
type: string
format: date
description: Filter by purchase orders created before this date (YYYY-MM-DD)
- in: query
name: createdAfter
schema:
type: string
format: date
description: Filter by purchase orders created after this date (YYYY-MM-DD)
- in: query
name: modifiedBefore
schema:
type: string
format: date
description: Filter by purchase orders modified before this date (YYYY-MM-DD)
- in: query
name: modifiedAfter
schema:
type: string
format: date
description: Filter by purchase orders modified after this date (YYYY-MM-DD)
- in: query
name: expiresBefore
schema:
type: string
format: date
description: Filter by purchase orders expiring before this date (YYYY-MM-DD)
- in: query
name: expiresAfter
schema:
type: string
format: date
description: Filter by purchase orders expiring after this date (YYYY-MM-DD)
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/excludeParam"
- in: query
$ref: '#/components/parameters/pageParam'
- in: query
$ref: '#/components/parameters/pageSizeParam'
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful response
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/PurchaseOrder'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_purchase_orders
/promoCodes:
get:
tags:
- Promo Codes
summary: Read Promo Codes
parameters:
- name: title
in: query
schema:
type: string
description: Filter by promo code title Exact match unless % wildcards are included.
- name: promoCodeIds
in: query
schema:
type: string
description: Comma separated list of promo code IDs.
- name: code
in: query
schema:
type: string
description: Filter by promo code
- name: courseIds
in: query
schema:
type: string
description: Comma separated list of course IDs.
- name: planIds
in: query
schema:
type: string
description: Comma separated list of subscription plan IDs.
- in: query
name: activeBefore
schema:
type: string
format: date
description: Filter by active date before specified date
- in: query
name: activeAfter
schema:
type: string
format: date
description: Filter by active date after specified date
- in: query
name: expiredBefore
schema:
type: string
format: date
description: Filter by expiration date before specified date
- in: query
name: expiredAfter
schema:
type: string
format: date
description: Filter by expiration date after specified date
- in: query
name: createdBefore
schema:
type: string
format: date
description: Filter by creation date before specified date
- in: query
name: createdAfter
schema:
type: string
format: date
description: Filter by creation date after specified date
- in: query
name: modifiedBefore
schema:
type: string
format: date
description: Filter by modification date before specified date
- in: query
name: modifiedAfter
schema:
type: string
format: date
description: Filter by modification date after specified date
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
- name: excludeCourseIds
in: query
schema:
type: boolean
description: When true, omits the course_ids array from the response to improve performance.
- name: excludePlanIds
in: query
schema:
type: boolean
description: When true, omits the plan_ids array from the response to improve performance.
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/PromoCode'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_promo_codes
/promoCode/{id}:
get:
tags:
- Promo Codes
summary: Read Promo Code
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: Promo code ID
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/PromoCode"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_promo_code
/quiz:
post:
tags:
- Quizzes
summary: Create Quiz
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Quiz"
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/Quiz'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_quiz
/quiz/{id}:
get:
deprecated: true
tags:
- Quizzes
summary: "Read Quiz - Deprecated, use /assessment/{id} instead"
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Quiz"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_quiz_deprecated_use_assessment_id_instead
patch:
tags:
- Quizzes
summary: Update Quiz
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/QuizUpdate'
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/Quiz'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_quiz
delete:
tags:
- Quizzes
summary: Delete Quiz
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_quiz
/quizzes:
get:
deprecated: true
tags:
- Quizzes
summary: "Read Quizzes - Deprecated, use /assessments instead"
parameters:
- in: query
schema:
type: string
description: Comma separated list of quiz ids.
example: 1,2,3
name: quizIds
- in: query
schema:
type: string
description: Comma separated list of course ids.
example: 1,2,3
name: courseIds
- in: query
schema:
type: string
description: Comma separated list of lesson ids.
example: 1,2,3
name: lessonIds
- in: query
schema:
type: string
name: title
description: Filter by title. Exact match unless % wildcards are included.
- in: query
name: createdBefore
schema:
type: string
format: date
- in: query
name: createdAfter
schema:
type: string
format: date
- in: query
name: modifiedBefore
schema:
type: string
format: date
- in: query
name: modifiedAfter
schema:
type: string
format: date
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
- in: query
name: lessonTitle
required: false
schema:
type: string
description: Filter by lesson title.
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Quiz"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_quizzes_deprecated_use_assessments_instead
/assessment/{id}:
get:
tags:
- Assessments
summary: Read Assessment
description: Returns full assessment detail including questions with type-specific data (choices for multiple choice, keywords for free text).
parameters:
- in: path
name: id
required: true
schema:
type: integer
description: Assessment ID
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/AssessmentDetail"
"404":
description: Assessment not found
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_assessment
/assessments:
get:
tags:
- Assessments
summary: Read Assessments
parameters:
- in: query
name: assessmentIds
schema:
type: string
description: Comma separated list of assessment IDs
- in: query
name: courseIds
schema:
type: string
description: Comma separated list of course IDs
- in: query
name: lessonIds
schema:
type: string
description: Comma separated list of lesson IDs
- in: query
name: title
schema:
type: string
description: Filter by title. Exact match unless % wildcards are included.
- in: query
name: enabled
schema:
type: boolean
- in: query
name: type
schema:
type: string
enum:
- quiz
- survey
description: Filter by assessment type
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/AssessmentDetail"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
description: List items do not include questions, course or lesson - use GET /assessment/{id} for the full shape.
operationId: read_assessments
/assessments/results:
get:
tags:
- Assessments
summary: Read Assessment Results
description: Returns a lean summary of assessment results without embedded quiz or answer details. Use /assessments/result/{id} for full answer breakdown.
parameters:
- in: query
name: ids
schema:
type: string
description: Comma separated list of result IDs
- in: query
name: assessmentIds
schema:
type: string
description: Comma separated list of assessment IDs
- in: query
$ref: "#/components/parameters/userNameParam"
- in: query
$ref: "#/components/parameters/userIdsParam"
- in: query
$ref: "#/components/parameters/groupIdsParam"
- in: query
$ref: "#/components/parameters/teamIdsParam"
- in: query
name: lessonId
schema:
type: integer
- in: query
name: archived
description: If true, show only archived data.
schema:
type: boolean
- in: query
name: submittedBefore
schema:
type: string
format: date
description: "Filter by submitted date before this date (YYYY-MM-DD)"
- in: query
name: submittedAfter
schema:
type: string
format: date
description: "Filter by submitted date after this date (YYYY-MM-DD)"
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
- in: query
name: lessonTitle
required: false
schema:
type: string
description: Filter by lesson title.
- in: query
name: courseTitle
required: false
schema:
type: string
description: Filter by course title.
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/AssessmentResultSummary"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_assessment_results
/assessments/result/{id}:
get:
tags:
- Assessments
summary: Read Assessment Result
description: Returns full assessment result detail including answer breakdown.
parameters:
- in: path
name: id
required: true
schema:
type: integer
description: Assessment Result ID
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/AssessmentResultDetail"
"404":
description: Assessment Result not found
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_assessment_result
/assessment/{id}/results:
get:
tags:
- Assessments
summary: Read Results for Assessment
description: Returns results scoped to a specific assessment/quiz.
parameters:
- in: path
name: id
required: true
schema:
type: integer
description: Assessment/Quiz ID
- in: query
$ref: "#/components/parameters/userIdsParam"
- in: query
$ref: "#/components/parameters/groupIdsParam"
- in: query
$ref: "#/components/parameters/teamIdsParam"
- in: query
name: archived
description: If true, show only archived data.
schema:
type: boolean
- in: query
name: submittedBefore
schema:
type: string
format: date
description: "Filter by submitted date before this date (YYYY-MM-DD)"
- in: query
name: submittedAfter
schema:
type: string
format: date
description: "Filter by submitted date after this date (YYYY-MM-DD)"
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/AssessmentResultSummary"
# ==========================================
# Assessment Question Banks
# ==========================================
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_results_for_assessment
/assessments/questionBank:
post:
tags:
- Assessment Question Banks
summary: Create Question Bank
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/QuestionBankCreate"
responses:
"201":
description: Question Bank created successfully
content:
application/json:
schema:
$ref: "#/components/schemas/QuestionBank"
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'422':
$ref: '#/components/responses/UnprocessableEntity'
operationId: create_question_bank
/assessments/questionBanks:
get:
tags:
- Assessment Question Banks
summary: List Question Banks
parameters:
- in: query
name: enabled
schema:
type: boolean
description: Filter by enabled status
- in: query
name: label
schema:
type: string
description: Search by label (partial match)
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/timestampCreatedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampCreatedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
name: page
schema:
type: integer
minimum: 1
description: Page number for pagination
- in: query
name: pageSize
schema:
type: integer
enum: [10, 25, 50, 100, 250]
description: Number of results per page
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/QuestionBank"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
description: List items do not include questions - use GET /assessments/questionBank/{id} for the full shape.
operationId: list_question_banks
/assessments/questionBank/{id}:
get:
tags:
- Assessment Question Banks
summary: Get Question Bank
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: Question Bank ID
responses:
"200":
description: Successful Response
content:
application/json:
schema:
$ref: "#/components/schemas/QuestionBank"
"404":
description: Question Bank not found
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: get_question_bank
patch:
tags:
- Assessment Question Banks
summary: Update Question Bank
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: Question Bank ID
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/QuestionBankUpdate"
responses:
"200":
description: Question Bank updated successfully
content:
application/json:
schema:
$ref: "#/components/schemas/QuestionBank"
"404":
description: Question Bank not found
'422':
$ref: '#/components/responses/UnprocessableEntity'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: update_question_bank
delete:
tags:
- Assessment Question Banks
summary: Delete Question Bank
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: Question Bank ID
responses:
"200":
description: Question Bank deleted successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Message'
"404":
description: Question Bank not found
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: delete_question_bank
/assessments/questionBank/{id}/questions:
get:
tags:
- Assessment Question Banks
summary: List Questions in Question Bank
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: Question Bank ID
- in: query
name: timestampModifiedBefore
schema:
type: string
format: date-time
pattern: '^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}:\d{2})?$'
example: "2023-01-12 15:30:00"
description: "Filter to questions whose timestamp_modified (the question bank's modified timestamp, shared by all its questions) is before this datetime. Format: YYYY-MM-DD HH:MM:SS (date-only YYYY-MM-DD also accepted)."
- in: query
name: timestampModifiedAfter
schema:
type: string
format: date-time
pattern: '^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}:\d{2})?$'
example: "2023-01-12 15:30:00"
description: "Filter to questions whose timestamp_modified (the question bank's modified timestamp, shared by all its questions) is after this datetime. Format: YYYY-MM-DD HH:MM:SS (date-only YYYY-MM-DD also accepted)."
- in: query
name: page
schema:
type: integer
minimum: 1
description: Page number for pagination
- in: query
name: pageSize
schema:
type: integer
enum: [10, 25, 50, 100, 250]
description: Number of results per page
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Question"
"404":
description: Question Bank not found
'422':
$ref: '#/components/responses/UnprocessableEntity'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: list_questions_in_question_bank
post:
tags:
- Assessment Question Banks
summary: Create Multiple Questions in Question Bank (Batch)
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: Question Bank ID
requestBody:
content:
application/json:
schema:
type: object
required:
- questions
properties:
questions:
type: array
items:
$ref: "#/components/schemas/QuestionCreate"
responses:
"201":
description: Questions created successfully
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: "5 questions created"
question_ids:
type: array
items:
type: integer
"404":
description: Question Bank not found
'422':
$ref: '#/components/responses/UnprocessableEntity'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_multiple_questions_in_question_bank_batch
/assessments/questionBank/{id}/question:
post:
tags:
- Assessment Question Banks
summary: Create Single Question in Question Bank
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: Question Bank ID
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/QuestionCreate"
responses:
"201":
description: Question created successfully
content:
application/json:
schema:
$ref: "#/components/schemas/Question"
"404":
description: Question Bank not found
# ==========================================
# Assessment Questions
# ==========================================
'422':
$ref: '#/components/responses/UnprocessableEntity'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_single_question_in_question_bank
/assessments/question:
post:
tags:
- Assessment Questions
summary: Create Question (Independent)
description: Create a question with either assessment_id or question_bank_id (mutually exclusive, one required)
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/QuestionCreateIndependent"
responses:
"201":
description: Question created successfully
content:
application/json:
schema:
$ref: "#/components/schemas/Question"
"400":
description: Neither assessment_id nor question_bank_id was supplied.
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'422':
$ref: '#/components/responses/UnprocessableEntity'
operationId: create_question_independent
/assessments/questions:
get:
tags:
- Assessment Questions
summary: List Questions
description: List all questions (excludes orphaned questions with both IDs null)
parameters:
- in: query
name: assessmentId
schema:
type: integer
description: Filter by assessment ID
- in: query
name: questionBankId
schema:
type: integer
description: Filter by question bank ID
- in: query
name: typeId
schema:
type: integer
description: Filter by question type ID
- in: query
name: timestampModifiedBefore
schema:
type: string
format: date-time
pattern: '^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}:\d{2})?$'
example: "2023-01-12 15:30:00"
description: "Filter to questions whose timestamp_modified (the parent assessment / question bank's modified timestamp) is before this datetime. Format: YYYY-MM-DD HH:MM:SS (date-only YYYY-MM-DD also accepted)."
- in: query
name: timestampModifiedAfter
schema:
type: string
format: date-time
pattern: '^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}:\d{2})?$'
example: "2023-01-12 15:30:00"
description: "Filter to questions whose timestamp_modified (the parent assessment / question bank's modified timestamp) is after this datetime. Format: YYYY-MM-DD HH:MM:SS (date-only YYYY-MM-DD also accepted)."
- in: query
name: page
schema:
type: integer
minimum: 1
description: Page number for pagination
- in: query
name: pageSize
schema:
type: integer
enum: [10, 25, 50, 100, 250]
description: Number of results per page
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Question"
'422':
$ref: '#/components/responses/UnprocessableEntity'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: list_questions
/assessments/question/{id}:
get:
tags:
- Assessment Questions
summary: Get Question
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: Question ID
responses:
"200":
description: Successful Response
content:
application/json:
schema:
$ref: "#/components/schemas/Question"
"404":
description: Question not found
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: get_question
patch:
tags:
- Assessment Questions
summary: Update Question
description: Update question properties (cannot change assessment_id or question_bank_id)
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: Question ID
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/QuestionUpdate"
responses:
"200":
description: Question updated successfully
content:
application/json:
schema:
$ref: "#/components/schemas/Question"
"404":
description: Question not found
'422':
$ref: '#/components/responses/UnprocessableEntity'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: update_question
delete:
tags:
- Assessment Questions
summary: Remove Question from Container
description: Clears the active parent ID (question_bank_id or assessment_id), orphaning the question
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: Question ID
responses:
"200":
description: Question removed from container successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Message'
"404":
description: Question not found
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: remove_question_from_container
/assessments/question/{id}/choices:
get:
tags:
- Assessment Questions
summary: List Question Choices
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: Question ID
responses:
"200":
description: Successful Response
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/QuestionChoice"
"404":
description: Question not found
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: list_question_choices
/assessments/question/{id}/choice:
post:
tags:
- Assessment Questions
summary: Create Question Choice
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: Question ID
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/QuestionChoiceCreate"
responses:
"201":
description: Choice created successfully
content:
application/json:
schema:
$ref: "#/components/schemas/QuestionChoice"
"404":
description: Question not found
'422':
$ref: '#/components/responses/UnprocessableEntity'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_question_choice
/assessments/question/{questionId}/choice/{choiceId}:
patch:
tags:
- Assessment Questions
summary: Update Question Choice
parameters:
- in: path
name: questionId
schema:
type: integer
required: true
description: Question ID
- in: path
name: choiceId
schema:
type: integer
required: true
description: Choice ID
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/QuestionChoiceUpdate"
responses:
"200":
description: Choice updated successfully
content:
application/json:
schema:
$ref: "#/components/schemas/QuestionChoice"
"404":
description: Question or Choice not found
'422':
$ref: '#/components/responses/UnprocessableEntity'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: update_question_choice
delete:
tags:
- Assessment Questions
summary: Delete Question Choice
parameters:
- in: path
name: questionId
schema:
type: integer
required: true
description: Question ID
- in: path
name: choiceId
schema:
type: integer
required: true
description: Choice ID
responses:
"200":
description: Choice deleted successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Message'
"404":
description: Question or Choice not found
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: delete_question_choice
/assessments/assessment/{id}/question:
post:
tags:
- Assessments
summary: Create Single Question in Assessment
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: Assessment ID
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/QuestionCreate"
responses:
"201":
description: Question created successfully
content:
application/json:
schema:
$ref: "#/components/schemas/Question"
"404":
description: Assessment not found
'422':
$ref: '#/components/responses/UnprocessableEntity'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_single_question_in_assessment
/assessments/assessment/{id}/questions:
post:
tags:
- Assessments
summary: Create Multiple Questions in Assessment (Batch)
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: Assessment ID
requestBody:
content:
application/json:
schema:
type: object
required:
- questions
properties:
questions:
type: array
items:
$ref: "#/components/schemas/QuestionCreate"
responses:
"201":
description: Questions created successfully
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: "5 questions created"
question_ids:
type: array
items:
type: integer
"404":
description: Assessment not found
'422':
$ref: '#/components/responses/UnprocessableEntity'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_multiple_questions_in_assessment_batch
/reports/checklists:
get:
tags:
- Reports
summary: Get metrics on number of checklists started and completed
description: |-
Requires a date range (maximum 1 year), groupBy is optional.
For example
`?groupBy=usergroup` will result in
```
{
"18": {
"group_title": "Usergroup A",
"started_count": 42,
"completed_count": 12
}
}
```
Date ranges over one year are rejected with HTTP 200 and a body of {"errors": ["Max date range is one year"]}.
parameters:
- in: query
name: groupBy
schema:
type: string
example: user, usergroup, checklist
enum:
- user
- usergroup
- checklist
- in: query
name: startDate
schema:
type: string
example: 2024-01-01
required: true
- in: query
name: endDate
schema:
type: string
example: 2024-12-01
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
oneOf:
- $ref: "#/components/schemas/ReportsChecklists"
- $ref: "#/components/schemas/ReportsChecklistsGroupedByUser"
- $ref: "#/components/schemas/ReportsChecklistsGroupedByUsergroup"
- $ref: "#/components/schemas/ReportsChecklistsGroupedByChecklist"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: get_metrics_on_number_of_checklists_started_and_completed
/reports/courses:
get:
tags:
- Reports
summary: Get metrics on number of courses started and completed
description: |-
Requires a date range (maximum 1 year), groupBy is optional.
For example
`?groupBy=usergroup` will result in
```
{
"18": {
"group_title": "Usergroup A",
"started_count": 42,
"completed_count": 12
}
}
```
Date ranges over one year are rejected with HTTP 200 and a body of {"errors": ["Max date range is one year"]}.
parameters:
- in: query
name: groupBy
schema:
type: string
example: user, usergroup, course
enum:
- user
- usergroup
- course
- in: query
name: startDate
schema:
type: string
example: 2024-01-01
required: true
- in: query
name: endDate
schema:
type: string
example: 2024-12-01
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
oneOf:
- $ref: "#/components/schemas/ReportsCourses"
- $ref: "#/components/schemas/ReportsCoursesGroupedByUser"
- $ref: "#/components/schemas/ReportsCoursesGroupedByUsergroup"
- $ref: "#/components/schemas/ReportsCoursesGroupedByCourse"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: get_metrics_on_number_of_courses_started_and_completed
/reports/users:
get:
tags:
- Reports
summary: Get metrics on number of active users and user logins
parameters:
- in: query
name: groupBy
schema:
type: string
example: usergroup
enum:
- usergroup
- in: query
name: startDate
schema:
type: string
example: 2024-01-01
required: true
- in: query
name: endDate
schema:
type: string
example: 2024-12-01
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
oneOf:
- $ref: "#/components/schemas/ReportsUsers"
- $ref: "#/components/schemas/ReportsUsersGroupedByUsergroup"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
description: 'Date ranges over one year are rejected with HTTP 200 and a body of {"errors": ["Max date range is one year"]}.'
operationId: get_metrics_on_number_of_active_users_and_user_logins
/submitQuiz:
post:
tags:
- Quizzes
summary: Submit quiz answers
requestBody:
content:
application/json:
schema:
type: object
$ref: "#/components/schemas/QuizResponsePayload"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
type: object
properties:
attempt:
type: integer
result:
$ref: '#/components/schemas/QuizResult'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: submit_quiz_answers
/subscription:
post:
tags:
- Subscriptions
summary: Create Subscription
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Subscription"
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Subscription"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_subscription
/subscription/{id}:
get:
tags:
- Subscriptions
summary: Read Subscription
#TODO add parameters for updating user groups
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Subscription"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_subscription
patch:
tags:
- Subscriptions
summary: Edit Subscription
#TODO add parameters for updating user groups
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SubscriptionUpdate'
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Subscription"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: edit_subscription
delete:
tags:
- Subscriptions
summary: Delete Subscription
#TODO add parameters for updating user groups
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_subscription
/subscriptions:
get:
tags:
- Subscriptions
summary: Read Subscriptions
parameters:
- in: query
name: subscriptionIds
schema:
type: string
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
- in: query
name: title
required: false
schema:
type: string
description: Filter by subscription title. Exact match unless % wildcards are included.
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Subscription"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_subscriptions
/subscription/{id}/subscribe:
post:
tags:
- Subscriptions
summary: Subscribe User(s) to a Subscription Plan
description: |
Subscribe one or more existing users to a subscription plan. Users must already exist in the system.
## Free subscriptions (default)
Omit the body entirely. `userIds` may contain one OR many ids — each user is subscribed to the plan in a single call. The plan must have `default_amount == 0.00`; otherwise the call returns 400.
Each subscription is created with a covering period derived from the plan's configuration: `period_start`/`period_end` from the request body win when supplied; otherwise the period runs from now until now + the plan's `default_sub_length` (or until the plan's fixed-term end date). A plan with no configured length (or a lifetime fixed-term plan) yields an open-ended lifetime period. This period drives the subscription's timeframe on the LMS User Manager timeline and its expiration by the daily cron.
## Paid subscriptions (single-user only)
When `gateway_transaction_id` is supplied in the request body, this endpoint records an externally-processed payment (e.g. Stripe `payment_intent_id`) alongside subscribing the user. This is the only way to register a user on a paid plan from this endpoint.
**In paid mode, `userIds` MUST contain exactly one id.** Multi-user calls are rejected with 400 — one gateway transaction cannot be split across multiple subscribers, so each paid signup is its own request. For subsequent (renewal) payments on an existing subscription, use `POST /v1/user/{userId}/subscription/{subId}/payment` instead.
Additional requirements when supplying `gateway_transaction_id`:
- Caller must hold one of: `all`, `all:create`, `payments:all`, `payments:create` (in addition to the subscribe permissions).
- `amount`, `paid_at`, and `currency` are required alongside `gateway_transaction_id`.
- The subscription is created in `INAC` state and flipped to `ACT` only after the payment row commits successfully. The subscription save and the payment recording run in a single `tovuti_rds` transaction — if recording fails, the subscription is rolled back.
- `gateway_transaction_id` must be globally unique across this tenant's `axs_pay_transactions.trxn_id`.
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: Subscription plan id. Must be numeric.
requestBody:
required: true
description: |
`userIds` is always required (as an **array**, even for a single user). When supplying `gateway_transaction_id` (paid flow), `userIds` must contain exactly one id and the four payment fields are also required. See `SubscribeRequest` for the full shape.
content:
application/json:
schema:
$ref: "#/components/schemas/SubscribeRequest"
responses:
"200":
description: Successful Response. When paid, the body includes `subscription_id` and `payment_id`.
content:
application/json:
schema:
$ref: '#/components/schemas/SubscribeResult'
"400":
description: Validation failure (missing/empty `userIds`, plan is paid but no `gateway_transaction_id` supplied, `userIds` has more than one entry in paid mode, user already subscribed, `gateway_transaction_id` already used globally, etc.).
"403":
description: Forbidden — token lacks the required permissions. Paid mode additionally requires one of `payments:create`/`payments:all`/`all:create`/`all`.
"404":
description: Subscription plan not found.
"409":
description: "`gateway_transaction_id` already recorded against a different subscription or purchase type (paid mode only)."
'401':
$ref: '#/components/responses/Unauthorized'
operationId: subscribe_user_s_to_a_subscription_plan
/subscription/{id}/unsubscribe:
post:
tags:
- Subscriptions
summary: Unsubscribe User(s) from a Subscription Plan
description: Only free subscriptions are supported at this time.
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: Subscription plan id. Must be numeric.
requestBody:
required: true
description: |
`userIds` is an array (always — even for a single user) of LMS user ids to unsubscribe.
content:
application/json:
schema:
type: object
required: [userIds]
properties:
userIds:
type: array
minItems: 1
items:
type: integer
example: [1620265, 1620266]
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: unsubscribe_user_s_from_a_subscription_plan
/survey/{id}:
get:
tags:
- Surveys
summary: Read Survey
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Survey"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_survey
/surveys:
get:
tags:
- Surveys
summary: Read Surveys
parameters:
- in: query
name: surveyIds
schema:
type: string
description: Comma-separated list of survey IDs
- in: query
name: title
schema:
type: string
description: Filter by title (supports LIKE matching) Exact match unless % wildcards are included.
- in: query
name: enabled
schema:
type: boolean
description: Filter by enabled status
- in: query
name: createdBefore
schema:
type: string
format: date
description: Filter by surveys created before this date (YYYY-MM-DD)
- in: query
name: createdAfter
schema:
type: string
format: date
description: Filter by surveys created after this date (YYYY-MM-DD)
- in: query
name: modifiedBefore
schema:
type: string
format: date
description: Filter by surveys modified before this date (YYYY-MM-DD)
- in: query
name: modifiedAfter
schema:
type: string
format: date
description: Filter by surveys modified after this date (YYYY-MM-DD)
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: '#/components/parameters/pageParam'
- in: query
$ref: '#/components/parameters/pageSizeParam'
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Survey"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_surveys
/surveyResponse:
post:
tags:
- Surveys
summary: Create Survey Response
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/SurveyResponse"
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SurveyResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
description: lesson_id and activity_id are required unless event_id is supplied; supplying event_id together with either returns 400.
operationId: create_survey_response
/surveyResponses:
get:
tags:
- Surveys
summary: Read Survey Responses
parameters:
- in: query
name: userId
schema:
type: integer
- in: query
name: surveyId
schema:
type: integer
- in: query
name: lessonId
schema:
type: integer
- in: query
name: activityId
schema:
type: string
- in: query
name: eventId
schema:
type: integer
- in: query
name: questionId
schema:
type: string
- in: query
name: archived
schema:
type: boolean
- in: query
$ref: "#/components/parameters/timestampCreatedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampCreatedAfterParam"
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/SurveyResponse"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_survey_responses
post:
tags:
- Surveys
summary: Create Survey Responses
requestBody:
content:
application/json:
schema:
type: object
properties:
responses:
type: array
items:
$ref: "#/components/schemas/SurveyResponse"
required:
- responses
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/SurveyResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
description: lesson_id and activity_id are required unless event_id is supplied; supplying event_id together with either returns 400.
operationId: create_survey_responses
/team:
post:
tags:
- Teams
summary: Create User Team
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Team"
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/Team'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_user_team
/team/{id}:
get:
tags:
- Teams
summary: Read User Team
parameters:
- in: path
name: id
schema:
type: integer
required: true
- in: query
$ref: "#/components/parameters/excludeTeamParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/Team'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_user_team
patch:
tags:
- Teams
summary: Update User Team
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/TeamUpdate'
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/Team"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_user_team
delete:
tags:
- Teams
summary: Delete User Team
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_user_team
/teams:
get:
tags:
- Teams
summary: Read User Teams
parameters:
- in: query
$ref: "#/components/parameters/teamIdsParam"
- in: query
name: title
schema:
type: string
description: Filter by title. Exact match unless % wildcards are included.
- in: query
name: memberType
schema:
type: string
enum: [individuals, groups]
example: individuals, groups
- in: query
name: createdBefore
schema:
type: string
format: date
- in: query
name: createdAfter
schema:
type: string
format: date
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
- in: query
$ref: "#/components/parameters/excludeTeamParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Team"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_user_teams
/transactions:
get:
tags:
- Transactions
summary: Read Transactions
parameters:
- in: query
name: id
schema:
type: integer
- in: query
name: axsTransactionId
schema:
type: integer
- in: query
name: productName
schema:
type: string
- in: query
name: productType
schema:
type: string
- in: query
name: transactorName
schema:
type: string
- in: query
name: transactorId
schema:
type: integer
- in: query
name: transactorType
schema:
type: string
- in: query
name: purchaserId
schema:
type: integer
- in: query
name: purchaserName
schema:
type: string
- in: query
name: payInstrumentName
schema:
type: string
- in: query
name: payInstrumentType
schema:
type: string
enum:
- credit card
- invoice
- purchase order
- external
description: "Filter by pay instrument type. Exact match on the type label."
- in: query
name: orderAmount
schema:
type: number
- in: query
name: exitStatus
schema:
type: string
- in: query
name: transactionType
schema:
type: string
- in: query
name: before
schema:
type: string
format: date
- in: query
name: after
schema:
type: string
format: date
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Transaction"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_transactions
/user:
post:
tags:
- Users
summary: Create User
description: userTeamIds can only be assigned for teams with member_type = 'individuals'.
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/UserPayload"
responses:
'201':
description: Successfully created users.
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_user
/user/{id}:
get:
tags:
- Users
summary: Read User
parameters:
- in: path
name: id
schema:
type: integer
required: true
- in: query
name: exclude
description: >
Comma-separated list of referenced datasets to omit from the response.
All are included by default; excluding one both drops it from the
payload and skips the query used to build it. Allowed values:
`customFields`, `objects`, `enrolledCourseIds`, `userTeamIds`.
Excluded custom field values can be fetched independently via
GET /metadata/customFields/values?objectType=users; excluded objects
via GET /objects; excluded enrollments via GET /user/{id}/courseProgress;
excluded team membership via GET /teams.
schema:
type: string
example: customFields,objects,enrolledCourseIds,userTeamIds
responses:
"200":
description: Successfully created user
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_user
patch:
tags:
- Users
summary: Update User
description: UserTeamIds can only be assigned for teams with member_type = 'individuals'.
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UserPayloadUpdate'
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_user
delete:
tags:
- Users
summary: Delete User
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successfully deleted users.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_user
/user/{id}/communityGroups:
get:
tags:
- Users
summary: Read User Community Groups
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/CommunityGroupIds"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_user_community_groups
patch:
tags:
- Users
summary: Update User Community Groups
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/CommunityGroupIds"
required:
- community_groups
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/CommunityGroupIds"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_user_community_groups
/user/{id}/awards:
get:
tags:
- Users
summary: Read User's Earned Awards
parameters:
- in: path
name: id
schema:
type: integer
required: true
- in: query
$ref: "#/components/parameters/awardTitleParam"
- in: query
$ref: "#/components/parameters/awardTypeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/AwardEarned"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_user_s_earned_awards
/user/{userId}/award/{awardId}:
patch:
tags:
- Users
summary: Update a user's earned award
parameters:
- in: path
name: userId
schema:
type: integer
required: true
- in: path
name: awardId
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/AwardEarned"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/AwardEarned'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
description: '{awardId} is the award-earned row id from GET /users/awards, not the award id. {userId} is existence-checked but does not scope the lookup.'
operationId: update_a_user_s_earned_award
/user/{id}/courseProgress:
get:
tags:
- Users
summary: Read User Course Progress
parameters:
- in: path
name: id
schema:
type: integer
required: true
- in: query
name: lessonId
description: Filter by Lesson Id.
schema:
type: integer
- in: query
name: courseId
description: Filter by Course Id.
schema:
type: integer
- in: query
name: archived
description: If true, show only archived data.
schema:
type: boolean
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/UserCourseProgress"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_user_course_progress
/user/{id}/subscriptions:
get:
tags:
- Users
summary: List User Subscriptions
description: Retrieve a paginated list of subscriptions for a specific user.
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: The ID of the user.
- in: query
schema:
type: integer
name: planId
description: Retrieve all subscriptions for this plan id
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/UserSubscription"
"404":
description: User not found.
"500":
description: Internal Server Error.
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: list_user_subscriptions
/user/{id}/subscription/{subscriptionId}:
get:
tags:
- Users
summary: Get User Subscription Plan
description: Retrieve the subscription plan details for a specified user and plan ID.
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: The ID of the user.
- in: path
name: subscriptionId
schema:
type: integer
required: true
description: The ID of the users subscription.
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
type: object
properties:
id:
type: integer
description: ID of the users subscription
userId:
type: integer
description: The ID of the user.
cancel_date:
type: string
description: The date the subscription was cancelled
planId:
type: integer
description: The ID of the subscription plan.
status:
type: string
description: Active or Inactive status
next_payment_date:
type: string
description: The next date the user will be charged, if applicable.
recurring_amount:
type: string
description: The amount the user will be charged on the next payment date, if applicable.
period_length:
type: string
description: How often the subscription renews or ends for the user.
"404":
description: The user or subscription plan was not found.
"500":
description: Internal Server Error.
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: get_user_subscription_plan
patch:
tags:
- Users
summary: Update User Subscription Plan
description: Update the subscription plan details for a specific user and plan ID.
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: The ID of the user.
- in: path
name: subscriptionId
schema:
type: integer
required: true
description: The ID of the subscription plan.
requestBody:
description: The fields to update for the subscription plan.
required: true
content:
application/json:
schema:
type: object
properties:
next_payment_date:
type: string
format: date
description: The updated start date for the subscription.
responses:
"200":
description: Successfully updated the subscription plan.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
description: Status of the update operation.
message:
type: string
description: Additional information about the update process.
"400":
description: Invalid request body or parameters.
"404":
description: User or subscription plan not found.
"500":
description: Internal Server Error.
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: update_user_subscription_plan
/user/{userId}/subscription/{subId}/payment:
post:
tags:
- Payments
summary: Record Subscription Payment
description: |
Record a payment that was processed externally (e.g. via Stripe) against a user's subscription. Creates a row in `axs_pay_transactions` and the matching `hybrid_order` / `hybrid_order_item` / `hybrid_transaction` rows, then marks the subscription period `PAID`.
Idempotent on `gateway_transaction_id`: replaying the same payload returns the existing record with `200` instead of `201`. A payload that collides with a different subscription's existing payment returns `409`.
parameters:
- in: path
name: userId
schema:
type: integer
required: true
description: The ID of the LMS user.
- in: path
name: subId
schema:
type: integer
required: true
description: The subscription ID (axs_pay_subscriptions.id).
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SubscriptionPaymentCreate"
responses:
"201":
description: Payment recorded.
content:
application/json:
schema:
$ref: "#/components/schemas/SubscriptionPayment"
"200":
description: Idempotent replay — the same `gateway_transaction_id` was already recorded for this user and subscription.
content:
application/json:
schema:
$ref: "#/components/schemas/SubscriptionPayment"
"400":
description: Validation failure (missing fields, `gateway_transaction_id` already used globally, etc).
"403":
description: Forbidden — token lacks `payments:create`.
"404":
description: Subscription not found for the given user.
"409":
description: "`gateway_transaction_id` already recorded against a different subscription or purchase type."
"500":
description: External pay instrument singleton not seeded in this client database. Run the LMS migration that adds `hybrid_pay_instrument_type` id=4 and the matching `hybrid_pay_instrument` row.
'401':
$ref: '#/components/responses/Unauthorized'
operationId: record_subscription_payment
/user/{userId}/subscription/{subId}/payments:
get:
tags:
- Payments
summary: List Subscription Payments
description: |
Return payments recorded against a user's subscription. Pass `gateway_transaction_id` to look up by the external gateway reference (Stripe payment_intent_id, etc.) — useful when the caller stored only the gateway id and needs to retrieve the Tovuti payment id for subsequent PATCH/DELETE calls.
Includes voided (`status: PLHO`) payments; filter client-side if you only want successful ones.
parameters:
- in: path
name: userId
schema:
type: integer
required: true
- in: path
name: subId
schema:
type: integer
required: true
- in: query
name: gatewayTransactionId
schema:
type: string
description: Exact-match filter on the external gateway reference. Returns 0 or 1 result.
example: pi_3O8aBcDeFgHiJk001
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
type: object
description: 'This endpoint builds its envelope by hand: only data, current_page, per_page, from and to are returned (plus total and last_page when includeTotal=true). No page URLs.'
properties:
data:
type: array
items:
$ref: '#/components/schemas/SubscriptionPayment'
current_page:
type: integer
per_page:
type: integer
from:
type: integer
nullable: true
to:
type: integer
nullable: true
total:
type: integer
nullable: true
last_page:
type: integer
nullable: true
"403":
description: Forbidden — token lacks `payments:read`.
"404":
description: Subscription not found for the given user.
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
operationId: list_subscription_payments
/user/{userId}/subscription/{subId}/payment/{id}:
get:
tags:
- Payments
summary: Read Subscription Payment
parameters:
- in: path
name: userId
schema:
type: integer
required: true
- in: path
name: subId
schema:
type: integer
required: true
- in: path
name: id
schema:
type: integer
required: true
description: The `hybrid_transaction.id` returned by Create or List.
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/SubscriptionPayment"
"400":
description: Record exists but is not a subscription payment.
"403":
description: Forbidden — token lacks `payments:read`.
"404":
description: Payment not found, does not belong to the given user, or does not belong to the given subscription.
'401':
$ref: '#/components/responses/Unauthorized'
operationId: read_subscription_payment
patch:
tags:
- Payments
summary: Correct Subscription Payment
description: |
Correct one or more fields on a recorded payment. All body fields are optional; only the fields supplied are updated.
Only payments with status `SUC` can be corrected. To reverse a payment, use DELETE (void).
parameters:
- in: path
name: userId
schema:
type: integer
required: true
- in: path
name: subId
schema:
type: integer
required: true
- in: path
name: id
schema:
type: integer
required: true
description: The `hybrid_transaction.id`.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SubscriptionPaymentUpdate"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/SubscriptionPayment"
"400":
description: Validation failure.
"403":
description: Forbidden — token lacks `payments:update`.
"404":
description: Payment not found.
"409":
description: Payment is voided or otherwise not in a correctable state.
'401':
$ref: '#/components/responses/Unauthorized'
operationId: correct_subscription_payment
delete:
tags:
- Payments
summary: Void Subscription Payment
description: |
Void a payment. Soft-delete: rows remain. The payment status becomes `Voided` (`axs_pay_transactions.status = PLHO`), the `hybrid_order` / `hybrid_order_item` / `hybrid_transaction` rows are marked FAIL, and the subscription period reverts from `Paid` (`PAID`) to `Unpaid` (`NONE`). The new period status is visible on `GET /v1/user/{userId}/subscription/{subId}` in the `periods[]` array.
A second DELETE on the same payment returns 409.
parameters:
- in: path
name: userId
schema:
type: integer
required: true
- in: path
name: subId
schema:
type: integer
required: true
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Payment voided.
content:
application/json:
schema:
$ref: "#/components/schemas/SubscriptionPayment"
"403":
description: Forbidden — token lacks `payments:delete`.
"404":
description: Payment not found.
"409":
description: Payment is already voided, or has been refunded and cannot be voided.
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
operationId: void_subscription_payment
/users:
get:
tags:
- Users
summary: Read Users
description: All parameters can be used in either the query or the request body.
parameters:
- in: query
name: exclude
description: >
Comma-separated list of referenced datasets to omit from the response.
All are included by default; excluding one both drops it from the
payload and skips the query used to build it. Allowed values:
`customFields`, `objects`, `enrolledCourseIds`, `userTeamIds`.
Excluded custom field values can be fetched independently via
GET /metadata/customFields/values?objectType=users; excluded objects
via GET /objects; excluded enrollments via GET /user/{id}/courseProgress;
excluded team membership via GET /teams.
schema:
type: string
example: customFields,objects,enrolledCourseIds,userTeamIds
- in: query
$ref: "#/components/parameters/userIdsParam"
- in: query
name: name
schema:
type: string
description: Search by user name.
- in: query
name: email
schema:
type: string
description: Search by user email.
- in: query
name: status
schema:
type: string
enum:
- active
- disabled
description: Search by user status (active/disabled) status.
- in: query
$ref: "#/components/parameters/objectIdsParam"
- in: query
name: objectTitle
schema:
type: string
description: Search Object Title associated to user.
- in: query
name: registeredBefore
schema:
type: string
format: date
- in: query
name: registeredAfter
schema:
type: string
format: date
- in: query
name: lastVisitedBefore
schema:
type: string
format: date
- in: query
name: lastVisitedAfter
schema:
type: string
format: date
- in: query
$ref: "#/components/parameters/groupIdsParam"
- in: query
$ref: "#/components/parameters/teamIdsParam"
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
- in: query
$ref: "#/components/parameters/customFieldsParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/User"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_users
/users/awards:
get:
tags:
- Users
summary: Read User Awards
parameters:
- in: query
$ref: "#/components/parameters/userNameParam"
- in: query
$ref: "#/components/parameters/awardTitleParam"
- in: query
$ref: "#/components/parameters/awardTypeParam"
- in: query
$ref: "#/components/parameters/userIdsParam"
- in: query
$ref: "#/components/parameters/groupIdsParam"
- in: query
$ref: "#/components/parameters/teamIdsParam"
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/AwardEarned"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_user_awards
/users/awards/{id}:
delete:
tags:
- Users
summary: Delete User Awards
parameters:
- in: path
schema:
type: integer
name: id
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
type: object
example: {"success": "AwardEarned id = {$id} deleted"}
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
description: '{id} is the award-earned row id from GET /users/awards, not the award id.'
operationId: delete_user_awards
/users/checklistProgress:
get:
tags:
- Users
summary: Read User Checklist Progress
parameters:
- in: query
$ref: "#/components/parameters/userNameParam"
- in: query
$ref: "#/components/parameters/userIdsParam"
- in: query
$ref: "#/components/parameters/groupIdsParam"
- in: query
$ref: "#/components/parameters/teamIdsParam"
- in: query
name: archived
description: If true, show only archived data.
schema:
type: boolean
- in: query
name: assignedBefore
description: Include only records whose assigned_date is on or before this date (YYYY-MM-DD).
schema:
type: string
format: date
- in: query
name: assignedAfter
description: Include only records whose assigned_date is on or after this date (YYYY-MM-DD).
schema:
type: string
format: date
- in: query
name: sortBy
description: >
Field to sort results by. `assigned_date` orders by the checklist's
assigned date. `timestampModified` orders by the progress record's
last-modified timestamp (the column the `timestampModifiedBefore` /
`timestampModifiedAfter` filters compare against) with the record id
as a tie-breaker, so results are stable when paging. Required
whenever `sortDir` is supplied.
schema:
type: string
enum:
- assigned_date
- timestampModified
- in: query
name: sortDir
description: >
Sort direction. The default depends on `sortBy`: `asc` for
`assigned_date`, `desc` for `timestampModified`. Only valid together
with `sortBy`; a request that sends `sortDir` on its own is rejected
with HTTP 400.
schema:
type: string
enum:
- asc
- desc
- in: query
$ref: "#/components/parameters/timestampCreatedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampCreatedAfterParam"
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/ChecklistProgress"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_user_checklist_progress
/users/courseProgress:
get:
tags:
- Users
summary: Read Users Course Progress
parameters:
- in: query
$ref: "#/components/parameters/courseTitleParam"
- in: query
$ref: "#/components/parameters/courseEnabledParam"
- in: query
$ref: "#/components/parameters/userNameParam"
- in: query
$ref: "#/components/parameters/userIdsParam"
- in: query
$ref: "#/components/parameters/groupIdsParam"
- in: query
$ref: "#/components/parameters/teamIdsParam"
- in: query
name: archived
description: If true, show only archived data.
schema:
type: boolean
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
- in: query
name: startedBefore
schema:
type: string
format: date
- in: query
name: startedAfter
schema:
type: string
format: date
- in: query
name: lastActivityBefore
schema:
type: string
- in: query
name: lastActivityAfter
schema:
type: string
- in: query
name: completedBefore
schema:
type: string
- in: query
name: completedAfter
schema:
type: string
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/CourseProgress"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_users_course_progress
/users/events:
get:
tags:
- Users
summary: Read User Event Registrations
parameters:
- in: query
$ref: "#/components/parameters/userNameParam"
- in: query
$ref: "#/components/parameters/eventTitleParam"
- in: query
$ref: "#/components/parameters/userIdsParam"
- in: query
$ref: "#/components/parameters/groupIdsParam"
- in: query
$ref: "#/components/parameters/teamIdsParam"
- in: query
$ref: "#/components/parameters/eventIdsParam"
- in: query
$ref: "#/components/parameters/timestampCreatedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampCreatedAfterParam"
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/EventRegistration"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_user_event_registrations
/users/quizResults:
get:
deprecated: true
tags:
- Users
summary: "Read Quiz Results - Deprecated, use /assessments/results instead"
parameters:
- in: query
name: ids
schema:
type: string
description: Comma separated list of ids for the quiz result.
- in: query
name: quizIds
schema:
type: string
description: Comma separated list of quiz ids.
- in: query
$ref: "#/components/parameters/userNameParam"
- in: query
$ref: "#/components/parameters/userIdsParam"
- in: query
$ref: "#/components/parameters/groupIdsParam"
- in: query
$ref: "#/components/parameters/teamIdsParam"
- in: query
name: archived
description: If true, show only archived data.
schema:
type: boolean
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
- in: query
name: lessonId
schema:
type: integer
- in: query
name: submittedBefore
schema:
type: string
- in: query
name: submittedAfter
schema:
type: string
- in: query
name: timestampCreatedBefore
schema:
type: string
format: date
description: "Filter by timestamp_created before this date (YYYY-MM-DD)"
- in: query
name: timestampCreatedAfter
schema:
type: string
format: date
description: "Filter by timestamp_created after this date (YYYY-MM-DD)"
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
- in: query
name: lessonTitle
required: false
schema:
type: string
description: Filter by lesson title.
- in: query
name: courseTitle
required: false
schema:
type: string
description: Filter by course title.
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/QuizResult"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_quiz_results_deprecated_use_assessments_results_instead
/users/sendWelcomeEmail:
post:
tags:
- Users
summary: Send Welcome Emails
description: >
When sending the Welcome Email, a new system-generated password will be
sent and, upon logging in, the user will be prompted to reset their
password.
parameters:
- in: query
name: userIds
required: true
schema:
type: array
items:
type: integer
example: [1620265, 1620266, 1620265]
- in: query
name: requirePasswordReset
schema:
type: boolean
description: Defaults to true, if not explicitly set
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
users:
type: array
items:
type: integer
description: Ids of the users emailed.
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: send_welcome_emails_when_sending_the_welcome_email_a_new_system_generated_password_will_be_sent_and_upon_logging_in_the_user_will_be_prompted_to_reset_their_password
/userGroup:
post:
tags:
- User Groups
summary: Create User Group
requestBody:
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/UserGroup"
required:
- title
- parent_id
responses:
'201':
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/UserGroup'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: create_user_group
/userGroup/{id}:
get:
tags:
- User Groups
summary: Read User Group
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/UserGroup"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_user_group
patch:
tags:
- User Groups
summary: Update User Group
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
type: object
$ref: "#/components/schemas/UserGroup"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: "#/components/schemas/UserGroup"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: update_user_group
delete:
tags:
- User Groups
summary: Delete User Group
description: "Delete a User Group via API.\n\nUser group ids 1, 2, 8, 20 and 32 are reserved and cannot be removed (403). Group id 8 is hidden from all user group endpoints."
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessMessage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: delete_user_group
/userGroup/{id}/users:
get:
tags:
- User Groups
summary: Read User Group's Users
description: Returns a paginated list of users belonging to the given user group.
parameters:
- in: path
name: id
schema:
type: integer
required: true
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/User"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
operationId: read_user_group_s_users
/userGroups:
get:
tags:
- User Groups
summary: Read User Groups
parameters:
- in: query
$ref: "#/components/parameters/groupIdsParam"
- in: query
$ref: "#/components/parameters/userIdsParam"
- in: query
name: title
schema:
type: string
description: Search by title of the user group. Exact match unless % wildcards are included.
- in: query
name: lft
schema:
type: integer
description: Start of the lft/rgt range. Required if rgt is present.
- in: query
name: rgt
schema:
type: integer
description: End of the lft/rgt range. Required if lft is present.
- in: query
name: parentId
schema:
type: integer
- in: query
$ref: "#/components/parameters/sortByParam"
- in: query
$ref: "#/components/parameters/sortDirParam"
- in: query
$ref: "#/components/parameters/pageParam"
- in: query
$ref: "#/components/parameters/pageSizeParam"
- in: query
$ref: "#/components/parameters/includeTotalParam"
- name: excludeUserIds
in: query
schema:
type: boolean
description: When true, omits the userIds array from the response to improve performance.
- in: query
$ref: "#/components/parameters/timestampModifiedBeforeParam"
- in: query
$ref: "#/components/parameters/timestampModifiedAfterParam"
responses:
"200":
description: Successful Response.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/PageData"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/UserGroup"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
operationId: read_user_groups
components:
parameters:
timestampCreatedBeforeParam:
name: timestampCreatedBefore
in: query
description: "Filter to records created before this datetime. Format: YYYY-MM-DD HH:MM:SS (date-only YYYY-MM-DD also accepted)."
schema:
type: string
format: date-time
pattern: '^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}:\d{2})?$'
example: "2023-01-12 15:30:00"
timestampCreatedAfterParam:
name: timestampCreatedAfter
in: query
description: "Filter to records created after this datetime. Format: YYYY-MM-DD HH:MM:SS (date-only YYYY-MM-DD also accepted)."
schema:
type: string
format: date-time
pattern: '^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}:\d{2})?$'
example: "2023-01-12 15:30:00"
timestampModifiedBeforeParam:
name: timestampModifiedBefore
in: query
description: "Filter to records last modified before this datetime. Format: YYYY-MM-DD HH:MM:SS (date-only YYYY-MM-DD also accepted). Compared inclusive of time against the raw timestamp value."
schema:
type: string
pattern: '^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}:\d{2})?$'
example: "2023-01-12 15:30:00"
timestampModifiedAfterParam:
name: timestampModifiedAfter
in: query
description: "Filter to records last modified after this datetime. Format: YYYY-MM-DD HH:MM:SS (date-only YYYY-MM-DD also accepted). Compared inclusive of time against the raw timestamp value."
schema:
type: string
pattern: '^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}:\d{2})?$'
example: "2023-01-12 15:30:00"
awardTitleParam:
name: awardTitle
in: query
description: Award title.
schema:
type: string
example: King of Sales
awardTypeParam:
name: awardType
in: query
description: Award type.
schema:
type: string
example: certificate
courseEnabledParam:
name: courseEnabled
in: query
description: Course is enabled? (0 for false 1 for true).
schema:
type: integer
example: 1
courseIdsParam:
name: courseIds
in: query
description: Course Ids.
schema:
type: string
example: 3,4,6
courseTitleParam:
name: courseTitle
in: query
description: Course Title.
schema:
type: string
example: Quantum gravity 101
customFieldsParam:
name: customFields
in: query
style: deepObject
explode: true
description: |
When querying Profile Fields you can use either field_id or title to specify the field value you want to query. % wildcard can be used in value key. Each entry requires value.
Serialized as indexed brackets. For example: "https://api.tovuti.io/api/v1/users?customFields[0][field_id]=44&customFields[0][value]=73958"
schema:
type: array
items:
$ref: '#/components/schemas/CustomFieldFilter'
eventIdsParam:
name: eventIds
in: query
description: Comma separated list of event ids
schema:
type: string
example: 1,2,3
eventTitleParam:
name: eventTitle
in: query
description: Event title.
schema:
type: string
example: The concept of art
groupIdsParam:
name: groupIds
in: query
description: Comma separated list of group ids.
schema:
type: string
example: 8,50,51
objectIdsParam:
name: objectIds
in: query
description: Comma separated list of object ids.
schema:
type: string
example: 8,50,51
pageParam:
name: page
in: query
description: Page number.
example: 1
schema:
type: integer
minimum: 1
default: 1
pageSizeParam:
name: pageSize
in: query
description: Page size, allowed values are 10,25,50,100,250.
example: 50
schema:
type: integer
enum:
- 10
- 25
- 50
- 100
- 250
default: 25
includeTotalParam:
name: includeTotal
in: query
description: >
When true, the response includes `total` (row count across all pages)
and `last_page`. Off by default because computing the count adds an
extra `COUNT(*)` query per request.
example: true
schema:
type: boolean
default: false
sortByParam:
name: sortBy
in: query
description: >
Sort the result set by this field. Allowed value: `timestampModified`,
which orders by the `timestamp_modified` value the endpoint returns on
each record and breaks ties on the record's primary key, so results are
stable when paging, and the `next_page_url` / `prev_page_url` links in
the response carry `sortBy` and `sortDir` forward. Records whose
`timestamp_modified` is null sort first under `asc` and last under
`desc`. When `sortBy` is omitted the endpoint returns rows in its
previous default order, which on most list endpoints is not guaranteed
to be consistent from one page to the next. Required whenever `sortDir`
is supplied.
schema:
type: string
enum:
- timestampModified
example: timestampModified
sortDirParam:
name: sortDir
in: query
description: >
Direction for `sortBy`: `asc` (oldest modification first) or `desc`
(most recently modified first). Defaults to `desc`. Only valid together
with `sortBy`; a request that sends `sortDir` on its own is rejected
with HTTP 400.
schema:
type: string
enum:
- asc
- desc
default: desc
example: desc
excludeParam:
name: exclude
in: query
description: >
Comma-separated list of referenced datasets to omit from the response.
All are included by default; excluding one both drops it from the payload
and skips the query/computation used to build it. Allowed value:
`customFields`. On the Events and Purchase Orders endpoints the response
key it removes is spelled `custom_fields`; the parameter value is
`customFields` on every endpoint that supports it.
schema:
type: string
example: customFields
excludeTeamParam:
name: exclude
in: query
description: >
Comma-separated list of referenced datasets to omit from the response.
All are included by default; excluding one both drops it from the payload
and skips the query used to build it. Allowed values:
`assignable_learning_path_ids`, `assignable_media_item_ids`, `lead_user_groups`.
schema:
type: string
example: assignable_learning_path_ids,assignable_media_item_ids,lead_user_groups
teamIdsParam:
name: teamIds
in: query
description: Comma separated list of team ids.
schema:
type: string
example: 1,2,3
userIdsParam:
name: userIds
in: query
description: Comma separated list of user ids.
schema:
type: string
example: 1719918,1719907,1719901
userNameParam:
name: userName
in: query
description: User name.
schema:
type: string
example: Jack Sparrow
responses:
NotFound:
description: Entity not found.
content:
application/json:
schema:
$ref: '#/components/schemas/NotFoundError'
UnprocessableEntity:
description: >
Validation failure. Returned instead of 400 by endpoints whose request
validation uses Laravel's default error format.
content:
application/json:
schema:
$ref: '#/components/schemas/UnprocessableEntityError'
BadRequest:
description: Validation failure.
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
Unauthorized:
description: Missing or invalid bearer token.
content:
application/json:
schema:
$ref: '#/components/schemas/Message'
Forbidden:
description: Token lacks the required permission.
content:
application/json:
schema:
$ref: '#/components/schemas/ForbiddenError'
securitySchemes:
sanctumToken:
type: http
scheme: bearer
schemas:
Assignment:
type: object
required:
- title
properties:
id:
type: integer
readOnly: true
example: 1
title:
type: string
type:
type: string
description: Set to 'recommended' for courses in this assignment to show up as recommended or 'assigned' for courses to show up as assigned.
example: Assigned
enum:
- Assigned
- Recommended
- assigned
- recommended
assignment_type:
type: string
description: Set to 'courses' for courses or 'learningpaths' for learning paths.
example: courses
enum:
- courses
- learningpaths
course_ids:
type: array
items:
type: integer
description: Required if assignment_type is "courses"
learning_path_ids:
type: array
items:
type: integer
description: Required if assignment_type is "learningpaths"
usergroups:
type: array
items:
type: integer
user_ids:
type: array
items:
type: integer
users:
readOnly: true
type: array
items:
type: object
properties:
id:
type: integer
example: 1620265
username:
type: string
example: johndoe
email:
type: string
example: john@doe.com
name:
type: string
example: John Doe
free:
type: boolean
description: If true, the assignment is free.
start_date:
type: string
format: date
end_date:
type: string
format: date
due_date:
type: string
format: date
days_to_complete:
type: integer
minimum: 0
maximum: 2048
assignment_filter_type:
type: string
description: Filter type ( users or groups ).
example: groups
enum:
- users
- groups
team_id:
type: integer
readOnly: true
dynamic_due_dates_enabled:
type: boolean
description: Only works for Learning Path Assignments
dynamic_due_date_number:
type: integer
description: Required if dynamic_due_dates_enabled is true
dynamic_due_date_unit:
type: string
enum:
- minute
- hour
- day
- week
- month
- year
example: '[minute, hour, day, month, year]'
description: Required if dynamic_due_dates_enabled is true
enroll_users_in_paths:
type: boolean
description: Only works for Learning Path Assignments. When true, users will be enrolled in the learning paths. Defaults to true if not specified.
created_by:
type: integer
readOnly: true
created_on:
type: string
format: date
readOnly: true
modified_by:
type: integer
readOnly: true
modified_on:
type: string
format: date
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this assignment changed.
description:
type: string
maxLength: 50
Audit:
type: object
properties:
id:
readOnly: true
type: integer
action:
readOnly: true
type: string
date:
readOnly: true
type: string
format: date
user:
readOnly: true
type: object
properties:
id:
type: integer
example: 1620265
username:
type: string
example: johndoe
email:
type: string
example: john@doe.com
name:
type: string
example: John Doe
ip_address:
readOnly: true
type: string
audit_type_id:
readOnly: true
type: integer
description: The id of the audit action type (see /audit/types).
target_item_id:
readOnly: true
type: integer
description: The ID of the record that was acted on, if there is one
changes:
readOnly: true
type: array
items:
type: object
properties:
field_name:
type: string
before:
type: string
after:
type: string
supplemental_data:
readOnly: true
type: object
description: Any additional info stored by the audit log for this action
timestamp_modified:
type: string
format: date-time
readOnly: true
description:
type: string
readOnly: true
AuditActionType:
type: object
properties:
id:
readOnly: true
type: integer
type:
readOnly: true
type: string
AuthAudit:
type: object
properties:
id:
readOnly: true
type: integer
action:
readOnly: true
type: string
date:
readOnly: true
type: string
format: date
user:
readOnly: true
type: object
properties:
id:
type: integer
example: 1620265
username:
type: string
example: johndoe
email:
type: string
example: john@doe.com
name:
type: string
example: John Doe
timestamp_modified:
type: string
format: date-time
readOnly: true
Award:
type: object
required:
- title
- type
properties:
id:
type: integer
readOnly: true
example: 1
title:
type: string
example: Badge of Awesomeness
type:
type: string
description: Can be badge, certificate, or milestone.
example: badge
enum:
- badge
- certificate
- milestone
certificate_type:
type: string
enum:
- internal
- external
default: internal
description: External certificates have no requirements
example: internal
description:
type: string
example: This badge is awesome!
maxLength: 50
enabled:
type: boolean
badge_hover:
type: string
example: Badge of Awesomeness
share_award_page:
type: boolean
expiration_type:
type: string
description: Type of time period after which the certificate will expire. Possible values are "year", "month", "week", "day".
example: year|month|week|day
expiration_classification:
type: string
description: Type of award expiration. Possible values are "static", "dynamic", "none".
example: static|dynamic|none
expiration_date:
type: string
format: date
description: Date of static award expiration
example: '2024-01-01 16:08:08'
expiration_amount:
type: integer
description: The number of [expiration_type]s that will need to pass before this award expires.
requirement_type:
type: string
description: Set this to "assigned" to assign the certificate to a specific user or set of users, or set to "conditional" to only award the certificate after a specific set of requirements are met.
example: conditional|assigned
user_can_lose_badge:
type: boolean
description: If true if the user will be able to lose their award.
certificate_id:
type: integer
description: The certificate template this award is associated with. Only used if type = 'certificate'.
requirements_all:
type: boolean
description: Only needed when requirement_type is set to "conditional". Set this to true if all requirements must be met, or false if any subset of them can be met to award the certificate.
user_list:
type: array
items:
type: integer
description: Array of user ids to assign the award to, only used when award type = "assigned".
usergroup_actions:
type: boolean
description: If set to true, add the users who were awarded the certificate to usergroups.
add_usergroups:
type: array
items:
type: integer
description: Array of user group ids to add award recipients to.
remove_usergroups:
type: array
items:
type: integer
description: Array of user group ids to remove award recipients from.
points_actions:
type: boolean
description: If set to true, points are awarded upon attainment of the award.
points_category:
type: integer
description: Id of points category that points should be assigned under.
points:
type: integer
description: The number of points to be awarded on certificate attainment.
requirements:
type: array
items:
$ref: "#/components/schemas/AwardRequirement"
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this award changed.
created_by:
type: integer
readOnly: true
created_on:
type: string
format: date-time
readOnly: true
AwardEarned:
type: object
properties:
award_id:
type: integer
description: The primary key of the award_earned record. Important, this is NOT the ID of the award itself
readOnly: true
user_id:
type: integer
readOnly: true
badge_id:
type: integer
description: The ID of the award. Can be used on the /award/{id} endpoint to pull more info. Works for badges, certificates, and milestones
readOnly: true
date_earned:
type: string
pattern: ^(\d{4})\-(0\d|1[012])\-(0\d|[12]\d|3[01])\s([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$
date_expires:
type: string
format: date
readOnly: true
award_title:
type: string
readOnly: true
award_type:
type: string
readOnly: true
user_name:
type: string
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
AwardRequirement:
type: object
properties:
requirement_active:
type: boolean
description: Set this to true to enable the requirement, false to disable it.
requirement_type:
type: string
description: One of "category", "course", "lesson", "usergroup", "accesslevel", "event", "quiz" or "checklist".
example: course
enum:
- category
- course
- lesson
- usergroup
- accesslevel
- event
- quiz
- checklist
requirement_completion:
type: string
description: Defines whether any or all [requirement_type]s are required to be completed in order for this award to be assigned.
example: any|all
required_category:
type: array
items:
type: integer
description: An array of course category ids used when requirement_type = "category".
required_course:
type: array
items:
type: integer
description: An array of course ids used when requirement_type = "course".
required_lesson:
type: array
items:
type: integer
description: An array of lesson ids used when requirement_type = "lesson".
usergroup:
type: array
items:
type: integer
description: An array of user group ids used when requirement_type = "usergroup".
accesslevel:
type: array
items:
type: integer
description: An array of access level ids used when requirement_type = "accesslevel".
required_event:
type: array
items:
type: integer
description: An array of event ids sed when requirement_type = "event".
required_event_action:
type: string
description: Set this to "registered" or "checkin" when using the "event" requirement type. This will require the user to be either registered or checked in to whichever events are given as part of the requirement.
example: registered|checkin
required_quiz:
type: array
items:
type: integer
description: Quiz ids the requirement applies to. Used when requirement_type is quiz.
required_checklist:
type: array
items:
type: integer
description: Checklist ids the requirement applies to. Used when requirement_type is checklist.
required:
- requirement_active
- requirement_type
- requirement_completion
AwardSyncRequest:
type: object
properties:
success:
readOnly: true
type: string
award_id:
type: integer
user_id:
type: integer
Checklist:
type: object
properties:
id:
type: integer
readOnly: true
example: 1
title:
type: string
description:
type: string
enabled:
type: boolean
due_date:
type: string
format: date
access_type:
type: string
example: none|access|user|list
userlist:
type: array
items:
type: integer
usergroup:
type: array
items:
type: integer
accesslevel:
type: array
items:
type: integer
is_sequential:
type: boolean
items:
type: array
items:
$ref: "#/components/schemas/ChecklistItem"
show_tooltip:
type: boolean
due_date_type:
type: string
example: dynamic|fixed|none
description: dynamic - Due date is Dynamically Based from the date that they first received any of the assigned user groups. (requires Access Restriction Type to be set as User Group), fixed - Set scheduled Due Date. none - No due date.
checklist_due_dynamic_number:
type: integer
description: Number of [checklist_due_dynamic_unit]s until this checklist is due.
example: 5
checklist_due_dynamic_unit:
type: string
example: day|week|month|year
description: Unit of time used for 'dynamic' due date type.
auto_translate:
type: boolean
language:
type: string
ordering:
type: integer
created_on:
type: string
format: date-time
readOnly: true
created_by:
type: integer
readOnly: true
timestamp_created:
type: string
format: date-time
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
params:
type: string
ChecklistItem:
type: object
properties:
id:
type: string
example: 1634694593n29Uo7
readOnly: true
type:
type: string
description: Describes on which event this checklist item will be considered completed.
example: course_completion|lesson_completion|certificate_awarded|badge_awarded|event_registration|event_checkin|watched_video|milestone_awarded|custom
icon:
type: string
example: lizicon-1-TEP-Connect-Icon-15
title:
type: string
instructions:
type: string
due_date_type:
type: string
example: dynamic|fixed|none
description: Dynamic due date type is based on time passed since the user was assigned to the usergroup this checklist is assigned to. Fixed is an exact date.
item_due_dynamic_number:
type: string
description: The number of [item_due_dynamic_unit] that describe the due date of this checklist item. Only used when due_date_type = dynamic.
item_due_dynamic_unit:
type: string
example: day|week|month|year
description: The unit of time used for [item_due_dynamic_number] Only used when due_date_type = dynamic.
due_date:
type: string
format: date
description: Only used when due_date_type = fixed.
course_id:
type: integer
example: The id of the course for the course_completion item type.
lesson_id:
type: integer
example: The id of the lesson for the lesson_completion item type.
milestone_id:
type: integer
example: The id of the milestone for the milestone_awarded item type
certificate_id:
type: integer
example: The id of the certificate for the certificate_awarded item type
badge_id:
type: integer
example: The id of the badge for the badge_awarded item type
event_id:
type: integer
example: The id of the event for the event_registration or event_checkin item types
media_id:
type: integer
example: The id of the watched_video for the watched_video item type
link:
type: string
completion_type:
type: string
example: auto|admin|user
description: If set to 'auto', the checklist will complete when the course/lesson/certificate/badge/event/media is completed. If set to 'admin' only an admin user can mark this item complete. If set to 'user' any user can mark this item complete.
points_category:
type: integer
example: 1
description: The id of the points category that points will be assigned to.
points:
type: integer
description: The number of points awarded when this item is completed.
required_for_completion:
type: boolean
description: If false the checklist item is not factored into the completion % for the list.
group:
type: integer
description: The grouping of this checklist item. Items in the same group will have the same group number
item_award:
type: integer
readOnly: true
ChecklistProgress:
type: object
properties:
user_id:
type: integer
readOnly: true
checklist_id:
type: integer
readOnly: true
item_id:
type: string
readOnly: true
example: 1689003604CWilGr
item_type:
type: string
readOnly: true
completed:
type: boolean
readOnly: true
date:
type: string
format: date
readOnly: true
due_date:
type: string
format: date
readOnly: true
archive_date:
type: string
format: date
readOnly: true
assigned_date:
type: string
format: date
readOnly: true
title:
type: string
readOnly: true
type:
type: string
readOnly: true
due_date_type:
type: string
readOnly: true
completion_type:
type: string
readOnly: true
enum:
- auto
- admin
- user
timestamp_created:
type: string
format: date-time
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
user_name:
type: string
readOnly: true
CommunityGroupPost:
type: object
properties:
id:
type: integer
description: ID of the post, unique within its type.
type:
type: string
enum: [post, discussion, announcement]
community_group_id:
type: integer
user_id:
type: integer
description: ID of the user who authored the content.
content_body:
type: string
description: Plain-text content. Mentions are rendered as the user's name and HTML is stripped. Discussions and announcements are the title and message separated by a blank line.
destination_url:
type: string
format: uri
description: Direct LMS link to the post.
created_at:
type: string
description: When the item was created, in UTC (`YYYY-MM-DD HH:MM:SS`, one-second precision).
example: "2026-09-01 14:30:00"
CommunityGroupComment:
type: object
properties:
id:
type: integer
type:
type: string
enum: [comment]
post_id:
type: integer
post_type:
type: string
enum: [post, discussion, announcement]
community_group_id:
type: integer
user_id:
type: integer
description: ID of the user who authored the comment.
content_body:
type: string
description: Plain-text comment content.
destination_url:
type: string
format: uri
description: Direct LMS link to the parent post (comments have no permalink of their own).
created_at:
type: string
description: When the item was created, in UTC (`YYYY-MM-DD HH:MM:SS`, one-second precision).
example: "2026-09-01 14:35:00"
CommunityGroup:
type: object
required:
- name
- published
- enable_user_groups
properties:
id:
type: integer
readOnly: true
name:
type: string
published:
type: boolean
enable_user_groups:
type: boolean
owner_id:
type: integer
readOnly: true
description:
type: string
users:
type: array
items:
type: integer
user_groups:
type: array
items:
type: integer
created:
type: string
format: date-time
readOnly: true
CommunityGroupIds:
type: object
properties:
community_groups:
type: array
items:
type: integer
Course:
type: object
required:
- title
- slug
- coursescategory_id
properties:
id:
type: integer
readOnly: true
title:
type: string
example: MyCourse
slug:
type: string
description: Unique URI for use in Search Engine Friendly urls.
pattern: "[a-z-]+"
coursescategory_id:
type: integer
format: int64
description: Id of the course category this course belongs to.
courses_sub_categories_ids:
type: array
items:
type: integer
description: Comma-separated list of course category ids that this course belongs to.
description:
type: string
short_description:
type: string
readOnly: true
image:
type: string
video_url:
type: string
featured_course:
type: boolean
price:
type: number
format: float
available_to_purchase:
type: boolean
enabled:
type: boolean
registrants:
readOnly: true
type: array
items:
type: integer
external_link:
type: string
format: url
final_course_survey:
nullable: true
description: Set to null to remove the final course survey from the course.
type: object
properties:
id:
type: integer
survey_title:
type: string
survey_instructions:
type: string
content_expires:
type: boolean
expiration_date:
type: string
format: date
custom_id:
type: string
required_for_completion:
type: boolean
customFields:
type: array
description: When assigning customFields either a field_id or title can be provided. It is recommended to use the field_id in case there is a field name with a duplicate title.
items:
$ref: '#/components/schemas/CustomFieldFilter'
lessons:
type: number
format: int
readOnly: true
description: The number of lessons in the course.
ordering:
type: number
format: int
readOnly: true
description: Used when displaying multiple courses.
view_access_type:
type: string
example: none
description: 'Visibility Permission Type. Note: "list" targets specific users and "user" targets user groups.'
enum:
- none
- list
- user
- access
register_access_type:
type: string
example: none
description: 'Registration Permission Type. Note: "list" targets specific users and "user" targets user groups.'
enum:
- none
- list
- user
- access
view_access_groups:
type: array
items:
type: integer
description: array of group ids. Required if view_access_type is user.
view_access_users:
type: array
items:
type: integer
description: array of user ids. Required if view_access_type is list.
view_access_levels:
type: array
items:
type: integer
description: array of access level ids. Required if view_access_type is access.
register_access_groups:
type: array
items:
type: integer
description: array of group ids. Required if register_access_type is user.
register_access_users:
type: array
items:
type: integer
description: array of user ids. Required if register_access_type is list.
register_access_levels:
type: array
items:
type: integer
description: array of access level ids. Required if register_access_type is access.
multilingual_overrides:
type: object
items:
type: object
description: 'An object with multilingual override data in the form { "fr": { "use": 1, "title": "French Title", ...} }. Overrides are only included if enabled (use = 1).'
use_library_content:
type: boolean
description: Specifies if a SCORM (or bizlibrary) package is used for this course
library_content_type:
type: string
description: Either 'bizlibrary' or 'scorm'
bizlibrary_content_title:
type: string
bizlibrary_content_id:
type: string
scorm_id:
type: integer
scorm_title:
type: string
locked:
type: integer
use_due_date:
type: boolean
readOnly: true
hard_due_date:
type: boolean
readOnly: true
due_date_type:
type: string
readOnly: true
description: static|dynamic
example: static|dynamic
due_static_date:
type: string
format: date
readOnly: true
due_dynamic_number:
type: integer
readOnly: true
due_dynamic_unit:
type: string
readOnly: true
description: minute|hour|day|week|month|year
example: minute|hour|day|week|month|year
open_date:
type: string
format: date
readOnly: true
close_date:
type: string
format: date
readOnly: true
visible_before_open:
type: boolean
readOnly: true
visible_after_close:
type: boolean
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this course changed, including related data such as lessons or assignments.
course_sub_title:
type: string
readOnly: true
ref_url:
type: string
readOnly: true
pricing_modifiers:
type: object
readOnly: true
created_on:
type: string
format: date-time
readOnly: true
modified_on:
type: string
format: date-time
readOnly: true
events:
type: array
readOnly: true
items:
type: object
properties:
id:
type: integer
title:
type: string
restrict_event_registrations:
type: integer
readOnly: true
allow_to_regsister_all_events:
type: integer
readOnly: true
description: 'Note: the misspelling is the actual field name returned by the API.'
event_registration_limit:
type: integer
readOnly: true
event_checkin_required:
type: integer
readOnly: true
event_registration_required:
type: integer
readOnly: true
CourseCategory:
type: object
required:
- title
- slug
properties:
id:
type: integer
readOnly: true
title:
type: string
parent_id:
type: integer
description: The id of the parent course category. 0 for no parent.
slug:
type: string
description: Unique URI for use in Search Engine Friendly urls.
pattern: "[a-z-]+"
enabled:
type: boolean
view_access_type:
type: string
example: none|list|user|access
description: Visibility Permission Type.
view_access_groups:
type: array
items:
type: integer
description: array of group ids. Required if view_access_type is user.
view_access_users:
type: array
items:
type: integer
description: array of user ids. Required if view_access_type is list.
view_access_levels:
type: array
items:
type: integer
description: array of access level ids. Required if view_access_type is access.
multilingual_overrides:
type: object
items:
type: object
description: 'An object with multilingual override data in the form { "fr": { "use": 1, "title": "French Title", ...} } . Overrides are only included if enabled (use = 1).'
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this course category changed.
CourseProgress:
type: object
properties:
user_id:
type: integer
course_id:
type: integer
language:
type: string
example: en-GB
lessons_completed_list:
type: array
items:
type: integer
lessons_total_list:
type: array
items:
type: integer
score:
type: number
progress:
type: number
format: float
date_started:
type: string
format: date
date_last_activity:
type: string
format: date
date_completed:
type: string
format: date
date_due:
type: string
format: date
archive_date:
type: string
format: date
status:
type: string
enum:
- not started
- in progress
- complete
description: Derived from date_started, date_completed, and progress fields.
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this course progress record changed, including related data.
id:
type: integer
readOnly: true
user_name:
type: string
readOnly: true
course_title:
type: string
readOnly: true
course_enabled:
type: integer
readOnly: true
marked_complete:
type: integer
readOnly: true
marked_complete_by:
type: integer
readOnly: true
params:
type: string
LearningPathProgress:
type: object
properties:
id:
type: integer
readOnly: true
user_id:
type: integer
learning_path_id:
type: integer
items_total:
type: integer
readOnly: true
description: >-
Server-derived from the learning path's required-course count. Ignored if supplied in
a request body.
items_completed:
type: integer
minimum: 0
description: >-
Must be between 0 and the learning path's item total (its required-course count),
inclusive.
progress:
type: number
format: float
date_started:
type: string
format: date
date_last_activity:
type: string
format: date
date_completed:
type: string
format: date
date_due:
type: string
format: date
archive_date:
type: string
format: date
timestamp_modified:
type: string
format: date-time
readOnly: true
CustomField:
type: object
description: Profile Fields are user defined fields that can be used in the user registration forms and/or subscription registration forms.
properties:
id:
type: integer
readOnly: true
type:
type: string
example: "group|gender|birthdate|textarea|text|url|date|list|radio|checkbox|email|time"
ordering:
type: integer
description: This column is used to define which group a custom field is in. For example a group with ordering = 1 would have fields in it with ordering = 2 or 3. Then another group could start at 4 with child fields with ordering id = 5 or 6.
published:
type: integer
description: If a custom field is not published, it will not be available to be used in any registration or subscription forms.
min:
type: integer
max:
type: integer
name:
type: string
tips:
type: string
visible:
type: integer
required:
type: integer
searchable:
type: integer
registration:
type: integer
options:
type: array
description: Options for select/radio style fields.
items:
type: string
fieldcode:
type: string
description: Unique key used for field.
params:
type: string
description: Params contains type-specific configuration for Profile Fields. Some options are alternate registration_text to use as the field label in the registration form, date range and format etc.
example: {"registration_text": "", "display": "date", "readonly": "0", "maxrange": "1", "minrange": "1", "date_format": "1"}
CustomFieldDefinition:
type: object
description: >
A custom field definition. Custom fields carry extra structured data on
courses, events, purchase orders and user objects (axs_custom_fields); rows
with object_type `users` are user profile field definitions
(joom_community_fields), returned by GET /metadata/customFields only when
objectType=users is requested explicitly. `hide_field` is omitted on users
rows - user profile fields have no such flag.
properties:
id:
type: integer
readOnly: true
example: 44
name:
type: string
example: Cost Center
type:
type: string
description: >
Field type as stored by the LMS. On object_type `users` rows this is a user
profile field type (see ProfileField.type); `group` rows are the section
headers the LMS profile form uses - they are returned so that every field_id
reported by GET /metadata/customFields/values?objectType=users resolves to a
definition here, and they never carry values themselves.
example: text
object_type:
type: string
description: The kind of object this field can be attached to.
enum: [courses, events, "purchase order", "user objects", users]
example: courses
enabled:
type: boolean
ordering:
type: integer
description: Display order within the object type.
hide_field:
type: boolean
description: >
LMS display flag. Not an authorization flag. Omitted on object_type `users`
rows - user profile fields have no such flag.
params:
type: object
description: >
Type-specific configuration, stored by the LMS as a JSON string and returned
decoded. Keys vary by field type. Omitted entirely when the field has no
configuration, so absence carries no meaning beyond "nothing set".
additionalProperties: true
properties:
options:
type: array
description: >
The choices for select, list, radio and checkbox fields. The LMS stores
these as a single newline-delimited string; the API returns them split
and trimmed, with blank entries removed. Omitted when the field has no
options, which is the normal case for types like text and country.
items:
type: string
example: ["gah", "geh", "gee"]
timestamp_created:
type: string
format: date-time
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
CustomFieldValueDetail:
type: object
description: >
A custom field value row (axs_custom_field_values) with its field definition
nested. Returned by the standalone custom field value endpoints. The
CustomFieldValueResponse schema is the trimmed shape embedded in course, event,
object, purchase order and user payloads.
properties:
id:
type: integer
readOnly: true
example: 1201
object_type:
type: string
enum: [courses, events, "purchase order", "user objects", users]
example: courses
object_id:
type: integer
description: >
Id of the course, event, purchase order, user object or user this value
belongs to, per object_type. Only unique within an object type.
example: 91
field_id:
type: integer
description: >
Retained alongside `field` so the row stays traceable when the definition
has been deleted. For object_type `users` this references a user field
definition (GET /metadata/customFields?objectType=users); for every other object_type it references
a metadata custom field (GET /metadata/customFields) - the two are
numbered independently.
example: 44
value:
type: string
example: "73958"
field:
type: object
nullable: true
description: The field definition this value belongs to. Null when the definition has been deleted.
properties:
id:
type: integer
example: 44
name:
type: string
example: Cost Center
type:
type: string
example: text
enabled:
type: boolean
timestamp_created:
type: string
format: date-time
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
Event:
type: object
required:
- title
- event_date
- alias
properties:
id:
type: integer
readOnly: true
example: 1
parent_id:
description: When creating a recurring event several 'child' events are created, each with a date and title based on the recurring settings and the title of the parent event. If an event has parent_id = 0 then it is a parent and may or may not have children.
type: integer
category_id:
type: integer
secondary_category_ids:
type: array
items:
type: integer
description: IDs of secondary categories assigned to this event.
readOnly: true
location_id:
type: integer
title:
type: string
example: My Event
registration_type:
type: integer
example: 0
description: 0 - Both Individual and Group Registration, 1 - Only Individual Registration, 2 - Only Group Registration, 3 - Disable Registration.
view_access:
type: array
items:
type: integer
description: ids of the groups that can view this course.
example: [1]
registration_access:
type: array
items:
type: integer
description: ids of the groups that can register for this course.
example: [1]
event_date:
type: string
example: '2026-08-29 12:00:00'
description: Accepts YYYY-MM-DD or YYYY-MM-DD HH:MM:SS; responses include the time component.
event_end_date:
type: string
example: '2026-08-29 12:00:00'
description: Accepts YYYY-MM-DD or YYYY-MM-DD HH:MM:SS; responses include the time component.
short_description:
type: string
description:
type: string
individual_price:
type: number
format: float
event_capacity:
type: integer
created_by:
type: integer
description: User id.
example: 1620265
readOnly: true
cut_off_date:
type: string
description: Registration end date. Accepts YYYY-MM-DD or YYYY-MM-DD HH:MM:SS; responses include the time component.
example: '2026-08-29 12:00:00'
published:
type: boolean
featured:
type: boolean
registration_start_date:
type: string
description: Registration start date. Accepts YYYY-MM-DD or YYYY-MM-DD HH:MM:SS; responses include the time component.
example: '2026-08-29 12:00:00'
alias:
type: string
description: Unique URI for use in Search Engine Friendly urls
pattern: '[a-z-]+'
example: my-event
language:
type: string
enable_auto_reminder:
type: boolean
description: If set to 'true' registrants will get auto reminder emails for this event.
image:
type: string
readOnly: true
timezone:
type: string
virtual_classroom_id:
type: string
example: B0C4D939-AF12-43D8-82B3-0A68D423F894
readOnly: true
virtual_classroom_uri:
type: string
description: uri of virtual classroom that can be used for linking directly to virtual classroom
readOnly: true
request_register:
type: boolean
readOnly: true
request_team:
type: boolean
readOnly: true
request_instructor:
type: boolean
readOnly: true
instructor_ids:
type: array
readOnly: true
items:
type: integer
allow_to_cancel:
type: boolean
readOnly: true
cancel_before_date:
type: string
format: date
nullable: true
description: Only present when allow_to_cancel is true.
readOnly: true
registration_count:
type: integer
readOnly: true
description: Total number of registrants for this event.
checked_in_count:
type: integer
readOnly: true
description: Total number of checked-in registrants for this event.
waitlist_count:
type: integer
readOnly: true
description: Total number of waitlisted registrants for this event.
sub_capacities:
type: array
readOnly: true
items:
$ref: "#/components/schemas/EventSubCapacity"
custom_fields:
type: array
readOnly: true
items:
$ref: '#/components/schemas/CustomFieldValueResponse'
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this event changed, including related data such as registrations.
EventSubCapacity:
type: object
properties:
id:
type: integer
readOnly: true
example: 1
event_id:
type: integer
example: 100
usergroup_ids:
type: array
items:
type: integer
capacity:
type: integer
example: 50
EventWithImage:
type: object
required:
- title
- event_date
- alias
properties:
id:
type: integer
readOnly: true
example: 1
parent_id:
description: When creating a recurring event several 'child' events are created, each with a date and title based on the recurring settings and the title of the parent event. If an event has parent_id = 0 then it is a parent and may or may not have children.
type: integer
category_id:
type: integer
secondary_category_ids:
type: array
items:
type: integer
description: IDs of secondary categories assigned to this event.
readOnly: true
location_id:
type: integer
title:
type: string
example: My Event
registration_type:
type: integer
example: 0
description: 0 - Both Individual and Group Registration, 1 - Only Individual Registration, 2 - Only Group Registration, 3 - Disable Registration.
view_access:
type: array
items:
type: integer
description: ids of the groups that can view this course.
registration_access:
type: array
items:
type: integer
description: ids of the groups that can register for this course.
event_date:
type: string
example: '2026-08-29 12:00:00'
description: Accepts YYYY-MM-DD or YYYY-MM-DD HH:MM:SS; responses include the time component.
event_end_date:
type: string
example: '2026-08-29 12:00:00'
description: Accepts YYYY-MM-DD or YYYY-MM-DD HH:MM:SS; responses include the time component.
short_description:
type: string
description:
type: string
individual_price:
type: number
format: float
event_capacity:
type: integer
created_by:
type: integer
description: User id.
example: 1620265
readOnly: true
cut_off_date:
type: string
description: Registration end date. Accepts YYYY-MM-DD or YYYY-MM-DD HH:MM:SS; responses include the time component.
example: '2026-08-29 12:00:00'
published:
type: boolean
featured:
type: boolean
registration_start_date:
type: string
description: Registration start date. Accepts YYYY-MM-DD or YYYY-MM-DD HH:MM:SS; responses include the time component.
example: '2026-08-29 12:00:00'
alias:
type: string
description: Unique URI for use in Search Engine Friendly urls.
pattern: "[a-z-]+"
language:
type: string
enable_auto_reminder:
type: boolean
description: If set to 'true' registrants will get auto reminder emails for this event.
image:
type: string
format: binary
description: Supported file types - jpg,png,jpeg,gif. Maximum size 10MB.
timezone:
type: string
example: America/New_York
EventRegistration:
type: object
properties:
id:
type: integer
description: >
Registration id - the unique key for this record. (user_id, event_id)
is not unique: a user can hold more than one registration for the same
event (for example a cancelled registration followed by a new one, or a
waitlist entry), and a group booking has a billing row plus one row per
member.
event_id:
type: integer
user_id:
type: integer
group_id:
type: integer
description: >
For a member of a group booking, the id of the group's billing
registration; 0 for individual registrations and billing rows.
first_name:
type: string
last_name:
type: string
organization:
type: string
address:
type: string
address2:
type: string
city:
type: string
state:
type: string
country:
type: string
zip:
type: string
phone:
type: string
fax:
type: string
email:
type: string
number_registrants:
type: integer
total_amount:
type: number
discount_amount:
type: number
amount:
type: number
register_date:
type: string
format: date
payment_date:
type: string
format: date
payment_method:
type: string
transaction_id:
type: string
axs_trxn_id:
type: integer
comment:
type: string
published:
type: boolean
is_request:
type: integer
cart_id:
type: integer
payment_processing_fee:
type: number
late_fee:
type: number
notified:
type: boolean
checked_in:
type: boolean
coupon_usage_calculated:
type: boolean
checked_in_count:
type: integer
deposit_amount:
type: number
payment_status:
type: integer
coupon_id:
type: integer
check_coupon:
type: boolean
tax_amount:
type: number
registration_code:
type: string
params:
type: object
is_reminder_sent:
type: boolean
is_deposit_payment_reminder_sent:
type: boolean
process_deposit_payment:
type: boolean
deposit_payment_transaction_id:
type: integer
deposit_payment_axs_trxn_id:
type: integer
user_ip:
type: string
deposit_payment_method:
type: integer
is_group_billing:
type: boolean
language:
type: string
invoice_number:
type: integer
cancel_date:
type: string
format: date
original_event_id:
type: integer
currency_code:
type: string
nullable: true
base_currency:
type: string
nullable: true
exchange_rate:
type: number
nullable: true
base_amount:
type: number
nullable: true
subcapacity_id:
type: integer
nullable: true
course_id:
type: integer
nullable: true
created_on:
type: string
format: date-time
created_by:
type: integer
modified_on:
type: string
format: date-time
modified_by:
type: integer
ordering:
type: integer
timestamp_created:
type: string
format: date-time
timestamp_modified:
type: string
format: date-time
user_name:
type: string
event_title:
type: string
status:
type: string
enum:
- Pending
- Registered
- Cancelled
- Waitlist
- Unknown
waitlist_order:
type: array
items:
type: integer
description: Ordered list of user IDs on the waitlist for this event
Transaction:
type: object
properties:
id:
type: integer
axs_transaction_id:
type: integer
transaction_number:
type: string
is_partial_order:
type: boolean
type:
type: string
pay_instrument:
type: object
properties:
id:
type: integer
nullable: true
description: >-
ID of the LMS record this pay instrument references; which record
that is depends on `type` (credit card → saved card record,
invoice → invoice, purchase order → purchase order). Interpret it
together with `type`. Always `null` when `type` is `external`.
name:
type: string
type:
type: string
enum:
- credit card
- invoice
- purchase order
- external
description: Only returned when the relation is explicitly loaded; GET /transactions does not return it.
amount_in_base_currency:
type: number
base_currency:
type: string
exit_status:
type: string
transaction_amount:
type: number
transaction_currency:
type: string
transactor:
type: object
properties:
id:
type: integer
username:
type: string
name:
type: string
description: Only returned when the relation is explicitly loaded; GET /transactions does not return it.
transactor_type:
type: string
order:
$ref: "#/components/schemas/Order"
timestamp_created:
type: string
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this transaction changed.
Order:
type: object
properties:
id:
type: integer
amount:
type: number
purchaser:
type: object
properties:
id:
type: integer
username:
type: string
name:
type: string
description: Only returned when the relation is explicitly loaded; GET /transactions does not return it.
item_count:
type: integer
status:
type: string
enum:
- fulfilled
- refunded
- transaction fail
- pending
items:
type: array
items:
$ref: "#/components/schemas/OrderItem"
OrderItem:
type: object
properties:
id:
type: integer
product:
$ref: "#/components/schemas/Product"
status:
type: string
total_amount_before_discount:
type: number
total_amount_with_discount:
type: number
fees:
type: number
total_amount:
type: number
quantity:
type: integer
discounts:
type: array
items:
$ref: "#/components/schemas/OrderItemDiscount"
OrderItemDiscount:
type: object
properties:
order_item_id:
type: integer
sequence_number:
type: integer
amount_before_discount:
type: number
amount_with_discount:
type: number
discount:
$ref: "#/components/schemas/Discount"
Product:
type: object
properties:
id:
type: integer
name:
type: string
type:
type: string
lms_product_id:
type: integer
price:
type: number
recurring_price:
type: number
fixed_group_price:
type: number
late_fee:
type: number
Discount:
type: object
properties:
id:
type: integer
name:
type: string
type:
type: string
enum:
- promo code
- pricing modifier
- event coupon
- event discount
- event early bird
lms_discount_id:
type: integer
is_active:
type: boolean
LearningPath:
type: object
required:
- title
properties:
id:
type: integer
readOnly: true
title:
type: string
slug:
type: string
readOnly: true
published:
type: boolean
description:
type: string
courses:
type: array
items:
type: integer
course_details:
type: array
readOnly: true
items:
type: object
properties:
id:
type: integer
title:
type: string
ordering:
type: integer
optional_courses:
type: array
items:
type: integer
optional_course_details:
type: array
readOnly: true
items:
type: object
properties:
id:
type: integer
title:
type: string
ordering:
type: integer
subcategories:
type: array
items:
type: integer
tags:
type: array
items:
type: integer
view_access_type:
type: string
example: none
description: 'Visibility Permission Type. Note: "list" targets specific users and "user" targets user groups.'
enum:
- none
- list
- user
- access
register_access_type:
type: string
example: none
description: 'Registration Permission Type. Note: "list" targets specific users and "user" targets user groups.'
enum:
- none
- list
- user
- access
view_access_groups:
type: array
items:
type: integer
description: array of group ids. Required if view_access_type is user.
view_access_users:
type: array
items:
type: integer
description: array of user ids. Required if view_access_type is list.
view_access_levels:
type: array
items:
type: integer
description: array of access level ids. Required if view_access_type is access.
register_access_groups:
type: array
items:
type: integer
description: array of group ids. Required if register_access_type is user.
register_access_users:
type: array
items:
type: integer
description: array of user ids. Required if register_access_type is list.
register_access_levels:
type: array
items:
type: integer
description: array of access level ids. Required if register_access_type is access.
created_by:
type: integer
readOnly: true
created_on:
type: string
format: date
readOnly: true
modified_by:
type: integer
readOnly: true
modified_on:
type: string
format: date
readOnly: true
deprecated: true
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this learning path changed, including related data such as courses or subcategories.
image:
type: string
readOnly: true
LearningPathWithImage:
type: object
required:
- title
properties:
id:
type: integer
readOnly: true
title:
type: string
slug:
type: string
readOnly: true
published:
type: boolean
description:
type: string
courses:
type: array
items:
type: integer
subcategories:
type: array
items:
type: integer
tags:
type: array
items:
type: integer
image:
type: string
format: binary
description: Supported file types - jpg,png,jpeg,gif. Maximum size 10MB.
view_access_type:
type: string
example: none|list|user|access
description: Visibility Permission Type.
register_access_type:
type: string
example: none|list|user|access
description: Registration Permission Type.
view_access_groups:
type: array
items:
type: integer
description: array of group ids. Required if view_access_type is user.
view_access_users:
type: array
items:
type: integer
description: array of user ids. Required if view_access_type is list.
view_access_levels:
type: array
items:
type: integer
description: array of access level ids. Required if view_access_type is access.
register_access_groups:
type: array
items:
type: integer
description: array of group ids. Required if register_access_type is user.
register_access_users:
type: array
items:
type: integer
description: array of user ids. Required if register_access_type is list.
register_access_levels:
type: array
items:
type: integer
description: array of access level ids. Required if register_access_type is access.
created_by:
type: integer
readOnly: true
created_on:
type: string
format: date
readOnly: true
modified_by:
type: integer
readOnly: true
modified_on:
type: string
format: date
readOnly: true
deprecated: true
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this learning path changed, including related data such as courses or subcategories.
optional_courses:
type: array
items:
type: integer
description: Ids of optional (non-required) courses in the learning path.
LearningPathCategory:
type: object
required:
- title
properties:
id:
type: integer
readOnly: true
title:
type: string
slug:
type: string
readOnly: true
published:
type: boolean
subcategories:
type: array
items:
type: integer
subcategory_details:
type: array
readOnly: true
items:
type: object
properties:
id:
type: integer
title:
type: string
ordering:
type: integer
created_by:
type: integer
readOnly: true
created_on:
type: string
format: date
readOnly: true
modified_by:
type: integer
readOnly: true
modified_on:
type: string
format: date
readOnly: true
deprecated: true
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this learning path category changed, including related data such as subcategories.
access_type:
type: string
example: none
enum:
- none
- access
- user
- list
description: 'Note: "list" targets specific users and "user" targets user groups.'
userlist:
type: array
items:
type: integer
usergroup:
type: array
items:
type: integer
accesslevel:
type: array
items:
type: integer
LearningPathSubcategory:
type: object
required:
- title
properties:
id:
type: integer
readOnly: true
title:
type: string
slug:
type: string
readOnly: true
published:
type: boolean
description:
type: string
categories:
type: array
items:
type: integer
learning_paths:
type: array
items:
type: integer
learning_path_details:
type: array
readOnly: true
items:
type: object
properties:
id:
type: integer
title:
type: string
ordering:
type: integer
created_by:
type: integer
readOnly: true
created_on:
type: string
format: date
readOnly: true
modified_by:
type: integer
readOnly: true
modified_on:
type: string
format: date
readOnly: true
deprecated: true
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this learning path subcategory changed, including related data such as learning paths.
access_type:
type: string
example: none
enum:
- none
- access
- user
- list
description: 'Note: "list" targets specific users and "user" targets user groups.'
userlist:
type: array
items:
type: integer
usergroup:
type: array
items:
type: integer
accesslevel:
type: array
items:
type: integer
image:
type: string
readOnly: true
LearningPathSubcategoryWithImage:
type: object
required:
- title
properties:
id:
type: integer
readOnly: true
title:
type: string
slug:
type: string
readOnly: true
published:
type: boolean
description:
type: string
categories:
type: array
items:
type: integer
image:
type: string
format: binary
description: Supported file types - jpg,png,jpeg,gif. Maximum size 10MB.
learning_paths:
type: array
items:
type: integer
created_by:
type: integer
readOnly: true
created_on:
type: string
format: date
readOnly: true
modified_by:
type: integer
readOnly: true
modified_on:
type: string
format: date
readOnly: true
deprecated: true
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this learning path subcategory changed, including related data such as learning paths.
access_type:
type: string
example: none|access|user|list
userlist:
type: array
items:
type: integer
usergroup:
type: array
items:
type: integer
accesslevel:
type: array
items:
type: integer
Lesson:
type: object
properties:
lesson_id:
type: integer
title:
type: string
description: Title of Lesson.
example: Introduction to Quantum Physics
image:
type: string
description: Image URL.
example: http://example.com/image.jpg
description:
type: string
description: Lesson description.
example: Lesson description text
lesson_type:
type: integer
description: Lesson Type.
example: 0 - Public, 1 - Access Only
language:
type: string
description: Language code.
example: en-GB|pt-BR
lesson_gating:
type: integer
description: Lesson Gating Status, read only, 1 if enabled, 0 if disabled.
published:
type: boolean
description: Lesson publish status.
example: true|false
quiz_prerequisite_setting:
type: integer
description: Unlock after quiz.
example: true|false
award_points:
type: integer
description: Number of Award points.
example: 10000
prerequisite_quizzes:
type: array
items:
type: object
example: [{"quiz_id": 1, "lesson_quiz": 10}]
teacher:
type: object
description: Simplified teacher object.
$ref: "#/components/schemas/Teacher"
teachers:
type: array
readOnly: true
items:
type: object
$ref: "#/components/schemas/Teacher"
teacher_ids:
type: array
writeOnly: true
items:
type: integer
description: List of teachers for this lesson, use the id of the teacher not the user
course:
type: object
properties:
course_id:
type: integer
title:
type: string
ordering:
type: integer
activities:
type: array
items:
type: object
readOnly: true
created_on:
type: string
format: style
ordering:
type: integer
is_final_course_survey:
type: boolean
use_library_content:
type: boolean
description: Specifies if a SCORM (or bizlibrary) package is used for this course
library_content_type:
type: string
description: Either 'bizlibrary' or 'scorm'
bizlibrary_content_title:
type: string
bizlibrary_content_id:
type: string
scorm_required:
type: boolean
scorm_id:
type: integer
scorm_title:
type: string
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this lesson changed, including related data such as activities or quizzes.
LessonInsert:
type: object
required:
- title
properties:
title:
type: string
description: Title of Lesson.
example: Introduction to Quantum Physics
image:
type: string
description: Image URL.
example: http://example.com/image.jpg
description:
type: string
description: Lesson description.
example: Lesson description text
lesson_type:
type: integer
description: Lesson Type.
example: 0 - Public, 1 - Access Only
language:
type: string
description: Language code.
example: en-GB|pt-BR
published:
type: boolean
description: Lesson publish status.
example: true|false
quiz_prerequisite_setting:
type: boolean
description: Unlock after quiz.
example: true|false
award_points:
type: integer
description: Number of Award points.
example: 10000
prerequisite_quizzes:
type: array
example: [1, 2, 4]
items:
type: integer
teacher_id:
type: integer
description: Teacher ID.
deprecated: true
teacher_ids:
type: array
items:
type: integer
description: Teacher IDs.
course_id:
type: integer
description: Course ID.
Location:
type: object
properties:
id:
type: integer
name:
type: string
example: Tovuti Headquarters
address:
type: string
example: 775 S Rivershore Ln \#120, Eagle, ID 83616, USA
city:
type: string
example: Eagle
state:
type: string
example: Idaho
zip:
type: string
example: 83616
country:
type: string
example: United States
lat:
type: number
format: float
example: 43.687440
description: Latitude.
long:
type: number
format: float
example: -116.354894
description: Longitude.
published:
type: boolean
example: true
user_id:
type: integer
description: User that created the location.
language:
type: string
example: en-GB
description: "Language code for the location. '*' is returned as 'All'."
layout:
type: string
description: Possible values are '', table, timeline.
timestamp_created:
type: string
format: date-time
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
EventCategory:
type: object
properties:
id:
type: integer
readOnly: true
parent_id:
type: integer
description: Parent category ID
name:
type: string
description:
type: string
published:
type: boolean
timestamp_created:
type: string
format: date-time
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
MediaCategory:
type: object
required:
- title
- published
- access_type
properties:
id:
type: integer
readOnly: true
example: 2
parent_id:
type: integer
example: 5
description: id of the parent media category.
title:
type: string
maxLength: 255
example: My Category
page_title:
type: string
maxLength: 255
example: text
description:
type: string
maxLength: 4000
example: This is descriptive text
published:
type: boolean
example: true
access_type:
type: string
example: none
enum:
- none
- list
- user
- access
description: 'Note: "list" targets specific users and "user" targets user groups.'
usergroup:
type: array
items:
type: integer
description: array of group ids.
userlist:
type: array
items:
type: integer
description: array of user ids.
accesslevel:
type: array
items:
type: integer
description: array of access level ids.
MediaItem:
type: object
required:
- title
- published
- media_type
- access_type
properties:
id:
type: integer
readOnly: true
example: 2
title:
type: string
maxLength: 255
example: My Video
speaker:
type: string
maxLength: 255
example: Jim Bob
description:
type: string
maxLength: 4000
example: This is descriptive text
published:
type: boolean
example: true
go_live_date:
type: string
example: '2026-07-30 12:00:00'
pattern: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$
description: Must be YYYY-MM-DD HH:MM:SS (a date-only value is rejected).
archive_date:
type: string
example: '2026-07-30 12:00:00'
pattern: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$
description: Must be YYYY-MM-DD HH:MM:SS (a date-only value is rejected).
use_expiration:
type: boolean
example: false
custom_id:
type: string
example: ABC123
expiration_date:
type: string
example: '2026-07-30 12:00:00'
pattern: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$
description: Must be YYYY-MM-DD HH:MM:SS (a date-only value is rejected).
category:
type: integer
example: 5
subcategory:
type: integer
example: 6
media_type:
type: string
example: video
enum:
- video
- audio
- pdf
- link
video_type:
type: string
example: mp4
description: Required if media_type is video.
enum:
- mp4
- youtube
- screencast
- facebook
- vimeo
source:
type: string
format: binary
description: audio file, video file, or pdf. Required if media_type is video, audio, or PDF.
thumbnail_image:
type: string
format: binary
description: Supported file types - jpg,png,jpeg,gif.
cover_image:
type: string
format: binary
description: Supported file types - jpg,png,jpeg,gif.
youtube_id:
type: string
example: DOWDNBu9DkU
description: ID of youtube video or full url. Required if video_type is youtube.
screencast_id:
type: string
example: DOWDNBu9DkU
description: Required if video_type is screencast.
facebook_url:
type: string
example: DOWDNBu9DkU
description: Required if video_type is facebook.
vimeo_id:
type: string
example: DOWDNBu9DkU
description: ID of vimeo video or full url. Required if video_type is vimeo.
interactive_source:
type: string
example: http://something.com
description: must be a full URL. Required if media_type is link.
access_type:
type: string
example: none
description: 'Visibility Permission Type. Note: "list" targets specific users and "user" targets user groups.'
enum:
- none
- list
- user
- access
access_purchase_type:
type: string
example: none
description: 'Access Permission Type. Note: "list" targets specific users and "user" targets user groups.'
enum:
- none
- list
- user
- access
usergroup:
type: array
items:
type: integer
description: array of group ids. Required if access_type is user.
userlist:
type: array
items:
type: integer
description: array of user ids. Required if access_type is list.
accesslevel:
type: array
items:
type: integer
description: array of access level ids. Required if access_type is access.
usergroup_purchase_register:
type: array
items:
type: integer
description: array of group ids. Required if access_purchase_type is user.
userlist_purchase_register:
type: array
items:
type: integer
description: array of user ids. Required if access_purchase_type is list.
accesslevel_purchase_register:
type: array
items:
type: integer
description: array of access level ids. Required if access_purchase_type is access.
tags:
type: array
items:
type: string
created_on:
type: string
format: date
example: YYYY-mm-dd
MediaItemNoData:
type: object
required:
- title
- published
- media_type
- access_type
properties:
id:
type: integer
readOnly: true
example: 2
title:
type: string
maxLength: 255
example: My Video
speaker:
type: string
maxLength: 255
example: Jim Bob
description:
type: string
maxLength: 4000
example: This is descriptive text
published:
type: boolean
example: true
go_live_date:
type: string
example: '2026-07-30 12:00:00'
pattern: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$
description: Must be YYYY-MM-DD HH:MM:SS (a date-only value is rejected).
archive_date:
type: string
example: '2026-07-30 12:00:00'
pattern: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$
description: Must be YYYY-MM-DD HH:MM:SS (a date-only value is rejected).
use_expiration:
type: boolean
example: false
custom_id:
type: string
example: ABC123
expiration_date:
type: string
example: '2026-07-30 12:00:00'
pattern: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$
description: Must be YYYY-MM-DD HH:MM:SS (a date-only value is rejected).
category:
type: integer
example: 5
subcategory:
type: integer
example: 6
media_type:
type: string
example: video
enum:
- video
- audio
- pdf
- link
video_type:
type: string
example: mp4
description: Required if media_type is video.
enum:
- mp4
- youtube
- screencast
- facebook
- vimeo
youtube_id:
type: string
example: DOWDNBu9DkU
description: ID of youtube video or full url. Required if video_type is youtube.
screencast_id:
type: string
example: JnD7uBZDI0Z
description: Required if video_type is screencast.
facebook_url:
type: string
example: https://facebook.com/johnd
description: Required if video_type is facebook.
vimeo_id:
type: string
example: https://vimeo.com/johndoe
description: ID of vimeo video or full url. Required if video_type is vimeo.
interactive_source:
type: string
example: http://interactivesource.com
description: must be a full URL. Required if media_type is link.
access_type:
type: string
example: none
description: 'Visibility Permission Type. Note: "list" targets specific users and "user" targets user groups.'
enum:
- none
- list
- user
- access
access_purchase_type:
type: string
example: none
description: 'Access Permission Type. Note: "list" targets specific users and "user" targets user groups.'
enum:
- none
- list
- user
- access
usergroup:
type: array
items:
type: integer
description: array of group ids. Required if access_type is user.
userlist:
type: array
items:
type: integer
description: array of user ids. Required if access_type is list.
accesslevel:
type: array
items:
type: integer
description: array of access level ids. Required if access_type is access.
usergroup_purchase_register:
type: array
items:
type: integer
description: array of group ids. Required if access_purchase_type is user.
userlist_purchase_register:
type: array
items:
type: integer
description: array of user ids. Required if access_purchase_type is list.
accesslevel_purchase_register:
type: array
items:
type: integer
description: array of access level ids. Required if access_purchase_type is access.
tags:
type: array
items:
type: string
Meeting:
type: object
required:
- meetingName
- meetingType
- date
- timezone
properties:
id:
type: integer
readOnly: true
meetingId:
type: string
example: 2391AFB0-0893-4850-9208-D7505685BE1F
readOnly: true
meetingName:
type: string
meetingType:
type: string
example: tovuti
enum:
- tovuti
- zoom
- webex
- gotomeeting
- google
- joinme
- other
creator:
type: integer
readOnly: true
maxParticipants:
type: integer
description: Maximum number of participants (0-999999).
minimum: 0
maximum: 999999
description:
type: string
date:
type: string
format: datetime
timezone:
type: string
example: "America/New_York"
access_type:
type: string
example: none
enum:
- none
- access
- user
- list
description: 'Note: "list" targets specific users and "user" targets user groups.'
hosts:
type: array
items:
type: integer
externalUrl:
type: string
format: url
moderatorPW:
type: string
readOnly: true
attendeePW:
type: string
readOnly: true
record:
type: boolean
description: If set to true, the meeting will be recorded.
duration:
type: integer
enabled:
type: boolean
userlist:
type: array
items:
type: integer
description: An array of user ids with access. Required access_type = 'users'.
accesslevel:
type: array
items:
type: integer
description: An array of access level ids with access. Required access_type = 'accesslevel'.
usergroup:
type: array
items:
type: integer
description: An array of usergroup ids with access. Required access_type = 'groups'.
attendees:
type: array
items:
type: integer
description: User ids of attendees for this meeting.
readOnly: true
created:
type: string
format: date-time
readOnly: true
Object:
type: object
properties:
id:
type: integer
readOnly: true
example: 2
title:
type: string
example: MyOrganization
type_id:
type: integer
example: id of ObjectType
user_portal:
type: integer
description: id of user portal for user portal override setting.
description:
type: string
enabled:
type: boolean
image:
type: string
customFields:
type: array
description: When assigning customFields either a field_id or title can be provided. It is recommended to use the field_id in case there is a field name with a duplicate title.
items:
$ref: "#/components/schemas/CustomFieldFilter"
timestamp_created:
type: string
format: date-time
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
ObjectType:
type: object
properties:
id:
type: integer
readOnly: true
example: 2
title:
type: string
example: Organization
enabled:
type: boolean
example: true
ObjectsValue:
type: object
properties:
id:
type: integer
title:
type: string
PageData:
type: object
description: >
Pagination envelope. The `first_page_url`, `next_page_url` and
`prev_page_url` links preserve the request's `pageSize`, `includeTotal`,
`sortBy` and `sortDir` parameters, so following them keeps the same page
size and sort order.
properties:
current_page:
type: integer
description: The current page.
example: 1
from:
type: integer
description: The start of the range for the page.
example: 1
nullable: true
to:
type: integer
description: The end of the range for the page.
example: 25
nullable: true
per_page:
type: integer
description: The number of items per page.
example: 10
first_page_url:
type: string
description: A URI to the first page.
format: url
example: http://{domain}/api/{endpoint}?page=1
next_page_url:
type: string
description: A URI to the next page.
format: url
example: http://{domain}/api/{endpoint}?page=1
nullable: true
prev_page_url:
type: string
description: A URI to the previous page.
format: url
example: http://{domain}/api/endpoint}?page=1
nullable: true
total:
type: integer
description: Total row count across all pages. Present only when `includeTotal=true` was passed.
example: 142
last_page:
type: integer
description: Last page number. Present only when `includeTotal=true` was passed.
example: 6
path:
type: string
description: Base URL of the paginated endpoint.
last_page_url:
type: string
nullable: true
description: Only returned by endpoints that serialize the paginator directly, and only when includeTotal=true.
links:
type: array
items:
type: object
description: Only returned by endpoints that serialize the paginator directly, and only when includeTotal=true.
ProfileField:
type: object
required:
- type
- enabled
- name
- visibility
- required
- searchable
- registration
- readonly
- group_id
properties:
id:
type: integer
readOnly: true
example: 10
type:
type: string
enum: [text, textarea, select, list, radio, checkbox, country, gender, email, time, date, url, birthdate]
example: '[text, textarea, select, list, radio, checkbox, country, gender, email, time, date, url, birthdate]'
ordering:
type: integer
readOnly: true
enabled:
type: boolean
name:
type: string
visibility:
type: string
example: '[personal, all, admin]'
enum: [personal, all, admin]
required:
type: boolean
searchable:
type: boolean
input_type:
type: string
example: '[text,password]'
enum: [text, password]
registration:
type: boolean
description: If true, the field is available on the registration form
registration_text:
type: string
description: Text that appears on the registration page, alongside the field
readonly:
type: boolean
min_characters:
type: integer
description: Used by input types [text, textarea, email, url]
max_characters:
type: integer
description: Used by input types [text, textarea, email, url]
max_length:
type: integer
description: Used by input types [text, url]
style:
type: string
description: Used by input types [text, textarea, select, list, radio, checkbox, date, url]
options:
type: array
items:
type: string
description: Used by input types [select, list, radio, checkbox]. Note, country and gender have pre-defined options and cannot be changed
size:
type: integer
description: Used by input types [select]
domains_whitelist:
type: array
items:
type: string
description: Used by input types [email]
domains_blacklist:
type: array
items:
type: string
description: Used by input types [email]
date_range_max:
type: string
format: date
description: Used by input types [date, birthdate]
example: 2009-09-01
date_range_min:
type: string
format: date
description: Used by input types [date, birthdate]
example: 2009-09-01
date_format:
type: string
description: |
Used by input types [date, birthdate]. 8 date format characters are available. Dates can be separated with spaces, commas, hyphens, orslashes. Example date is January 2, 2000.
Y - Full numeric representation of a year, e.g. 2000
y - Last two digits of the year, e.g. 00
M - Abbreviated month name, three letters, e.g. Jan
m - Numeric representation of a month, with leading zeroes, e.g. 01
D - Abbreviated day of the month, e.g. Sun
d - Numeric day of the month, e.g. 01
F - Full month name, e.g. January
l - Full weekday name e.g. Sunday
date_type:
type: string
enum: [date, age]
example: '[date,age]'
description: Used by input types [date, birthdate]
fieldcode:
type: string
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this profile field changed.
group_id:
type: integer
description: Id of the profile field group this field belongs to (see GET /profileFields/groups). Required when creating a field.
UserGroupMappingResponse:
type: object
properties:
id:
type: integer
readOnly: true
title:
type: string
example: "Employees of Company X"
field_id:
type: integer
example: 1
field_name:
type: string
example: "Role"
field_values:
type: array
items:
type: string
example: ["employee", "administrator", "manager"]
group_ids:
type: array
items:
type: integer
example: [2570, 199, 52]
UserGroupMapping:
type: object
required:
- group_ids
properties:
id:
type: integer
readOnly: true
title:
type: string
example: "Employees of Company X"
group_ids:
type: array
items:
type: integer
example: [1, 2, 3]
field_id:
type: integer
example: 1
field_values:
type: array
items:
type: string
example: ["employee", "administrator", "manager"]
ProfileFieldGroup:
type: object
required:
- enabled
- name
- visibility
properties:
id:
type: integer
readOnly: true
example: 10
enabled:
type: boolean
name:
type: string
visibility:
type: string
example: '[personal, all, admin]'
enum: [personal, all, admin]
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this profile field group changed.
ordering:
type: integer
PurchaseOrder:
type: object
properties:
id:
type: integer
description: Purchase Order ID
readOnly: true
title:
type: string
maxLength: 200
description: Purchase Order title
purchase_order_number:
type: string
maxLength: 155
nullable: true
description: Purchase Order number
description:
type: string
nullable: true
description: Purchase Order description
initial_amount:
type: number
format: double
nullable: true
description: Initial amount
remaining_balance:
type: number
format: double
nullable: true
description: Remaining balance
currency:
type: object
readOnly: true
description: Currency associated with this purchase order
properties:
id:
type: integer
currency:
type: string
code:
type: string
object_type_id:
type: integer
description: Object Type ID
use_tokens:
type: boolean
description: Whether tokens are used
token_id:
type: integer
nullable: true
description: Token ID
enabled:
type: boolean
description: Whether purchase order is enabled
date_created:
type: string
format: date
nullable: true
description: Creation date (YYYY-MM-DD)
example: "2026-01-15"
date_modified:
type: string
format: date
nullable: true
description: Last modification date (YYYY-MM-DD)
example: "2026-01-20"
deprecated: true
date_expires:
type: string
format: date
nullable: true
description: Expiration date (YYYY-MM-DD)
example: "2026-12-31"
object:
type: object
nullable: true
description: Associated object
custom_fields:
type: array
description: Custom field values
items:
type: object
properties:
field_id:
type: integer
value:
type: string
field_title:
type: string
nullable: true
field_type:
type: string
nullable: true
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this purchase order changed, including related data.
PromoCode:
type: object
properties:
id:
type: integer
readOnly: true
example: 1
description: Promo code ID
title:
type: string
example: "Summer Sale 2024"
description: Promo code title
promo_code:
type: string
example: "SUMMER2024"
description: The actual promo code string
item_discount_unit:
type: string
enum:
- Percent
- Flat
example: "Percent"
description: Discount unit type for item purchases
item_discount_amount:
type: number
format: float
example: 10.00
description: Discount amount for item purchases
initial_discount_unit:
type: string
enum:
- Percent
- Flat
example: "Flat"
description: Discount unit type for initial subscription payment
initial_discount_amount:
type: number
format: float
example: 5.00
description: Discount amount for initial subscription payment
recurring_discount_unit:
type: string
enum:
- Percent
- Flat
example: "Percent"
description: Discount unit type for recurring subscription payments
recurring_discount_amount:
type: number
format: float
example: 15.00
description: Discount amount for recurring subscription payments
active_date:
type: string
format: date
example: "2024-06-01"
nullable: true
description: Date when promo code becomes active (null if not set)
expiration_date:
type: string
format: date
example: "2024-08-31"
nullable: true
description: Date when promo code expires (null if not set)
uses_remaining:
type: integer
example: 100
description: Number of times promo code can still be used
times_used:
type: integer
example: 5
description: Number of times promo code has been used
include_all_courses:
type: boolean
example: true
description: Whether promo code applies to all courses
timestamp_created:
type: string
format: date-time
readOnly: true
example: "2024-01-15 10:30:00"
description: When the promo code was created
timestamp_modified:
type: string
format: date-time
readOnly: true
example: "2024-01-20 14:45:00"
description: When the promo code was last modified
course_ids:
type: array
items:
type: integer
readOnly: true
example: [1, 2, 3]
description: IDs of courses associated with this promo code
plan_ids:
type: array
items:
type: integer
readOnly: true
example: [5, 6]
description: IDs of subscription plans associated with this promo code
Quiz:
type: object
required:
- title
- slug
- required_score
properties:
id:
type: integer
readOnly: true
example: 1
title:
type: string
example: MyQuiz
slug:
type: string
description: Unique URI for use in Search Engine Friendly urls.
pattern: "[a-z-]+"
image:
type: string
format: uri
tries:
type: integer
description: Number of attempts users have to complete the quiz.
remaining_retries:
type: integer
description: Remaining tries.
description:
type: string
example: This is my quiz
course_id:
type: integer
description: Course id of the course this quiz is assigned to.
lesson_id:
type: integer
description: Lesson id of the lesson this quiz is assigned to.
created_by:
type: integer
description: User id of the user who created this quiz.
readOnly: true
created_on:
type: string
format: date
readOnly: true
required_score:
type: number
description: Required score in percentage.
example: 75
type:
type: string
example: quiz
enum:
- quiz
- survey
description: Only accepted on create; ignored on update.
completion_message:
type: string
example: Quiz Completed!
pass_message:
type: string
example: Congratulations, you passed!
fail_message:
type: string
example: Quiz Failed, minimum score is 75%
questions:
type: array
items:
$ref: "#/components/schemas/QuizQuestion"
allow_retries:
type: boolean
duration:
type: integer
description: Time limit for the quiz in minutes. Must be in the range 0-100.
show_overlay:
type: boolean
show_answers:
type: boolean
missed_questions_only:
type: boolean
description: Maps to Allow to Retake Only Incorrect Answers toggle in LMS.
quiz_result:
type: array
items:
type: object
properties:
quizresult_id:
type: integer
point:
type: integer
total_marks:
type: integer
user_id:
type: integer
example: 1625627
quizquestion_id:
type: integer
course_id:
type: integer
lesson_id:
type: integer
enabled:
type: integer
ordering:
type: integer
date:
type: string
format: datetime
answers:
type: string
archive_date:
type: string
format: date
description: Only populated by GET /quizzes; never returned by GET /quiz/{id}/.
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this quiz changed.
show_question_numbers:
type: integer
modified_by:
type: integer
readOnly: true
modified_on:
type: string
format: date-time
readOnly: true
lesson_title:
type: string
readOnly: true
course_title:
type: string
readOnly: true
AssessmentDetail:
type: object
properties:
id:
type: integer
readOnly: true
course_id:
type: integer
lesson_id:
type: integer
title:
type: string
description:
type: string
image:
type: string
enabled:
type: boolean
type:
type: object
properties:
id:
type: integer
label:
type: string
question_bank_id:
type: integer
nullable: true
show_question_numbers:
type: boolean
show_feedback:
type: boolean
show_question_choice_feedback:
type: boolean
show_correct_answer:
type: boolean
is_final:
type: boolean
use_pool:
type: boolean
randomize_answer_order:
type: boolean
pool_size:
type: integer
nullable: true
created_by:
type: integer
timestamp_created:
type: string
format: date-time
readOnly: true
modified_by:
type: integer
timestamp_modified:
type: string
format: date-time
readOnly: true
description: >
Also bumped when the assessment's questions or choices are created,
updated or deleted via the API (including question bank changes for
bank-backed assessments), so timestampModifiedAfter polling detects
content edits.
time_limit_minutes:
type: integer
description: Quiz only
required_passing_score:
type: number
description: Quiz only
allow_retries:
type: boolean
description: Quiz only
number_allowed_retries:
type: integer
description: Quiz only
completion_message:
type: string
description: Quiz only
passed_message:
type: string
description: Quiz only
failed_message:
type: string
description: Quiz only
rating_scale_max:
type: integer
description: Survey only
completed_message:
type: string
description: Survey only
questions:
type: array
description: Included on single assessment detail. Questions include type-specific data (choices, keywords).
items:
type: object
properties:
id:
type: integer
assessment_id:
type: integer
question_bank_id:
type: integer
nullable: true
sequence_number:
type: integer
label:
type: string
media:
type: string
nullable: true
show_feedback:
type: boolean
timestamp_modified:
type: string
format: date-time
nullable: true
description: Mirrors the parent assessment's modified timestamp; questions have no timestamp columns of their own.
type:
type: string
choices:
type: array
description: Multiple choice questions only
items:
type: object
properties:
id:
type: integer
label:
type: string
sequence_number:
type: integer
is_correct:
type: boolean
feedback_text:
type: string
nullable: true
image_url:
type: string
nullable: true
keywords:
type: array
description: Free text questions only
items:
type: object
properties:
id:
type: integer
label:
type: string
variation1:
type: string
nullable: true
variation2:
type: string
nullable: true
variation3:
type: string
nullable: true
feedback_correct:
type: string
nullable: true
feedback_incorrect:
type: string
nullable: true
min_character_count:
type: integer
description: Free text questions only
max_character_count:
type: integer
description: Free text questions only
retry_missed_questions_only:
type: boolean
readOnly: true
description: Quiz assessments only.
horizontal_rating_scale_display:
type: boolean
readOnly: true
description: Survey assessments only.
use_default_scale_labels:
type: boolean
readOnly: true
description: Survey assessments only.
course:
type: object
readOnly: true
properties:
id:
type: integer
title:
type: string
lesson:
type: object
readOnly: true
properties:
id:
type: integer
title:
type: string
AssessmentResultSummary:
type: object
properties:
id:
type: integer
readOnly: true
user_id:
type: integer
assessment_id:
type: integer
assessment_type:
type: string
description: Type of assessment
course_id:
type: integer
lesson_id:
type: integer
assessment_title:
type: string
lesson_title:
type: string
course_title:
type: string
submitted_date:
type: string
format: date-time
score:
type: number
passed:
type: boolean
total_questions:
type: integer
number_correct:
type: integer
user_name:
type: string
archive_date:
type: string
format: date-time
nullable: true
timestamp_created:
type: string
format: date-time
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
AssessmentResultDetail:
allOf:
- $ref: "#/components/schemas/AssessmentResultSummary"
- type: object
properties:
responses:
type: array
description: |
Per-response data. Shape varies by question type. Multi-select multiple choice
questions emit one entry per chosen choice (the same `question_id` will appear
multiple times); consumers must group by `question_id` to reconstruct the answer.
items:
type: object
properties:
question_id:
type: integer
question:
type: string
description: Question label text
question_type:
type: string
enum:
- multiple choice
- multiple choice (multi select)
- free-form text
recorded_timestamp:
type: string
format: date-time
nullable: true
selected_choice:
type: object
nullable: true
description: Present for multiple choice questions
properties:
id:
type: integer
label:
type: string
free_text:
type: string
nullable: true
description: Present for free text questions — the learner's written response
is_correct:
type: boolean
nullable: true
description: "For MC: from choice. For free text: from graded response (null if ungraded)."
QuizQuestion:
type: object
required:
- title
- answer1
- answer2
- correctAnswer
properties:
title:
type: string
example: "Why did foo bar?"
media:
type: string
format: uri
answer1:
type: string
example: "Because baz"
answer2:
type: string
example: "Because couldn't solve fizzbuzz"
answer3:
type: string
example: "Because bar foo"
answer4:
type: string
example: "All of the above"
correctAnswer:
type: integer
description: Index of the correct answer. 0 - answer1 , 1 - answer2, etc.
QuizResponsePayload:
type: object
required:
- user_id
- quiz_id
- course_id
- answers
properties:
user_id:
type: integer
example: 1714926
quiz_id:
type: integer
example: 1234
lesson_id:
type: integer
example: 1234
course_id:
type: integer
example: 1234
answers:
type: array
items:
type: integer
example: [0, 2, 1]
QuizResult:
type: object
properties:
id:
type: integer
readOnly: true
user_id:
type: integer
readOnly: true
quiz_id:
type: integer
format: int64
readOnly: true
answers:
type: array
items:
type: object
properties:
question:
type: string
answer:
type: string
correct:
type: boolean
correctAnswer:
type: string
readOnly: true
submitted_date:
type: string
format: date
readOnly: true
total_questions:
type: integer
readOnly: true
number_correct:
type: integer
readOnly: true
score:
type: number
readOnly: true
passed:
type: boolean
readOnly: true
quiz:
readOnly: true
type: object
$ref: "#/components/schemas/Quiz"
lesson_id:
type: integer
readOnly: true
user_name:
type: string
readOnly: true
archive_date:
type: string
nullable: true
readOnly: true
timestamp_created:
type: string
format: date-time
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
ReportsChecklists:
type: object
properties:
started_count:
type: number
completed_count:
type: number
ReportsChecklistsGroupedByUsergroup:
type: object
description: Map keyed by the numeric user group id.
additionalProperties:
type: object
properties:
group_title:
type: string
description: The title of the group
started_count:
type: number
completed_count:
type: number
ReportsChecklistsGroupedByUser:
type: object
description: Map keyed by the numeric user id.
additionalProperties:
type: object
properties:
started_count:
type: number
completed_count:
type: number
display_name:
type: string
description: The display name of the user
ReportsChecklistsGroupedByChecklist:
type: object
description: Map keyed by the numeric checklist id.
additionalProperties:
type: object
properties:
checklist_title:
type: string
description: The title of the checklist
started_count:
type: number
completed_count:
type: number
ReportsCourses:
type: object
properties:
started_count:
type: number
completed_count:
type: number
ReportsCoursesGroupedByUsergroup:
type: object
description: Map keyed by the numeric user group id.
additionalProperties:
type: object
properties:
group_title:
type: string
description: The title of the group
started_count:
type: number
completed_count:
type: number
ReportsCoursesGroupedByUser:
type: object
description: Map keyed by the numeric user id.
additionalProperties:
type: object
properties:
display_name:
type: string
description: The display name of the user
started_count:
type: number
completed_count:
type: number
ReportsCoursesGroupedByCourse:
type: object
description: Map keyed by the numeric course id.
additionalProperties:
type: object
properties:
course_title:
type: string
description: The course title
started_count:
type: number
completed_count:
type: number
ReportsUsers:
type: object
properties:
login_count:
type: number
active_count:
type: number
ReportsUsersGroupedByUsergroup:
type: object
description: Map keyed by the numeric user group id.
additionalProperties:
type: object
properties:
group_title:
type: string
description: The title of the group
login_count:
type: number
active_count:
type: number
Subscription:
type: object
required:
- title
properties:
id:
type: integer
readOnly: true
example: 1
title:
type: string
published:
type: boolean
private:
type: boolean
featured:
type: boolean
default_sub_length:
type: string
description: Default length of the subscription period. Valid values are 1-15D, 1-12M, and 1-5Y
example: 1D
default_initial_amount:
type: number
description: Amount of money (in USD) that the subscription will cost on signup.
format: float
default_amount:
type: number
description: Amount of money (in USD) that the subscription will cost when the subscription period length has elapsed and the subscription is renewed.
format: float
usergroups:
type: array
items:
type: integer
description: Array of user groups for which this subscription will be available.
description_html:
type: string
description: Plain text or HTML-formatted description that describes the subscription.
description_type:
type: string
description: Description type.
type:
type: string
description:
type: string
timestamp_created:
type: string
format: date-time
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
SubscriptionPayment:
type: object
description: |
A payment recorded against a user's subscription period. `id` is the `hybrid_transaction.id` and is the value the PATCH and DELETE endpoints expect in the URL. `gateway_transaction_id` is the external (e.g. Stripe) reference used for idempotent replay and for look-up via the list endpoint.
properties:
id:
type: integer
readOnly: true
description: The `hybrid_transaction.id`. Use this in PATCH/DELETE URLs.
example: 1234
gateway_transaction_id:
type: string
description: External payment gateway reference (e.g. Stripe `payment_intent_id`).
example: pi_3O8aBcDeFgHiJk001
user_id:
type: integer
example: 42
subscription_id:
type: integer
example: 17
amount:
type: number
format: float
example: 49.99
currency:
type: string
description: ISO-4217 currency code.
example: USD
paid_at:
type: string
description: When the payment was processed (`YYYY-MM-DD HH:MM:SS`).
example: "2026-05-13 14:00:00"
status:
type: string
description: |
Human-readable payment status. Mapped from `axs_pay_transactions.status`.
- `Success` (`SUC`)
- `Voided` (`PLHO`) — soft-deleted via DELETE
- `Refunded` (`REF`)
- `Declined` (`DEC`)
- `Failed` (`FAIL`)
Unknown DB values pass through unchanged.
example: Success
period:
type: object
description: The subscription period this payment covers.
properties:
id:
type: integer
example: 9988
start:
type: string
format: date
example: "2026-05-13"
end:
type: string
format: date
example: "2026-06-13"
status:
type: string
description: |
Human-readable period status. Mapped from `axs_pay_subscription_periods.status`.
- `Paid` (`PAID`)
- `Unpaid` (`NONE`)
- `Partial` (`PART`)
- `Prorated Partial` (`PRO1`)
- `Provisional` (`PRO2`)
- `Free` (`FREE`)
- `Complimentary` (`COMP`)
- `Paused` (`PAUS`)
Unknown DB values pass through unchanged.
example: Paid
SubscribeRequest:
type: object
description: |
Body for `POST /v1/subscription/{id}/subscribe/`. `userIds` is always required.
## Free flow
Plan has `default_amount == 0.00`. Only `userIds` is required; the payment fields are ignored. `userIds` may contain one or many ids. `period_start`/`period_end` are honored when supplied; otherwise the subscription period is derived from the plan's configuration (`default_sub_length`, or the fixed-term end date).
## Paid flow
Supply `gateway_transaction_id` (plus `amount`, `paid_at`, `currency`) alongside `userIds` to register an externally-processed payment. `userIds` must contain exactly one id, and the caller must hold one of `payments:create`/`payments:all`/`all:create`/`all`.
required:
- userIds
properties:
userIds:
type: array
minItems: 1
items:
type: integer
description: |
LMS user ids to subscribe. Always an array — even for a single user. **Must contain exactly one id when `gateway_transaction_id` is supplied.**
example: [1620265, 1620266]
gateway_transaction_id:
type: string
maxLength: 255
description: |
External gateway reference (e.g. Stripe `payment_intent_id`). Must be globally unique across all `axs_pay_transactions.trxn_id` values for this tenant.
example: pi_3O8aBcDeFgHiJk001
amount:
type: number
format: float
description: Amount paid. Must be greater than 0.
example: 49.99
paid_at:
type: string
description: When the payment was processed. Must not be in the future. `YYYY-MM-DD HH:MM:SS`.
example: "2026-05-13 14:00:00"
currency:
type: string
minLength: 3
maxLength: 3
description: ISO-4217 currency code. Must exist in the tenant's `currency.code` table.
example: USD
period_start:
type: string
format: date
description: |
Optional. Start of the subscription period being registered (free flow) or covered by this payment (paid flow). If omitted, a period is derived from the plan's `default_sub_length` starting today. Required when `period_end` is supplied.
example: "2026-05-13"
period_end:
type: string
format: date
description: Optional. End of the subscription period. Required when `period_start` is supplied; must be strictly after `period_start`.
example: "2026-06-13"
SubscriptionPaymentCreate:
type: object
required:
- gateway_transaction_id
- amount
- paid_at
- currency
properties:
gateway_transaction_id:
type: string
maxLength: 255
description: |
External gateway reference (e.g. Stripe `payment_intent_id`). Must be globally unique across all `axs_pay_transactions.trxn_id` values for this tenant. Acts as the idempotency key — replaying the same `(userId, subId, gateway_transaction_id)` returns the existing record with HTTP 200 instead of 201.
example: pi_3O8aBcDeFgHiJk001
amount:
type: number
format: float
description: Amount paid. Must be greater than 0.
example: 49.99
paid_at:
type: string
description: When the payment was processed. Must not be in the future. `YYYY-MM-DD HH:MM:SS`.
example: "2026-05-13 14:00:00"
currency:
type: string
minLength: 3
maxLength: 3
description: ISO-4217 currency code.
example: USD
period_start:
type: string
format: date
description: |
Optional. Start of the subscription period this payment covers. If omitted, a period is derived from the subscription's `period_length` starting today (or at the end of the existing covering period). Required when `period_end` is supplied.
example: "2026-05-13"
period_end:
type: string
format: date
description: Optional. End of the subscription period. Required when `period_start` is supplied; must be strictly after `period_start`.
example: "2026-06-13"
SubscriptionPaymentUpdate:
type: object
description: |
Correct one or more fields on an existing payment. All fields are optional; only the fields supplied are updated. The endpoint does not support reversing a payment — use DELETE for that.
properties:
gateway_transaction_id:
type: string
maxLength: 255
description: Corrected external gateway reference.
amount:
type: number
format: float
description: Corrected amount. Must be greater than 0.
paid_at:
type: string
description: Corrected payment timestamp. Must not be in the future. `YYYY-MM-DD HH:MM:SS`.
UserSubscription:
type: object
properties:
id:
type: integer
readOnly: true
user_id:
type: integer
readOnly: true
cancel_date:
type: string
readOnly: true
plan_id:
type: integer
readOnly: true
status:
type: string
readOnly: true
next_payment_date:
type: string
recurring_amount:
type: string
readOnly: true
period_length:
type: string
readOnly: true
Survey:
type: object
properties:
id:
type: integer
readOnly: true
example: 1
title:
type: string
example: MySurvey
description:
type: string
example: This is my survey
questions:
type: array
items:
type: object
properties:
id:
type: string
readOnly: true
example: 1624487827DHmcGo
question_type:
type: string
description: Possible values are textbox, textarea, multiplechoice, multiplechoice_multiselect, and likert.
example: multiplechoice
question:
type: string
example: What is love?
multiple_choice_options:
type: string
description: Newline separated list of options for multiplechoice and multiplechoice_multiselect question types.
example: Baby\r\ndon't\r\nhurt\r\nme
params:
type: object
properties:
likert_labels:
type: string
description: Possible values are 'custom' or 'default'.
label_1:
type: string
example: Strongly Disagree
label_2:
type: string
example: Disagree
label_3:
type: string
example: Undecided
label_4:
type: string
example: Agree
label_5:
type: string
example: Strongly Agree
label_6:
type: string
label_7:
type: string
label_8:
type: string
label_9:
type: string
label_10:
type: string
label_11:
type: string
rating_number:
type: string
description: Likert scale number, possible values are 5, 7, or 11.
example: 0
rating_direction:
type: string
description: Controls the display of likert labels in quiz. Possible values are 'vertical' or 'horizontal'.
custom_completed_message:
type: string
description: Toggle for using either the default or user provided completion message. Possible values are 'custom' or 'default'.
completed_message:
type: string
description: If custom_completed_message = custom then this message is used.
enabled:
type: boolean
description: Defines the published (also called enabled) status of the survey.
modified_date:
type: string
example: "2022-12-06 12:54:43"
created_on:
type: string
example: "2022-12-06 12:54:43"
created_by:
type: integer
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
timestamp_created:
type: string
format: date-time
readOnly: true
SurveyResponse:
type: object
required:
- survey_id
- user_id
- question_id
- question_type
- question
- answer
properties:
id:
type: integer
readOnly: true
example: 1
survey_id:
type: integer
user_id:
type: integer
description: id of the user that submitted the response.
example: 1623570
lesson_id:
type: integer
description: id of the lesson that this survey was submitted in.
activity_id:
type: string
description: id of the corresponding lesson student activity used to complete the survey, it should be one of the activities inside lesson with id = lesson_id.
example: 1656638001Xehtvk
event_id:
type: integer
description: id of the event that this survey was completed as a part of. Surveys are either completed inside lessons or events.
question_id:
type: string
example: 1659494905ZHLhxu
question_type:
type: string
description: the question type can be likert, multiplechoice, multiplechoice_multiselect, textbox or textarea.
enum:
- likert
- multiplechoice
- textarea
- multiplechoice_multiselect
- textbox
question:
type: string
example: Rate your learning experience on a scale from 1-5
answer:
type: string
example: 5
score:
type: integer
description: Used for question_type = likert, the corresponding likert score for the selected response.
timestamp_created:
type: string
format: date-time
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
submitted_date:
type: string
readOnly: true
archive_date:
type: string
nullable: true
readOnly: true
Tag:
type: object
properties:
id:
type: integer
readOnly: true
title:
type: string
readOnly: true
enabled:
type: boolean
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
Instructor:
type: object
properties:
id:
type: integer
readOnly: true
example: 1
name:
type: string
example: John Doe
title:
type: string
example: Lead Instructor
image:
type: string
example: images/instructors/photo.jpg
enabled:
type: boolean
example: true
user_id:
type: integer
nullable: true
example: 123
use_tovuti_profile:
type: boolean
example: false
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this instructor changed, including related data.
Teacher:
type: object
properties:
teacher_id:
type: integer
title:
type: string
user_id:
type: integer
Team:
type: object
required:
- title
- member_type
properties:
id:
type: integer
readOnly: true
example: 1
title:
type: string
example: MyUserTeam
member_type:
type: string
description: Possible values are 'individuals' or 'groups'.
example: groups
enum:
- individuals
- groups
description:
type: string
example: Team description
enabled:
type: boolean
example: true
description: Same as 'published'
team_lead:
type: array
items:
type: integer
description: Set of user ids. Users with ids in this set are team leads.
use_lead_groups:
type: boolean
example: true
default: true
description: When set to true, the lead_user_groups attribute can be set
lead_user_groups:
type: array
items:
type: integer
description: An array of usergroup IDs
user_ids:
type: array
items:
type: integer
description: Set of user ids. Users with these ids will be added as team members. Only used when member_type = 'individuals'.
user_groups:
type: array
items:
type: integer
description: Set of user group ids. Users in these groups will be added as team members. Only used when member_type = 'groups'.
date_created:
type: string
format: date
readOnly: true
allow_adding_users:
type: boolean
description: If set to 'true' team leads will be able to add users to teams they are leaders of.
allow_removing_users_from_team:
type: boolean
description: If set to 'true' team leads will be able to remove users from teams they are leaders of.
allow_removing_users_from_system:
type: boolean
description: If set to 'true' team leads will be able to delete users in their team completely.
allow_managing_users_groups:
type: boolean
description: If set to 'true' team leads will be able to add or remove usergroups that are a part of the teams they are leaders of.
assignable_user_groups:
type: array
items:
type: integer
description: Set of user group ids that team leads can assign members to.
allow_assigning_courses:
type: boolean
description: If set to 'true' team leads will be able to assign team members to course in assignable_course_ids.
assignable_course_ids:
type: array
items:
type: integer
description: Set of course ids that team leads can enroll team members in.
allow_assigning_events:
type: boolean
description: If set to 'true' team leads will be able to register team members for events.
allow_assigning_learning_paths:
type: boolean
description: If set to 'true' team leads will be able to assign learning paths to teanm members.
assignable_learning_path_ids:
type: array
items:
type: integer
description: Set of learning path ids that team leads can enroll team members in.
allow_assigning_media_items:
type: boolean
description: >
If set to 'true' team leads will be able to create media item assignments for
team members from the media items in assignable_media_item_ids. Only takes
effect on sites with media item assignments enabled; the value is stored either way.
assignable_media_item_ids:
type: array
items:
type: integer
description: >
Set of media item ids that team leads can assign to team members. An empty
array allows every enabled media item. Team leads also need visibility
access to a media item to assign it. On update, omit this field to leave
the list unchanged; send an empty array to clear it.
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this team changed.
created_by:
type: integer
readOnly: true
User:
type: object
properties:
id:
type: integer
format: int64
readOnly: true
example: 1714926
name:
type: string
example: John Doe
username:
type: string
example: johndoe
email:
type: string
example: johndoe@gmail.com
password:
type: string
example: password100
writeOnly: true
userGroupIds:
type: array
items:
type: integer
description: Ids of usergroups this user belongs to.
userTeamIds:
type: array
items:
type: integer
description: Ids of userteams this user belongs to. userTeamIds can only be assigned for teams with member_type = 'individuals'.
enrolledCourseIds:
type: array
items:
type: integer
requireReset:
type: boolean
description: If 'true' the user will be required to reset their password on their next login.
registerDate:
readOnly: true
type: string
format: date
lastvisitDate:
readOnly: true
type: string
format: date
customFields:
type: array
description: When assigning customFields either a field_id or title can be provided. It is recommended to use the field_id in case there is a field name with a duplicate title.
items:
$ref: '#/components/schemas/CustomFieldValueResponse'
objects:
type: array
description: Array of Objects associated to user.
items:
$ref: "#/components/schemas/ObjectsValue"
accessLevels:
readOnly: true
type: array
items:
type: integer
status:
type: string
description: The current enabled/disabled status of the user. Possible values are active or disabled.
example: active
timestamp_modified:
type: string
format: date-time
readOnly: true
UserCourseProgress:
type: object
properties:
user_id:
type: integer
readOnly: true
course_id:
type: integer
language:
type: string
lessons_completed_list:
type: array
items:
type: integer
lessons_total_list:
type: array
items:
type: integer
score:
type: number
progress:
type: number
format: float
date_started:
type: string
format: date
date_last_activity:
type: string
format: date
date_completed:
type: string
format: date
date_due:
type: string
format: date
archive_date:
type: string
format: date
lessons:
type: object
description: Lessons list.
example: {"activities": [{"activity_id": "1619209659BqkVD2", "user_id": "User ID", "activity_name": "Name", "activity_type": "interactive", "student_response": "Recorded student response for activity", "activity_status": "in progress"}]}
id:
type: integer
readOnly: true
status:
type: string
readOnly: true
user_name:
type: string
readOnly: true
course_title:
type: string
readOnly: true
course_enabled:
type: integer
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
UserGroup:
type: object
properties:
id:
type: integer
readOnly: true
example: 2
title:
type: string
example: MyUserGroup
parent_id:
type: integer
description: User group id of the parent group.
example: 1
userIds:
type: array
items:
type: integer
description: User ids of users that are in this group.
links:
type: object
readOnly: true
properties:
parent_url:
type: string
children_url:
type: string
descendants_url:
type: string
lft:
type: integer
description: Start of range that contains descendant user groups. See https://en.wikipedia.org/wiki/Nested_set_model for more info.
readOnly: true
rgt:
type: integer
description: End of range that contains descendant user groups. See https://en.wikipedia.org/wiki/Nested_set_model for more info.
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
UserPayload:
type: object
required:
- name
- username
- email
- password
properties:
id:
type: integer
format: int64
readOnly: true
example: 1714926
name:
type: string
example: John Doe
username:
type: string
example: johndoe
email:
type: string
example: johndoe@gmail.com
password:
type: string
example: password100
writeOnly: true
userGroupIds:
type: array
items:
type: integer
description: Ids of usergroups this user belongs to.
userTeamIds:
type: array
items:
type: integer
description: Ids of userteams this user belongs to. userTeamIds can only be assigned for teams with member_type = 'individuals'.
enrolledCourseIds:
type: array
items:
type: integer
requireReset:
type: boolean
description: If 'true' the user will be required to reset their password on their next login.
registerDate:
readOnly: true
type: string
format: date
lastvisitDate:
readOnly: true
type: string
format: date
customFields:
type: array
description: When assigning customFields either a field_id or title can be provided. It is recommended to use the field_id in case there is a field name with a duplicate title.
items:
$ref: '#/components/schemas/CustomFieldFilter'
objectIds:
type: array
description: Array of Objects Ids.
items:
type: integer
accessLevels:
readOnly: true
type: array
items:
type: integer
status:
type: string
enum: [active, disabled]
example: '[active, disabled]'
# ==========================================
# Assessment Schemas
# ==========================================
QuestionBank:
type: object
properties:
id:
type: integer
readOnly: true
example: 1
label:
type: string
example: "Math Fundamentals Question Bank"
description:
type: string
nullable: true
example: "Collection of basic math questions"
enabled:
type: boolean
example: true
created_by:
type: integer
nullable: true
example: 123
created_timestamp:
type: string
format: date-time
readOnly: true
modified_by:
type: integer
nullable: true
example: 456
modified_timestamp:
type: string
format: date-time
readOnly: true
description: >
Also bumped when the bank's questions or choices are created, updated
or deleted via the API. Bank changes cascade to assessments drawing
from the bank, so timestampModifiedAfter polling on assessments
detects them too.
questions:
type: array
readOnly: true
items:
$ref: "#/components/schemas/Question"
QuestionBankCreate:
type: object
required:
- label
properties:
label:
type: string
example: "Math Fundamentals Question Bank"
description:
type: string
nullable: true
example: "Collection of basic math questions"
enabled:
type: boolean
default: true
QuestionBankUpdate:
type: object
properties:
label:
type: string
example: "Updated Question Bank"
description:
type: string
nullable: true
enabled:
type: boolean
modified_by:
type: integer
nullable: true
Question:
type: object
properties:
id:
type: integer
readOnly: true
example: 1
assessment_id:
type: integer
nullable: true
example: 5
question_bank_id:
type: integer
nullable: true
example: 3
sequence_number:
type: integer
default: 0
example: 1
label:
type: string
example: "What is 2 + 2?"
media:
type: string
nullable: true
example: "https://example.com/image.jpg"
show_feedback:
type: boolean
default: false
timestamp_modified:
type: string
format: date-time
readOnly: true
nullable: true
example: "2026-08-26 15:43:26"
description: >
Questions have no timestamp columns of their own; question and choice
edits bump the parent assessment (or question bank), so this mirrors the
parent's modified timestamp - a "last changed no later than" value.
type:
type: object
readOnly: true
properties:
id:
type: integer
example: 1
label:
type: string
example: "multiple choice"
choices:
type: array
readOnly: true
description: Multiple choice questions only
items:
$ref: "#/components/schemas/QuestionChoice"
keywords:
type: array
readOnly: true
description: Free text questions only
items:
type: object
properties:
id:
type: integer
label:
type: string
variation1:
type: string
nullable: true
variation2:
type: string
nullable: true
variation3:
type: string
nullable: true
feedback_correct:
type: string
nullable: true
feedback_incorrect:
type: string
nullable: true
min_character_count:
type: integer
description: Free text questions only
max_character_count:
type: integer
description: Free text questions only
QuestionCreate:
type: object
required:
- label
- type_id
properties:
label:
type: string
example: "What is 2 + 2?"
type_id:
type: integer
example: 1
sequence_number:
type: integer
default: 0
media:
type: string
nullable: true
show_feedback:
type: boolean
default: false
choices:
type: array
items:
type: object
required:
- label
- sequence_number
properties:
label:
type: string
example: "4"
sequence_number:
type: integer
example: 1
is_correct:
type: boolean
default: false
feedback_text:
type: string
nullable: true
QuestionCreateIndependent:
type: object
required:
- label
- type_id
properties:
label:
type: string
example: "What is 2 + 2?"
type_id:
type: integer
example: 1
assessment_id:
type: integer
nullable: true
example: 5
description: "Either assessment_id or question_bank_id must be provided (mutually exclusive)"
question_bank_id:
type: integer
nullable: true
example: 3
description: "Either assessment_id or question_bank_id must be provided (mutually exclusive)"
sequence_number:
type: integer
default: 0
media:
type: string
nullable: true
show_feedback:
type: boolean
default: false
choices:
type: array
items:
type: object
required:
- label
- sequence_number
properties:
label:
type: string
example: "4"
sequence_number:
type: integer
example: 1
is_correct:
type: boolean
default: false
feedback_text:
type: string
nullable: true
QuestionUpdate:
type: object
properties:
label:
type: string
type_id:
type: integer
sequence_number:
type: integer
media:
type: string
nullable: true
show_feedback:
type: boolean
QuestionChoice:
type: object
properties:
id:
type: integer
readOnly: true
example: 1
question_id:
type: integer
example: 5
label:
type: string
example: "4"
sequence_number:
type: integer
example: 1
is_correct:
type: boolean
example: true
static_sequence:
type: boolean
nullable: true
example: false
feedback_text:
type: string
nullable: true
example: "Correct!"
image_url:
type: string
nullable: true
example: "https://example.com/image.png"
QuestionChoiceCreate:
type: object
required:
- label
- sequence_number
properties:
label:
type: string
example: "4"
sequence_number:
type: integer
example: 1
is_correct:
type: boolean
default: false
feedback_text:
type: string
nullable: true
QuestionChoiceUpdate:
type: object
properties:
label:
type: string
sequence_number:
type: integer
is_correct:
type: boolean
feedback_text:
type: string
nullable: true
CustomFieldFilter:
type: object
required:
- value
properties:
field_id:
type: integer
description: Id of the profile field. Preferred over title.
title:
type: string
description: Title of the profile field; use field_id when titles are ambiguous.
value:
type: string
description: Value to match/assign. % wildcards supported when filtering.
CustomFieldValueResponse:
type: object
properties:
field_id:
type: integer
readOnly: true
value:
type: string
readOnly: true
field_title:
type: string
readOnly: true
field_type:
type: string
readOnly: true
AwardUpdate:
type: object
properties:
id:
type: integer
readOnly: true
example: 1
title:
type: string
example: Badge of Awesomeness
type:
type: string
description: Can be badge, certificate, or milestone.
example: badge
enum:
- badge
- certificate
- milestone
certificate_type:
type: string
enum:
- internal
- external
default: internal
description: External certificates have no requirements
example: internal
description:
type: string
example: This badge is awesome!
maxLength: 50
enabled:
type: boolean
badge_hover:
type: string
example: Badge of Awesomeness
share_award_page:
type: boolean
expiration_type:
type: string
description: Type of time period after which the certificate will expire. Possible values are "year", "month", "week", "day".
example: year|month|week|day
expiration_classification:
type: string
description: Type of award expiration. Possible values are "static", "dynamic", "none".
example: static|dynamic|none
expiration_date:
type: string
format: date
description: Date of static award expiration
example: '2024-01-01 16:08:08'
expiration_amount:
type: integer
description: The number of [expiration_type]s that will need to pass before this award expires.
requirement_type:
type: string
description: Set this to "assigned" to assign the certificate to a specific user or set of users, or set to "conditional" to only award the certificate after a specific set of requirements are met.
example: conditional|assigned
user_can_lose_badge:
type: boolean
description: If true if the user will be able to lose their award.
certificate_id:
type: integer
description: The certificate template this award is associated with. Only used if type = 'certificate'.
requirements_all:
type: boolean
description: Only needed when requirement_type is set to "conditional". Set this to true if all requirements must be met, or false if any subset of them can be met to award the certificate.
user_list:
type: array
items:
type: integer
description: Array of user ids to assign the award to, only used when award type = "assigned".
usergroup_actions:
type: boolean
description: If set to true, add the users who were awarded the certificate to usergroups.
add_usergroups:
type: array
items:
type: integer
description: Array of user group ids to add award recipients to.
remove_usergroups:
type: array
items:
type: integer
description: Array of user group ids to remove award recipients from.
points_actions:
type: boolean
description: If set to true, points are awarded upon attainment of the award.
points_category:
type: integer
description: Id of points category that points should be assigned under.
points:
type: integer
description: The number of points to be awarded on certificate attainment.
requirements:
type: array
items:
$ref: "#/components/schemas/AwardRequirement"
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this award changed.
created_by:
type: integer
readOnly: true
created_on:
type: string
format: date-time
readOnly: true
description: Same shape as Award but with no required fields - all fields are optional on update.
TeamUpdate:
type: object
properties:
id:
type: integer
readOnly: true
example: 1
title:
type: string
example: MyUserTeam
member_type:
type: string
description: Possible values are 'individuals' or 'groups'.
example: groups
enum:
- individuals
- groups
description:
type: string
example: Team description
enabled:
type: boolean
example: true
description: Same as 'published'
team_lead:
type: array
items:
type: integer
description: Set of user ids. Users with ids in this set are team leads.
use_lead_groups:
type: boolean
example: true
default: true
description: When set to true, the lead_user_groups attribute can be set
lead_user_groups:
type: array
items:
type: integer
description: An array of usergroup IDs
user_ids:
type: array
items:
type: integer
description: Set of user ids. Users with these ids will be added as team members. Only used when member_type = 'individuals'.
user_groups:
type: array
items:
type: integer
description: Set of user group ids. Users in these groups will be added as team members. Only used when member_type = 'groups'.
date_created:
type: string
format: date
readOnly: true
allow_adding_users:
type: boolean
description: If set to 'true' team leads will be able to add users to teams they are leaders of.
allow_removing_users_from_team:
type: boolean
description: If set to 'true' team leads will be able to remove users from teams they are leaders of.
allow_removing_users_from_system:
type: boolean
description: If set to 'true' team leads will be able to delete users in their team completely.
allow_managing_users_groups:
type: boolean
description: If set to 'true' team leads will be able to add or remove usergroups that are a part of the teams they are leaders of.
assignable_user_groups:
type: array
items:
type: integer
description: Set of user group ids that team leads can assign members to.
allow_assigning_courses:
type: boolean
description: If set to 'true' team leads will be able to assign team members to course in assignable_course_ids.
assignable_course_ids:
type: array
items:
type: integer
description: Set of course ids that team leads can enroll team members in.
allow_assigning_events:
type: boolean
description: If set to 'true' team leads will be able to register team members for events.
allow_assigning_learning_paths:
type: boolean
description: If set to 'true' team leads will be able to assign learning paths to teanm members.
assignable_learning_path_ids:
type: array
items:
type: integer
description: Set of learning path ids that team leads can enroll team members in.
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this team changed.
created_by:
type: integer
readOnly: true
description: Same shape as Team but with no required fields - all fields are optional on update.
CommunityGroupUpdate:
type: object
properties:
id:
type: integer
readOnly: true
name:
type: string
published:
type: boolean
enable_user_groups:
type: boolean
owner_id:
type: integer
readOnly: true
description:
type: string
users:
type: array
items:
type: integer
user_groups:
type: array
items:
type: integer
created:
type: string
format: date-time
readOnly: true
description: Same shape as CommunityGroup but with no required fields - all fields are optional on update.
UserPayloadUpdate:
type: object
properties:
id:
type: integer
format: int64
readOnly: true
example: 1714926
name:
type: string
example: John Doe
username:
type: string
example: johndoe
email:
type: string
example: johndoe@gmail.com
password:
type: string
example: password100
writeOnly: true
userGroupIds:
type: array
items:
type: integer
description: Ids of usergroups this user belongs to.
userTeamIds:
type: array
items:
type: integer
description: Ids of userteams this user belongs to. userTeamIds can only be assigned for teams with member_type = 'individuals'.
enrolledCourseIds:
type: array
items:
type: integer
requireReset:
type: boolean
description: If 'true' the user will be required to reset their password on their next login.
registerDate:
readOnly: true
type: string
format: date
lastvisitDate:
readOnly: true
type: string
format: date
customFields:
type: array
description: When assigning customFields either a field_id or title can be provided. It is recommended to use the field_id in case there is a field name with a duplicate title.
items:
$ref: '#/components/schemas/CustomFieldFilter'
objectIds:
type: array
description: Array of Objects Ids.
items:
type: integer
accessLevels:
readOnly: true
type: array
items:
type: integer
status:
type: string
enum: [active, disabled]
example: '[active, disabled]'
# ==========================================
# Assessment Schemas
# ==========================================
description: Same shape as UserPayload but with no required fields - all fields are optional on update.
ProfileFieldUpdate:
type: object
properties:
id:
type: integer
readOnly: true
example: 10
type:
type: string
enum: [text, textarea, select, list, radio, checkbox, country, gender, email, time, date, url, birthdate]
example: '[text, textarea, select, list, radio, checkbox, country, gender, email, time, date, url, birthdate]'
ordering:
type: integer
readOnly: true
enabled:
type: boolean
name:
type: string
visibility:
type: string
example: '[personal, all, admin]'
enum: [personal, all, admin]
required:
type: boolean
searchable:
type: boolean
input_type:
type: string
example: '[text,password]'
enum: [text, password]
registration:
type: boolean
description: If true, the field is available on the registration form
registration_text:
type: string
description: Text that appears on the registration page, alongside the field
readonly:
type: boolean
min_characters:
type: integer
description: Used by input types [text, textarea, email, url]
max_characters:
type: integer
description: Used by input types [text, textarea, email, url]
max_length:
type: integer
description: Used by input types [text, url]
style:
type: string
description: Used by input types [text, textarea, select, list, radio, checkbox, date, url]
options:
type: array
items:
type: string
description: Used by input types [select, list, radio, checkbox]. Note, country and gender have pre-defined options and cannot be changed
size:
type: integer
description: Used by input types [select]
domains_whitelist:
type: array
items:
type: string
description: Used by input types [email]
domains_blacklist:
type: array
items:
type: string
description: Used by input types [email]
date_range_max:
type: string
format: date
description: Used by input types [date, birthdate]
example: 2009-09-01
date_range_min:
type: string
format: date
description: Used by input types [date, birthdate]
example: 2009-09-01
date_format:
type: string
description: |
Used by input types [date, birthdate]. 8 date format characters are available. Dates can be separated with spaces, commas, hyphens, orslashes. Example date is January 2, 2000.
Y - Full numeric representation of a year, e.g. 2000
y - Last two digits of the year, e.g. 00
M - Abbreviated month name, three letters, e.g. Jan
m - Numeric representation of a month, with leading zeroes, e.g. 01
D - Abbreviated day of the month, e.g. Sun
d - Numeric day of the month, e.g. 01
F - Full month name, e.g. January
l - Full weekday name e.g. Sunday
date_type:
type: string
enum: [date, age]
example: '[date,age]'
description: Used by input types [date, birthdate]
fieldcode:
type: string
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this profile field changed.
group_id:
type: integer
description: Id of the profile field group this field belongs to (see GET /profileFields/groups). Required when creating a field.
description: Same shape as ProfileField but with no required fields - all fields are optional on update.
ProfileFieldGroupUpdate:
type: object
properties:
id:
type: integer
readOnly: true
example: 10
enabled:
type: boolean
name:
type: string
visibility:
type: string
example: '[personal, all, admin]'
enum: [personal, all, admin]
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this profile field group changed.
ordering:
type: integer
description: Same shape as ProfileFieldGroup but with no required fields - all fields are optional on update.
UserGroupMappingUpdate:
type: object
properties:
id:
type: integer
readOnly: true
title:
type: string
example: "Employees of Company X"
group_ids:
type: array
items:
type: integer
example: [1, 2, 3]
field_id:
type: integer
example: 1
field_values:
type: array
items:
type: string
example: ["employee", "administrator", "manager"]
description: Same shape as UserGroupMapping but with no required fields - all fields are optional on update.
CourseUpdate:
type: object
properties:
id:
type: integer
readOnly: true
title:
type: string
example: MyCourse
slug:
type: string
description: Unique URI for use in Search Engine Friendly urls.
pattern: "[a-z-]+"
coursescategory_id:
type: integer
format: int64
description: Id of the course category this course belongs to.
courses_sub_categories_ids:
type: array
items:
type: integer
description: Comma-separated list of course category ids that this course belongs to.
description:
type: string
short_description:
type: string
readOnly: true
image:
type: string
video_url:
type: string
featured_course:
type: boolean
price:
type: number
format: float
available_to_purchase:
type: boolean
enabled:
type: boolean
registrants:
readOnly: true
type: array
items:
type: integer
external_link:
type: string
format: url
final_course_survey:
nullable: true
description: Set to null to remove the final course survey from the course.
type: object
properties:
id:
type: integer
survey_title:
type: string
survey_instructions:
type: string
content_expires:
type: boolean
expiration_date:
type: string
format: date
custom_id:
type: string
required_for_completion:
type: boolean
customFields:
type: array
description: When assigning customFields either a field_id or title can be provided. It is recommended to use the field_id in case there is a field name with a duplicate title.
items:
$ref: '#/components/schemas/CustomFieldFilter'
lessons:
type: number
format: int
readOnly: true
description: The number of lessons in the course.
ordering:
type: number
format: int
readOnly: true
description: Used when displaying multiple courses.
view_access_type:
type: string
example: none
description: 'Visibility Permission Type. Note: "list" targets specific users and "user" targets user groups.'
enum:
- none
- list
- user
- access
register_access_type:
type: string
example: none
description: 'Registration Permission Type. Note: "list" targets specific users and "user" targets user groups.'
enum:
- none
- list
- user
- access
view_access_groups:
type: array
items:
type: integer
description: array of group ids. Required if view_access_type is user.
view_access_users:
type: array
items:
type: integer
description: array of user ids. Required if view_access_type is list.
view_access_levels:
type: array
items:
type: integer
description: array of access level ids. Required if view_access_type is access.
register_access_groups:
type: array
items:
type: integer
description: array of group ids. Required if register_access_type is user.
register_access_users:
type: array
items:
type: integer
description: array of user ids. Required if register_access_type is list.
register_access_levels:
type: array
items:
type: integer
description: array of access level ids. Required if register_access_type is access.
multilingual_overrides:
type: object
items:
type: object
description: 'An object with multilingual override data in the form { "fr": { "use": 1, "title": "French Title", ...} }. Overrides are only included if enabled (use = 1).'
use_library_content:
type: boolean
description: Specifies if a SCORM (or bizlibrary) package is used for this course
library_content_type:
type: string
description: Either 'bizlibrary' or 'scorm'
bizlibrary_content_title:
type: string
bizlibrary_content_id:
type: string
scorm_id:
type: integer
scorm_title:
type: string
locked:
type: integer
use_due_date:
type: boolean
readOnly: true
hard_due_date:
type: boolean
readOnly: true
due_date_type:
type: string
readOnly: true
description: static|dynamic
example: static|dynamic
due_static_date:
type: string
format: date
readOnly: true
due_dynamic_number:
type: integer
readOnly: true
due_dynamic_unit:
type: string
readOnly: true
description: minute|hour|day|week|month|year
example: minute|hour|day|week|month|year
open_date:
type: string
format: date
readOnly: true
close_date:
type: string
format: date
readOnly: true
visible_before_open:
type: boolean
readOnly: true
visible_after_close:
type: boolean
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this course changed, including related data such as lessons or assignments.
course_sub_title:
type: string
readOnly: true
ref_url:
type: string
readOnly: true
pricing_modifiers:
type: object
readOnly: true
created_on:
type: string
format: date-time
readOnly: true
modified_on:
type: string
format: date-time
readOnly: true
events:
type: array
readOnly: true
items:
type: object
properties:
id:
type: integer
title:
type: string
restrict_event_registrations:
type: integer
readOnly: true
allow_to_regsister_all_events:
type: integer
readOnly: true
description: 'Note: the misspelling is the actual field name returned by the API.'
event_registration_limit:
type: integer
readOnly: true
event_checkin_required:
type: integer
readOnly: true
event_registration_required:
type: integer
readOnly: true
description: Same shape as Course but with no required fields - all fields are optional on update.
CourseCategoryUpdate:
type: object
properties:
id:
type: integer
readOnly: true
title:
type: string
parent_id:
type: integer
description: The id of the parent course category. 0 for no parent.
slug:
type: string
description: Unique URI for use in Search Engine Friendly urls.
pattern: "[a-z-]+"
enabled:
type: boolean
view_access_type:
type: string
example: none|list|user|access
description: Visibility Permission Type.
view_access_groups:
type: array
items:
type: integer
description: array of group ids. Required if view_access_type is user.
view_access_users:
type: array
items:
type: integer
description: array of user ids. Required if view_access_type is list.
view_access_levels:
type: array
items:
type: integer
description: array of access level ids. Required if view_access_type is access.
multilingual_overrides:
type: object
items:
type: object
description: 'An object with multilingual override data in the form { "fr": { "use": 1, "title": "French Title", ...} } . Overrides are only included if enabled (use = 1).'
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this course category changed.
description: Same shape as CourseCategory but with no required fields - all fields are optional on update.
LessonInsertUpdate:
type: object
properties:
title:
type: string
description: Title of Lesson.
example: Introduction to Quantum Physics
image:
type: string
description: Image URL.
example: http://example.com/image.jpg
description:
type: string
description: Lesson description.
example: Lesson description text
lesson_type:
type: integer
description: Lesson Type.
example: 0 - Public, 1 - Access Only
language:
type: string
description: Language code.
example: en-GB|pt-BR
published:
type: boolean
description: Lesson publish status.
example: true|false
quiz_prerequisite_setting:
type: boolean
description: Unlock after quiz.
example: true|false
award_points:
type: integer
description: Number of Award points.
example: 10000
prerequisite_quizzes:
type: array
example: [1, 2, 4]
items:
type: integer
teacher_id:
type: integer
description: Teacher ID.
deprecated: true
teacher_ids:
type: array
items:
type: integer
description: Teacher IDs.
course_id:
type: integer
description: Course ID.
description: Same shape as LessonInsert but with no required fields - all fields are optional on update.
QuizUpdate:
type: object
properties:
id:
type: integer
readOnly: true
example: 1
title:
type: string
example: MyQuiz
slug:
type: string
description: Unique URI for use in Search Engine Friendly urls.
pattern: "[a-z-]+"
image:
type: string
format: uri
tries:
type: integer
description: Number of attempts users have to complete the quiz.
remaining_retries:
type: integer
description: Remaining tries.
description:
type: string
example: This is my quiz
course_id:
type: integer
description: Course id of the course this quiz is assigned to.
lesson_id:
type: integer
description: Lesson id of the lesson this quiz is assigned to.
created_by:
type: integer
description: User id of the user who created this quiz.
readOnly: true
created_on:
type: string
format: date
readOnly: true
required_score:
type: number
description: Required score in percentage.
example: 75
type:
type: string
example: quiz
enum:
- quiz
- survey
description: Only accepted on create; ignored on update.
completion_message:
type: string
example: Quiz Completed!
pass_message:
type: string
example: Congratulations, you passed!
fail_message:
type: string
example: Quiz Failed, minimum score is 75%
questions:
type: array
items:
$ref: "#/components/schemas/QuizQuestion"
allow_retries:
type: boolean
duration:
type: integer
description: Time limit for the quiz in minutes. Must be in the range 0-100.
show_overlay:
type: boolean
show_answers:
type: boolean
missed_questions_only:
type: boolean
description: Maps to Allow to Retake Only Incorrect Answers toggle in LMS.
quiz_result:
type: array
items:
type: object
properties:
quizresult_id:
type: integer
point:
type: integer
total_marks:
type: integer
user_id:
type: integer
example: 1625627
quizquestion_id:
type: integer
course_id:
type: integer
lesson_id:
type: integer
enabled:
type: integer
ordering:
type: integer
date:
type: string
format: datetime
answers:
type: string
archive_date:
type: string
format: date
description: Only populated by GET /quizzes; never returned by GET /quiz/{id}/.
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this quiz changed.
show_question_numbers:
type: integer
modified_by:
type: integer
readOnly: true
modified_on:
type: string
format: date-time
readOnly: true
lesson_title:
type: string
readOnly: true
course_title:
type: string
readOnly: true
description: Same shape as Quiz but with no required fields - all fields are optional on update.
AssignmentUpdate:
type: object
properties:
id:
type: integer
readOnly: true
example: 1
title:
type: string
type:
type: string
description: Set to 'recommended' for courses in this assignment to show up as recommended or 'assigned' for courses to show up as assigned.
example: Assigned
enum:
- Assigned
- Recommended
- assigned
- recommended
assignment_type:
type: string
description: Set to 'courses' for courses or 'learningpaths' for learning paths.
example: courses
enum:
- courses
- learningpaths
course_ids:
type: array
items:
type: integer
description: Required if assignment_type is "courses"
learning_path_ids:
type: array
items:
type: integer
description: Required if assignment_type is "learningpaths"
usergroups:
type: array
items:
type: integer
user_ids:
type: array
items:
type: integer
users:
readOnly: true
type: array
items:
type: object
properties:
id:
type: integer
example: 1620265
username:
type: string
example: johndoe
email:
type: string
example: john@doe.com
name:
type: string
example: John Doe
free:
type: boolean
description: If true, the assignment is free.
start_date:
type: string
format: date
end_date:
type: string
format: date
due_date:
type: string
format: date
days_to_complete:
type: integer
minimum: 0
maximum: 2048
assignment_filter_type:
type: string
description: Filter type ( users or groups ).
example: groups
enum:
- users
- groups
team_id:
type: integer
readOnly: true
dynamic_due_dates_enabled:
type: boolean
description: Only works for Learning Path Assignments
dynamic_due_date_number:
type: integer
description: Required if dynamic_due_dates_enabled is true
dynamic_due_date_unit:
type: string
enum:
- minute
- hour
- day
- week
- month
- year
example: '[minute, hour, day, month, year]'
description: Required if dynamic_due_dates_enabled is true
enroll_users_in_paths:
type: boolean
description: Only works for Learning Path Assignments. When true, users will be enrolled in the learning paths. Defaults to true if not specified.
created_by:
type: integer
readOnly: true
created_on:
type: string
format: date
readOnly: true
modified_by:
type: integer
readOnly: true
modified_on:
type: string
format: date
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this assignment changed.
description:
type: string
maxLength: 50
description: Same shape as Assignment but with no required fields - all fields are optional on update.
LearningPathUpdate:
type: object
properties:
id:
type: integer
readOnly: true
title:
type: string
slug:
type: string
readOnly: true
published:
type: boolean
description:
type: string
courses:
type: array
items:
type: integer
course_details:
type: array
readOnly: true
items:
type: object
properties:
id:
type: integer
title:
type: string
ordering:
type: integer
optional_courses:
type: array
items:
type: integer
optional_course_details:
type: array
readOnly: true
items:
type: object
properties:
id:
type: integer
title:
type: string
ordering:
type: integer
subcategories:
type: array
items:
type: integer
tags:
type: array
items:
type: integer
view_access_type:
type: string
example: none
description: 'Visibility Permission Type. Note: "list" targets specific users and "user" targets user groups.'
enum:
- none
- list
- user
- access
register_access_type:
type: string
example: none
description: 'Registration Permission Type. Note: "list" targets specific users and "user" targets user groups.'
enum:
- none
- list
- user
- access
view_access_groups:
type: array
items:
type: integer
description: array of group ids. Required if view_access_type is user.
view_access_users:
type: array
items:
type: integer
description: array of user ids. Required if view_access_type is list.
view_access_levels:
type: array
items:
type: integer
description: array of access level ids. Required if view_access_type is access.
register_access_groups:
type: array
items:
type: integer
description: array of group ids. Required if register_access_type is user.
register_access_users:
type: array
items:
type: integer
description: array of user ids. Required if register_access_type is list.
register_access_levels:
type: array
items:
type: integer
description: array of access level ids. Required if register_access_type is access.
created_by:
type: integer
readOnly: true
created_on:
type: string
format: date
readOnly: true
modified_by:
type: integer
readOnly: true
modified_on:
type: string
format: date
readOnly: true
deprecated: true
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this learning path changed, including related data such as courses or subcategories.
image:
type: string
readOnly: true
description: Same shape as LearningPath but with no required fields - all fields are optional on update.
LearningPathWithImageUpdate:
type: object
properties:
id:
type: integer
readOnly: true
title:
type: string
slug:
type: string
readOnly: true
published:
type: boolean
description:
type: string
courses:
type: array
items:
type: integer
subcategories:
type: array
items:
type: integer
tags:
type: array
items:
type: integer
image:
type: string
format: binary
description: Supported file types - jpg,png,jpeg,gif. Maximum size 10MB.
view_access_type:
type: string
example: none|list|user|access
description: Visibility Permission Type.
register_access_type:
type: string
example: none|list|user|access
description: Registration Permission Type.
view_access_groups:
type: array
items:
type: integer
description: array of group ids. Required if view_access_type is user.
view_access_users:
type: array
items:
type: integer
description: array of user ids. Required if view_access_type is list.
view_access_levels:
type: array
items:
type: integer
description: array of access level ids. Required if view_access_type is access.
register_access_groups:
type: array
items:
type: integer
description: array of group ids. Required if register_access_type is user.
register_access_users:
type: array
items:
type: integer
description: array of user ids. Required if register_access_type is list.
register_access_levels:
type: array
items:
type: integer
description: array of access level ids. Required if register_access_type is access.
created_by:
type: integer
readOnly: true
created_on:
type: string
format: date
readOnly: true
modified_by:
type: integer
readOnly: true
modified_on:
type: string
format: date
readOnly: true
deprecated: true
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this learning path changed, including related data such as courses or subcategories.
optional_courses:
type: array
items:
type: integer
description: Ids of optional (non-required) courses in the learning path.
description: Same shape as LearningPathWithImage but with no required fields - all fields are optional on update.
LearningPathCategoryUpdate:
type: object
properties:
id:
type: integer
readOnly: true
title:
type: string
slug:
type: string
readOnly: true
published:
type: boolean
subcategories:
type: array
items:
type: integer
subcategory_details:
type: array
readOnly: true
items:
type: object
properties:
id:
type: integer
title:
type: string
ordering:
type: integer
created_by:
type: integer
readOnly: true
created_on:
type: string
format: date
readOnly: true
modified_by:
type: integer
readOnly: true
modified_on:
type: string
format: date
readOnly: true
deprecated: true
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this learning path category changed, including related data such as subcategories.
access_type:
type: string
example: none
enum:
- none
- access
- user
- list
description: 'Note: "list" targets specific users and "user" targets user groups.'
userlist:
type: array
items:
type: integer
usergroup:
type: array
items:
type: integer
accesslevel:
type: array
items:
type: integer
description: Same shape as LearningPathCategory but with no required fields - all fields are optional on update.
LearningPathSubcategoryUpdate:
type: object
properties:
id:
type: integer
readOnly: true
title:
type: string
slug:
type: string
readOnly: true
published:
type: boolean
description:
type: string
categories:
type: array
items:
type: integer
learning_paths:
type: array
items:
type: integer
learning_path_details:
type: array
readOnly: true
items:
type: object
properties:
id:
type: integer
title:
type: string
ordering:
type: integer
created_by:
type: integer
readOnly: true
created_on:
type: string
format: date
readOnly: true
modified_by:
type: integer
readOnly: true
modified_on:
type: string
format: date
readOnly: true
deprecated: true
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this learning path subcategory changed, including related data such as learning paths.
access_type:
type: string
example: none
enum:
- none
- access
- user
- list
description: 'Note: "list" targets specific users and "user" targets user groups.'
userlist:
type: array
items:
type: integer
usergroup:
type: array
items:
type: integer
accesslevel:
type: array
items:
type: integer
image:
type: string
readOnly: true
description: Same shape as LearningPathSubcategory but with no required fields - all fields are optional on update.
LearningPathSubcategoryWithImageUpdate:
type: object
properties:
id:
type: integer
readOnly: true
title:
type: string
slug:
type: string
readOnly: true
published:
type: boolean
description:
type: string
categories:
type: array
items:
type: integer
image:
type: string
format: binary
description: Supported file types - jpg,png,jpeg,gif. Maximum size 10MB.
learning_paths:
type: array
items:
type: integer
created_by:
type: integer
readOnly: true
created_on:
type: string
format: date
readOnly: true
modified_by:
type: integer
readOnly: true
modified_on:
type: string
format: date
readOnly: true
deprecated: true
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this learning path subcategory changed, including related data such as learning paths.
access_type:
type: string
example: none|access|user|list
userlist:
type: array
items:
type: integer
usergroup:
type: array
items:
type: integer
accesslevel:
type: array
items:
type: integer
description: Same shape as LearningPathSubcategoryWithImage but with no required fields - all fields are optional on update.
MediaCategoryUpdate:
type: object
properties:
id:
type: integer
readOnly: true
example: 2
parent_id:
type: integer
example: 5
description: id of the parent media category.
title:
type: string
maxLength: 255
example: My Category
page_title:
type: string
maxLength: 255
example: text
description:
type: string
maxLength: 4000
example: This is descriptive text
published:
type: boolean
example: true
access_type:
type: string
example: none
enum:
- none
- list
- user
- access
description: 'Note: "list" targets specific users and "user" targets user groups.'
usergroup:
type: array
items:
type: integer
description: array of group ids.
userlist:
type: array
items:
type: integer
description: array of user ids.
accesslevel:
type: array
items:
type: integer
description: array of access level ids.
description: Same shape as MediaCategory but with no required fields - all fields are optional on update.
MediaItemNoDataUpdate:
type: object
properties:
id:
type: integer
readOnly: true
example: 2
title:
type: string
maxLength: 255
example: My Video
speaker:
type: string
maxLength: 255
example: Jim Bob
description:
type: string
maxLength: 4000
example: This is descriptive text
published:
type: boolean
example: true
go_live_date:
type: string
example: '2026-07-30 12:00:00'
pattern: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$
description: Must be YYYY-MM-DD HH:MM:SS (a date-only value is rejected).
archive_date:
type: string
example: '2026-07-30 12:00:00'
pattern: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$
description: Must be YYYY-MM-DD HH:MM:SS (a date-only value is rejected).
use_expiration:
type: boolean
example: false
custom_id:
type: string
example: ABC123
expiration_date:
type: string
example: '2026-07-30 12:00:00'
pattern: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$
description: Must be YYYY-MM-DD HH:MM:SS (a date-only value is rejected).
category:
type: integer
example: 5
subcategory:
type: integer
example: 6
media_type:
type: string
example: video
enum:
- video
- audio
- pdf
- link
video_type:
type: string
example: mp4
description: Required if media_type is video.
enum:
- mp4
- youtube
- screencast
- facebook
- vimeo
youtube_id:
type: string
example: DOWDNBu9DkU
description: ID of youtube video or full url. Required if video_type is youtube.
screencast_id:
type: string
example: JnD7uBZDI0Z
description: Required if video_type is screencast.
facebook_url:
type: string
example: https://facebook.com/johnd
description: Required if video_type is facebook.
vimeo_id:
type: string
example: https://vimeo.com/johndoe
description: ID of vimeo video or full url. Required if video_type is vimeo.
interactive_source:
type: string
example: http://interactivesource.com
description: must be a full URL. Required if media_type is link.
access_type:
type: string
example: none
description: 'Visibility Permission Type. Note: "list" targets specific users and "user" targets user groups.'
enum:
- none
- list
- user
- access
access_purchase_type:
type: string
example: none
description: 'Access Permission Type. Note: "list" targets specific users and "user" targets user groups.'
enum:
- none
- list
- user
- access
usergroup:
type: array
items:
type: integer
description: array of group ids. Required if access_type is user.
userlist:
type: array
items:
type: integer
description: array of user ids. Required if access_type is list.
accesslevel:
type: array
items:
type: integer
description: array of access level ids. Required if access_type is access.
usergroup_purchase_register:
type: array
items:
type: integer
description: array of group ids. Required if access_purchase_type is user.
userlist_purchase_register:
type: array
items:
type: integer
description: array of user ids. Required if access_purchase_type is list.
accesslevel_purchase_register:
type: array
items:
type: integer
description: array of access level ids. Required if access_purchase_type is access.
tags:
type: array
items:
type: string
description: Same shape as MediaItemNoData but with no required fields - all fields are optional on update.
MediaItemUpdate:
type: object
properties:
id:
type: integer
readOnly: true
example: 2
title:
type: string
maxLength: 255
example: My Video
speaker:
type: string
maxLength: 255
example: Jim Bob
description:
type: string
maxLength: 4000
example: This is descriptive text
published:
type: boolean
example: true
go_live_date:
type: string
example: '2026-07-30 12:00:00'
pattern: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$
description: Must be YYYY-MM-DD HH:MM:SS (a date-only value is rejected).
archive_date:
type: string
example: '2026-07-30 12:00:00'
pattern: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$
description: Must be YYYY-MM-DD HH:MM:SS (a date-only value is rejected).
use_expiration:
type: boolean
example: false
custom_id:
type: string
example: ABC123
expiration_date:
type: string
example: '2026-07-30 12:00:00'
pattern: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$
description: Must be YYYY-MM-DD HH:MM:SS (a date-only value is rejected).
category:
type: integer
example: 5
subcategory:
type: integer
example: 6
media_type:
type: string
example: video
enum:
- video
- audio
- pdf
- link
video_type:
type: string
example: mp4
description: Required if media_type is video.
enum:
- mp4
- youtube
- screencast
- facebook
- vimeo
source:
type: string
format: binary
description: audio file, video file, or pdf. Required if media_type is video, audio, or PDF.
thumbnail_image:
type: string
format: binary
description: Supported file types - jpg,png,jpeg,gif.
cover_image:
type: string
format: binary
description: Supported file types - jpg,png,jpeg,gif.
youtube_id:
type: string
example: DOWDNBu9DkU
description: ID of youtube video or full url. Required if video_type is youtube.
screencast_id:
type: string
example: DOWDNBu9DkU
description: Required if video_type is screencast.
facebook_url:
type: string
example: DOWDNBu9DkU
description: Required if video_type is facebook.
vimeo_id:
type: string
example: DOWDNBu9DkU
description: ID of vimeo video or full url. Required if video_type is vimeo.
interactive_source:
type: string
example: http://something.com
description: must be a full URL. Required if media_type is link.
access_type:
type: string
example: none
description: 'Visibility Permission Type. Note: "list" targets specific users and "user" targets user groups.'
enum:
- none
- list
- user
- access
access_purchase_type:
type: string
example: none
description: 'Access Permission Type. Note: "list" targets specific users and "user" targets user groups.'
enum:
- none
- list
- user
- access
usergroup:
type: array
items:
type: integer
description: array of group ids. Required if access_type is user.
userlist:
type: array
items:
type: integer
description: array of user ids. Required if access_type is list.
accesslevel:
type: array
items:
type: integer
description: array of access level ids. Required if access_type is access.
usergroup_purchase_register:
type: array
items:
type: integer
description: array of group ids. Required if access_purchase_type is user.
userlist_purchase_register:
type: array
items:
type: integer
description: array of user ids. Required if access_purchase_type is list.
accesslevel_purchase_register:
type: array
items:
type: integer
description: array of access level ids. Required if access_purchase_type is access.
tags:
type: array
items:
type: string
created_on:
type: string
format: date
example: YYYY-mm-dd
description: Same shape as MediaItem but with no required fields - all fields are optional on update.
EventUpdate:
type: object
properties:
id:
type: integer
readOnly: true
example: 1
parent_id:
description: When creating a recurring event several 'child' events are created, each with a date and title based on the recurring settings and the title of the parent event. If an event has parent_id = 0 then it is a parent and may or may not have children.
type: integer
category_id:
type: integer
secondary_category_ids:
type: array
items:
type: integer
description: IDs of secondary categories assigned to this event.
readOnly: true
location_id:
type: integer
title:
type: string
example: My Event
registration_type:
type: integer
example: 0
description: 0 - Both Individual and Group Registration, 1 - Only Individual Registration, 2 - Only Group Registration, 3 - Disable Registration.
view_access:
type: array
items:
type: integer
description: ids of the groups that can view this course.
example: [1]
registration_access:
type: array
items:
type: integer
description: ids of the groups that can register for this course.
example: [1]
event_date:
type: string
example: '2026-08-29 12:00:00'
description: Accepts YYYY-MM-DD or YYYY-MM-DD HH:MM:SS; responses include the time component.
event_end_date:
type: string
example: '2026-08-29 12:00:00'
description: Accepts YYYY-MM-DD or YYYY-MM-DD HH:MM:SS; responses include the time component.
short_description:
type: string
description:
type: string
individual_price:
type: number
format: float
event_capacity:
type: integer
created_by:
type: integer
description: User id.
example: 1620265
readOnly: true
cut_off_date:
type: string
description: Registration end date. Accepts YYYY-MM-DD or YYYY-MM-DD HH:MM:SS; responses include the time component.
example: '2026-08-29 12:00:00'
published:
type: boolean
featured:
type: boolean
registration_start_date:
type: string
description: Registration start date. Accepts YYYY-MM-DD or YYYY-MM-DD HH:MM:SS; responses include the time component.
example: '2026-08-29 12:00:00'
alias:
type: string
description: Unique URI for use in Search Engine Friendly urls
pattern: '[a-z-]+'
example: my-event
language:
type: string
enable_auto_reminder:
type: boolean
description: If set to 'true' registrants will get auto reminder emails for this event.
image:
type: string
readOnly: true
timezone:
type: string
virtual_classroom_id:
type: string
example: B0C4D939-AF12-43D8-82B3-0A68D423F894
readOnly: true
virtual_classroom_uri:
type: string
description: uri of virtual classroom that can be used for linking directly to virtual classroom
readOnly: true
request_register:
type: boolean
readOnly: true
request_team:
type: boolean
readOnly: true
request_instructor:
type: boolean
readOnly: true
instructor_ids:
type: array
readOnly: true
items:
type: integer
allow_to_cancel:
type: boolean
readOnly: true
cancel_before_date:
type: string
format: date
nullable: true
description: Only present when allow_to_cancel is true.
readOnly: true
registration_count:
type: integer
readOnly: true
description: Total number of registrants for this event.
checked_in_count:
type: integer
readOnly: true
description: Total number of checked-in registrants for this event.
waitlist_count:
type: integer
readOnly: true
description: Total number of waitlisted registrants for this event.
sub_capacities:
type: array
readOnly: true
items:
$ref: "#/components/schemas/EventSubCapacity"
custom_fields:
type: array
readOnly: true
items:
$ref: '#/components/schemas/CustomFieldValueResponse'
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Reflects the last time anything about this event changed, including related data such as registrations.
description: Same shape as Event but with no required fields - all fields are optional on update.
EventWithImageUpdate:
type: object
properties:
id:
type: integer
readOnly: true
example: 1
parent_id:
description: When creating a recurring event several 'child' events are created, each with a date and title based on the recurring settings and the title of the parent event. If an event has parent_id = 0 then it is a parent and may or may not have children.
type: integer
category_id:
type: integer
secondary_category_ids:
type: array
items:
type: integer
description: IDs of secondary categories assigned to this event.
readOnly: true
location_id:
type: integer
title:
type: string
example: My Event
registration_type:
type: integer
example: 0
description: 0 - Both Individual and Group Registration, 1 - Only Individual Registration, 2 - Only Group Registration, 3 - Disable Registration.
view_access:
type: array
items:
type: integer
description: ids of the groups that can view this course.
registration_access:
type: array
items:
type: integer
description: ids of the groups that can register for this course.
event_date:
type: string
example: '2026-08-29 12:00:00'
description: Accepts YYYY-MM-DD or YYYY-MM-DD HH:MM:SS; responses include the time component.
event_end_date:
type: string
example: '2026-08-29 12:00:00'
description: Accepts YYYY-MM-DD or YYYY-MM-DD HH:MM:SS; responses include the time component.
short_description:
type: string
description:
type: string
individual_price:
type: number
format: float
event_capacity:
type: integer
created_by:
type: integer
description: User id.
example: 1620265
readOnly: true
cut_off_date:
type: string
description: Registration end date. Accepts YYYY-MM-DD or YYYY-MM-DD HH:MM:SS; responses include the time component.
example: '2026-08-29 12:00:00'
published:
type: boolean
featured:
type: boolean
registration_start_date:
type: string
description: Registration start date. Accepts YYYY-MM-DD or YYYY-MM-DD HH:MM:SS; responses include the time component.
example: '2026-08-29 12:00:00'
alias:
type: string
description: Unique URI for use in Search Engine Friendly urls.
pattern: "[a-z-]+"
language:
type: string
enable_auto_reminder:
type: boolean
description: If set to 'true' registrants will get auto reminder emails for this event.
image:
type: string
format: binary
description: Supported file types - jpg,png,jpeg,gif. Maximum size 10MB.
timezone:
type: string
example: America/New_York
description: Same shape as EventWithImage but with no required fields - all fields are optional on update.
SubscriptionUpdate:
type: object
properties:
id:
type: integer
readOnly: true
example: 1
title:
type: string
published:
type: boolean
private:
type: boolean
featured:
type: boolean
default_sub_length:
type: string
description: Default length of the subscription period. Valid values are 1-15D, 1-12M, and 1-5Y
example: 1D
default_initial_amount:
type: number
description: Amount of money (in USD) that the subscription will cost on signup.
format: float
default_amount:
type: number
description: Amount of money (in USD) that the subscription will cost when the subscription period length has elapsed and the subscription is renewed.
format: float
usergroups:
type: array
items:
type: integer
description: Array of user groups for which this subscription will be available.
description_html:
type: string
description: Plain text or HTML-formatted description that describes the subscription.
description_type:
type: string
description: Description type.
type:
type: string
description:
type: string
timestamp_created:
type: string
format: date-time
readOnly: true
timestamp_modified:
type: string
format: date-time
readOnly: true
description: Same shape as Subscription but with no required fields - all fields are optional on update.
SuccessMessage:
type: object
properties:
success:
type: string
example: Entity id = 1 deleted
Message:
type: object
properties:
message:
type: string
SubscribeResult:
type: object
properties:
success:
type: string
subscription_id:
type: integer
nullable: true
description: Present for paid plans.
payment_id:
type: integer
nullable: true
description: Present for paid plans.
ValidationError:
type: object
properties:
errors:
type: array
items:
type: string
example:
errors:
- The title field is required.
UnprocessableEntityError:
type: object
properties:
message:
type: string
description: The first validation message, followed by a count of any others.
errors:
type: object
description: Validation messages keyed by the request field that failed.
additionalProperties:
type: array
items:
type: string
example:
message: The label field is required. (and 1 more error)
errors:
label:
- The label field is required.
type_id:
- The type id field is required.
ForbiddenError:
type: object
properties:
Forbidden:
type: string
example:
Forbidden: Access Denied
NotFoundError:
type: object
properties:
error:
type: string
example:
error: Entity id = 1 not found