@lap v0.3
# Machine-readable API spec. Each @endpoint block is one API call.
@api iQualify Management API
@base https://api.iqualify.com/v1
@version v1
@auth ApiKey Authorization in header
@endpoints 84
@hint download_for_search
@toc root(1), offerings(55), course-mappings(5), courses(9), org(1), users(13)

@group root
@endpoint GET /
@returns(200)

@endgroup

@group offerings
@endpoint GET /offerings/{offeringId}/analytics/pulses
@required {offeringId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint GET /offerings/{offeringId}/analytics/pulses/responses
@required {offeringId: str}
@optional {pulseType: str(submit_text/MCQ/spatial_triangular/spatial_planar/spatial_linear), responseTime: any}
@returns(200)
@errors {401, 403, 404}

@endpoint GET /offerings/{offeringId}/analytics/pulses/{pulseId}/responses
@required {offeringId: str, pulseId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint GET /offerings/{offeringId}/analytics/marks/assignments
@required {offeringId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint GET /offerings/{offeringId}/analytics/marks/quizzes
@required {offeringId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint GET /offerings/{offeringId}/analytics/learners-progress
@required {offeringId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint GET /offerings/{offeringId}/analytics/unit-reactions
@required {offeringId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint GET /offerings/{offeringId}/analytics/submissions/assignments
@required {offeringId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint GET /offerings/{offeringId}/analytics/social-notes
@required {offeringId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint GET /offerings/{offeringId}/analytics/activities/responses
@required {offeringId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint GET /offerings/{offeringId}/analytics/submissions/open-response/{assessmentId}
@required {offeringId: str, assessmentId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint GET /offerings/{offeringId}/analytics/submissions/{userEmail}/assignments/{assessmentId}
@required {offeringId: str, userEmail: str(email), assessmentId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint GET /offerings/{offeringId}/groups
@required {offeringId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint POST /offerings/{offeringId}/groups
@required {offeringId: str, title: str}
@returns(201) {id: str, title: str, createdAt: str}
@errors {400, 401, 403, 404}

@endpoint GET /offerings/{offeringId}/groups/{groupId}/learners
@required {offeringId: str, groupId: str}
@returns(200)
@errors {400, 401, 403, 404}

@endpoint POST /offerings/{offeringId}/groups/{groupId}/learners
@required {offeringId: str, groupId: str}
@optional {email: str}
@returns(201) {id: str, avatarUrl: str, profile: map{displayName: str, mobile: str}, email: str(email), firstName: str, lastName: str, personId: str, lastAccessAt: str(date-time), firstAccessAt: str(date-time), metadata: map{tags: [str]}, invite: map{url: str}}
@errors {400, 401, 403, 404}

@endpoint DELETE /offerings/{offeringId}/groups/{groupId}/learners/{userEmail}
@required {offeringId: str, groupId: str, userEmail: str(email)}
@returns(204)
@errors {400, 401, 403, 404}

@endpoint GET /offerings/{offeringId}/analytics/channels/{channelId}/posts
@required {offeringId: str, channelId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint GET /offerings/{offeringId}/analytics/channels/{channelId}/comments
@required {offeringId: str, channelId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint GET /offerings/{offeringId}/analytics/channels/{channelId}/replies
@required {offeringId: str, channelId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint GET /offerings/{offeringId}/channels
@required {offeringId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint POST /offerings/{offeringId}/channels
@required {offeringId: str, title: str}
@optional {isBroadcastOnly: bool=false}
@returns(201) {id: str, title: str, isBroadcastOnly: bool}
@errors {400, 401, 403, 404}

@endpoint PATCH /offerings/{offeringId}/channels/{channelId}
@required {offeringId: str, channelId: str}
@optional {title: str, isBroadcastOnly: bool, privateSupport: bool, groupDiscussion: bool, group: map{autoAssign: bool}}
@returns(200) {id: str, title: str, isBroadcastOnly: bool}
@errors {400, 401, 403, 404}

@endpoint POST /offerings/{offeringId}/channels/{channelId}/learners
@required {offeringId: str, channelId: str}
@optional {email: str}
@returns(204)
@errors {400, 401, 403, 404}

@endpoint DELETE /offerings/{offeringId}/channels/{channelId}/learners
@required {offeringId: str, channelId: str}
@optional {email: str}
@returns(204)
@errors {400, 401, 403, 404}

@endpoint GET /offerings/{offeringId}/channels/{channelId}/learners
@required {offeringId: str, channelId: str}
@returns(200) {id: str, title: str, isBroadcastOnly: bool}
@errors {400, 401, 403, 404}

@endgroup

@group course-mappings
@endpoint GET /course-mappings
@returns(200)
@errors {401, 403}

@endpoint GET /course-mappings/externalcourse/{externalCourseId}
@required {externalCourseId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint GET /course-mappings/{offeringId}
@required {offeringId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint PUT /course-mappings/{offeringId}/{externalCourseId}
@required {offeringId: str, externalCourseId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint DELETE /course-mappings/{offeringId}/{externalCourseId}
@required {offeringId: str, externalCourseId: str}
@returns(200)
@errors {401, 403, 404}

@endgroup

@group courses
@endpoint GET /courses
@returns(200)
@errors {401, 403}

@endpoint GET /courses/{contentId}
@required {contentId: str}
@returns(200) {id: str, name: str, createdAt: str(date-time), coverImageUrl: str, tasksEnabled: bool, metadata: any}
@errors {401, 403, 404}

@endpoint GET /courses/{contentId}/activations
@required {contentId: str}
@returns(200) {id: str, name: str, end: str, start: str, learnersCount: str, info: str, metadata: map{rootContentId: str}}
@errors {401, 403, 404}

@endpoint PUT /courses/{contentId}/metadata/tags
@required {contentId: str}
@optional {tags: [str]}
@returns(200) {id: str, name: str, createdAt: str(date-time), coverImageUrl: str, tasksEnabled: bool, metadata: any}
@errors {400, 401, 403, 404}

@endpoint PUT /courses/{contentId}/metadata/category
@required {contentId: str}
@optional {category: str}
@returns(200) {id: str, name: str, createdAt: str(date-time), coverImageUrl: str, tasksEnabled: bool, metadata: any}
@errors {400, 401, 403, 404}

@endpoint PUT /courses/{contentId}/metadata/level
@required {contentId: str}
@optional {level: str}
@returns(200) {id: str, name: str, createdAt: str(date-time), coverImageUrl: str, tasksEnabled: bool, metadata: any}
@errors {400, 401, 403, 404}

@endpoint PUT /courses/{contentId}/metadata/topic
@required {contentId: str}
@optional {topic: str}
@returns(200) {id: str, name: str, createdAt: str(date-time), coverImageUrl: str, tasksEnabled: bool, metadata: any}
@errors {400, 401, 403, 404}

@endpoint POST /courses/{rootContentId}/permissions/{userEmail}
@required {rootContentId: str, userEmail: str}
@optional {isBuilder: bool=true, isReviewer: bool=false}
@returns(201) {contentId: str}
@errors {400, 401, 403, 404}

@endpoint GET /courses/{contentId}/permissions
@required {contentId: str}
@returns(200) {email: str, name: str, isBuilder: bool, isReviewer: bool}
@errors {401, 403, 404}

@endgroup

@group offerings
@endpoint GET /offerings
@returns(200)
@errors {401, 403}

@endpoint POST /offerings
@required {start: str(date-time)}
@optional {identifier: str, name: str, description: str, contentId: str, rootContentId: str, end: str(date-time), useRelativeDates: bool=false, trailerVideoUrl: str, isReadonly: bool, hasEarlyCloseOff: bool, earlyCloseOffDate: str(date-time), createDefaultChannels: bool=false, badge: map{title: str, description: str, requiresApproval: bool, badgeExpiry: map}, hiddenPageIds: [str], metadata: map{category: str, topic: str, level: str, tags: [str]}, settings: map{allowSocialFeatures: bool, enablePrivateSupportChannel: bool}}
@returns(201) {id: str, identifier: str, name: str, description: str, overview: str, contentId: str, useRelativeDates: bool, start: str(date-time), end: str(date-time), coverImageUrl: str, trailerVideoUrl: str, isReadonly: bool, studyPlan: map{filename: str, mimetype: str, size: num, url: str, createdAt: str(date-time)}, hasEarlyCloseOff: bool, earlyCloseOffDate: str(date-time), enrollmentLimit: num, price: num, currency: str, allowEnrollment: bool, settings: map{aggregateProgressScore: bool, allowSocialFeatures: bool, allowTasks: bool, enablePrivateSupportChannel: bool, strictStartDate: bool}, tasksEnabled: bool, metadata: map{rootContentId: str, category: str, topic: str, level: str, tags: [str]}}
@errors {400, 401, 403, 404}

@endpoint GET /offerings/summary
@optional {$top: str=50, $orderby: str, $filter: str}
@returns(200)
@errors {400, 401, 403}

@endpoint GET /offerings/current
@returns(200)
@errors {401, 403}

@endpoint GET /offerings/past
@returns(200)
@errors {401, 403}

@endpoint GET /offerings/future
@returns(200)
@errors {401, 403}

@endpoint GET /offerings/info/{textPattern}
@required {textPattern: str}
@returns(200)
@errors {400, 401, 403, 404}

@endpoint GET /offerings/{offeringId}
@required {offeringId: str}
@returns(200) {id: str, identifier: str, name: str, description: str, overview: str, contentId: str, useRelativeDates: bool, start: str(date-time), end: str(date-time), coverImageUrl: str, trailerVideoUrl: str, isReadonly: bool, studyPlan: map{filename: str, mimetype: str, size: num, url: str, createdAt: str(date-time)}, hasEarlyCloseOff: bool, earlyCloseOffDate: str(date-time), enrollmentLimit: num, price: num, currency: str, allowEnrollment: bool, settings: map{aggregateProgressScore: bool, allowSocialFeatures: bool, allowTasks: bool, enablePrivateSupportChannel: bool, strictStartDate: bool}, tasksEnabled: bool, metadata: map{rootContentId: str, category: str, topic: str, level: str, tags: [str]}}
@errors {401, 403, 404}

@endpoint PATCH /offerings/{offeringId}
@required {offeringId: str}
@optional {identifier: str, name: str, overview: str, description: str, contentId: str, rootContentId: str, start: str(date-time), end: str(date-time), useRelativeDates: bool, trailerVideoUrl: str, isReadonly: bool, hasEarlyCloseOff: bool, earlyCloseOffDate: str(date-time), badge: map{title: str, description: str, requiresApproval: bool, badgeExpiry: map}, metadata: map{category: str, topic: str, level: str, tags: [str]}}
@returns(200) {id: str, identifier: str, name: str, description: str, overview: str, contentId: str, useRelativeDates: bool, start: str(date-time), end: str(date-time), coverImageUrl: str, trailerVideoUrl: str, isReadonly: bool, studyPlan: map{filename: str, mimetype: str, size: num, url: str, createdAt: str(date-time)}, hasEarlyCloseOff: bool, earlyCloseOffDate: str(date-time), enrollmentLimit: num, price: num, currency: str, allowEnrollment: bool, settings: map{aggregateProgressScore: bool, allowSocialFeatures: bool, allowTasks: bool, enablePrivateSupportChannel: bool, strictStartDate: bool}, tasksEnabled: bool, metadata: map{rootContentId: str, category: str, topic: str, level: str, tags: [str]}}
@errors {400, 401, 403, 404}

@endpoint GET /offerings/{offeringId}/badges
@required {offeringId: str}
@returns(200) {title: str, description: str, criterias: any, badgeExpiry: map{expires: bool, expiryType: str, expirationDate: str(date-time), timeframeUnit: str, timeframeAmount: num}, badgeUrl: str, openBadge: any}
@errors {401, 403, 404}

@endpoint PUT /offerings/{offeringId}/metadata/tags
@required {offeringId: str}
@optional {tags: [str]}
@returns(200) {id: str, identifier: str, name: str, description: str, overview: str, contentId: str, useRelativeDates: bool, start: str(date-time), end: str(date-time), coverImageUrl: str, trailerVideoUrl: str, isReadonly: bool, studyPlan: map{filename: str, mimetype: str, size: num, url: str, createdAt: str(date-time)}, hasEarlyCloseOff: bool, earlyCloseOffDate: str(date-time), enrollmentLimit: num, price: num, currency: str, allowEnrollment: bool, settings: map{aggregateProgressScore: bool, allowSocialFeatures: bool, allowTasks: bool, enablePrivateSupportChannel: bool, strictStartDate: bool}, tasksEnabled: bool, metadata: map{rootContentId: str, category: str, topic: str, level: str, tags: [str]}}
@errors {400, 401, 403, 404}

@endpoint PUT /offerings/{offeringId}/metadata/category
@required {offeringId: str}
@optional {category: str}
@returns(200) {id: str, identifier: str, name: str, description: str, overview: str, contentId: str, useRelativeDates: bool, start: str(date-time), end: str(date-time), coverImageUrl: str, trailerVideoUrl: str, isReadonly: bool, studyPlan: map{filename: str, mimetype: str, size: num, url: str, createdAt: str(date-time)}, hasEarlyCloseOff: bool, earlyCloseOffDate: str(date-time), enrollmentLimit: num, price: num, currency: str, allowEnrollment: bool, settings: map{aggregateProgressScore: bool, allowSocialFeatures: bool, allowTasks: bool, enablePrivateSupportChannel: bool, strictStartDate: bool}, tasksEnabled: bool, metadata: map{rootContentId: str, category: str, topic: str, level: str, tags: [str]}}
@errors {400, 401, 403, 404}

@endpoint PUT /offerings/{offeringId}/metadata/topic
@required {offeringId: str}
@optional {topic: str}
@returns(200) {id: str, identifier: str, name: str, description: str, overview: str, contentId: str, useRelativeDates: bool, start: str(date-time), end: str(date-time), coverImageUrl: str, trailerVideoUrl: str, isReadonly: bool, studyPlan: map{filename: str, mimetype: str, size: num, url: str, createdAt: str(date-time)}, hasEarlyCloseOff: bool, earlyCloseOffDate: str(date-time), enrollmentLimit: num, price: num, currency: str, allowEnrollment: bool, settings: map{aggregateProgressScore: bool, allowSocialFeatures: bool, allowTasks: bool, enablePrivateSupportChannel: bool, strictStartDate: bool}, tasksEnabled: bool, metadata: map{rootContentId: str, category: str, topic: str, level: str, tags: [str]}}
@errors {400, 401, 403, 404}

@endpoint PUT /offerings/{offeringId}/metadata/level
@required {offeringId: str}
@optional {level: str}
@returns(200) {id: str, identifier: str, name: str, description: str, overview: str, contentId: str, useRelativeDates: bool, start: str(date-time), end: str(date-time), coverImageUrl: str, trailerVideoUrl: str, isReadonly: bool, studyPlan: map{filename: str, mimetype: str, size: num, url: str, createdAt: str(date-time)}, hasEarlyCloseOff: bool, earlyCloseOffDate: str(date-time), enrollmentLimit: num, price: num, currency: str, allowEnrollment: bool, settings: map{aggregateProgressScore: bool, allowSocialFeatures: bool, allowTasks: bool, enablePrivateSupportChannel: bool, strictStartDate: bool}, tasksEnabled: bool, metadata: map{rootContentId: str, category: str, topic: str, level: str, tags: [str]}}
@errors {400, 401, 403, 404}

@endpoint GET /offerings/{offeringId}/assessments
@required {offeringId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint PATCH /offerings/{offeringId}/assessments/{assessmentId}
@required {offeringId: str, assessmentId: str}
@optional {markType: str, markNumber: str, openDate: str(date-time), dueDate: str(date-time), content: str}
@returns(200) {id: str, pid: str, title: str, type: str, content: str, points: str, hidden: bool, filename: str, maxAttempts: int(int32), durationMinutes: int(int32), totalQuestions: int(int32), totalThemes: int(int32), documents: [map], themes: [map], markType: str, markNumber: str, openDate: str(date-time), dueDate: str(date-time)}
@errors {400, 401, 403, 404}

@endpoint PATCH /offerings/{offeringId}/assessments/{assessmentId}/{userEmail}
@required {offeringId: str, assessmentId: str, userEmail: str(email)}
@optional {dueDate: str(date-time)}
@returns(204)
@errors {400, 401, 403, 404}

@endpoint DELETE /offerings/{offeringId}/assessments/{assessmentId}/documents/{documentId}
@required {offeringId: str, assessmentId: str, documentId: str}
@returns(204)
@errors {401, 403, 404}

@endpoint GET /offerings/{offeringId}/learners/pending-submission
@required {offeringId: str}
@optional {days: str}
@returns(200)
@errors {400, 401, 403, 404}

@endpoint GET /offerings/{offeringId}/activities/openresponse
@required {offeringId: str}
@returns(200)
@errors {401, 403, 404}

@endpoint GET /offerings/{offeringId}/users
@required {offeringId: str}
@optional {facilitators: str(true/false)=true, learners: str(true/false)=true, markers: str(true/false)=true}
@returns(200)
@errors {400, 401, 403, 404}

@endpoint POST /offerings/{offeringId}/users
@required {offeringId: str}
@returns(201)
@returns(207)
@errors {400, 401, 403, 404}

@endpoint DELETE /offerings/{offeringId}/users/{userEmail}
@required {offeringId: str, userEmail: str(email)}
@returns(204)
@errors {400, 401, 403, 404}

@endpoint GET /offerings/{offeringId}/users/{markerEmail}/marks
@required {offeringId: str, markerEmail: str}
@returns(200)
@errors {401, 403, 404}

@endpoint POST /offerings/{offeringId}/users/{markerEmail}/marks
@required {offeringId: str, markerEmail: str}
@returns(200)
@errors {400, 401, 403, 404}

@endpoint DELETE /offerings/{offeringId}/users/{markerEmail}/marks
@required {offeringId: str, markerEmail: str}
@returns(200)
@errors {400, 401, 403, 404}

@endpoint POST /offerings/{offeringId}/users/{userEmail}/badges/award
@required {offeringId: str, userEmail: str(email)}
@returns(201) {awarded: bool, badgeId: str, badgeUrl: str}
@errors {400, 401, 403, 404}

@endpoint GET /offerings/{offeringId}/users/{userEmail}/submissions/open-response
@required {offeringId: str, userEmail: str(email)}
@returns(200)
@errors {400, 401, 403, 404}

@endpoint DELETE /offerings/{offeringId}/users/{userEmail}/assessments/{assessmentId}
@required {offeringId: str, userEmail: str(email), assessmentId: str}
@returns(204)
@errors {400, 401, 403, 404}

@endgroup

@group org
@endpoint GET /org
@returns(200) {id: str, name: str}
@errors {401, 403, 404}

@endgroup

@group users
@endpoint GET /users/{userEmail}
@required {userEmail: str(email)}
@returns(200) {id: str, avatarUrl: str, profile: map{displayName: str, mobile: str}, email: str(email), firstName: str, lastName: str, personId: str, lastAccessAt: str(date-time), firstAccessAt: str(date-time), metadata: map{tags: [str]}, invite: map{url: str}}
@errors {400, 401, 403, 404}

@endpoint PATCH /users/{userEmail}
@required {userEmail: str(email)}
@optional {firstName: str, lastName: str, email: str(email), personId: str, profile: map{displayName: str}, metadata: map{tags: [str]}, sendInvite: bool=true}
@returns(200) {id: str, avatarUrl: str, profile: map{displayName: str, mobile: str}, email: str(email), firstName: str, lastName: str, personId: str, lastAccessAt: str(date-time), firstAccessAt: str(date-time), metadata: map{tags: [str]}, invite: map{url: str}}
@errors {400, 401, 403, 404}

@endpoint PUT /users/{userEmail}/suspend
@required {userEmail: str(email)}
@optional {suspended: bool}
@returns(204)
@errors {400, 401, 403, 404}

@endpoint GET /users/{userEmail}/offerings
@required {userEmail: str(email)}
@returns(200)
@errors {400, 401, 403, 404}

@endpoint POST /users/{userEmail}/offerings
@required {userEmail: str(email)}
@returns(200)
@errors {400, 401, 403, 404}

@endpoint GET /users/{userEmail}/offerings/{offeringId}/progress
@required {userEmail: str(email), offeringId: str}
@returns(200) {id: str, firstName: str, lastName: str, email: str, completion: str}
@errors {400, 401, 403, 404}

@endpoint POST /users/{userEmail}/permissions/{permissionName}
@required {userEmail: str(email), permissionName: str(builder/manager/insights/userAdmin)}
@returns(200) {id: str, avatarUrl: str, profile: map{displayName: str, mobile: str}, email: str(email), firstName: str, lastName: str, personId: str, lastAccessAt: str(date-time), firstAccessAt: str(date-time), metadata: map{tags: [str]}, invite: map{url: str}}
@errors {400, 401, 403, 404}

@endpoint GET /users/all/progress
@optional {$top: str=50, $orderby: str, $filter: str}
@returns(200) {top: int, data: any}
@errors {400, 401, 403}

@endpoint GET /users/{userEmail}/progress
@required {userEmail: str(email)}
@returns(200) {id: str, firstName: str, lastName: str, email: str, personId: str, offerings: [map]}
@errors {400, 401, 403, 404}

@endpoint GET /users/{userEmail}/badges
@required {userEmail: str(email)}
@returns(200)
@errors {400, 401, 403, 404}

@endpoint PATCH /users/{userEmail}/transfer
@required {userEmail: str(email)}
@optional {fromOfferingId: str, toOfferingId: str, sendInvite: bool}
@returns(200)
@errors {400, 401, 403, 404}

@endpoint POST /users/{userEmail}/invite-email
@required {userEmail: str(email)}
@returns(204)
@errors {401, 403, 404}

@endpoint POST /users
@optional {firstName: str, lastName: str, email: str(email), personId: str, profile: map{displayName: str}, metadata: map{tags: [str]}, sendInvite: bool=true}
@returns(201) {id: str, avatarUrl: str, profile: map{displayName: str, mobile: str}, email: str(email), firstName: str, lastName: str, personId: str, lastAccessAt: str(date-time), firstAccessAt: str(date-time), metadata: map{tags: [str]}, invite: map{url: str}}
@errors {400, 401, 403, 404}

@endgroup

@end
