Skip to main content

Courses

The Courses API provides the courses available to the authenticated student, along with course metadata, tags, and the student's progress in those courses.

Get Available Courses

This endpoint returns only the courses the authenticated student can access. The response is paginated and includes related tags and course-progress records separately so clients can associate them using tag_ids and course_id.

HTTP Request

GET /api/v3/courses/

Query Parameters

ParameterTypeDescription
pageintegerOptional. Page number to retrieve. Defaults to 1.
page_sizeintegerOptional. Number of courses to return per page. Defaults to 20.
qstringOptional. Searches for courses by title.
tagsstringOptional. Filters courses by tag name. Repeat this parameter to match any of several tags, for example ?tags=Banking&tags=Finance.
created_0dateOptional. Returns courses created on or after this date. Use YYYY-MM-DD format.
created_1dateOptional. Returns courses created on or before this date. Use YYYY-MM-DD format.
ostringOptional. Sort order: order, -created, created, title, or -title.

Authentication

Include the student's JWT in the Authorization header. An unauthenticated request returns 401 Unauthorized.

curl --request GET \
--url 'https://lmsdemo.testpress.in/api/v3/courses/?page=1&page_size=20&o=order' \
--header 'authorization: JWT your_jwt_token' \
--header 'cache-control: no-cache'

Course Fields

FieldTypeDescription
idintegerUnique course ID.
titlestringCourse title.
descriptionstringCourse description, which may contain HTML.
imagestringCourse image URL.
created_byintegerID of the user who created the course.
createddatetimeDate and time when the course was created.
modifieddatetimeDate and time when the course was last modified.
contents_urlstringAPI URL for retrieving the course contents.
slugstringURL-friendly course identifier.
chapters_countintegerNumber of chapters in the course.
contents_countintegerTotal number of chapter contents.
exams_countintegerNumber of exams.
videos_countintegerNumber of videos.
attachments_countintegerNumber of attachments.
html_contents_countintegerNumber of HTML or text contents.
video_conferences_countintegerNumber of video conferences.
live_streams_countintegerNumber of live streams.
orderintegerConfigured display order.
external_content_linkstring or nullExternal destination associated with the course.
external_link_labelstringLabel to display for the external link.
enable_discussionsbooleanWhether discussions are enabled.
device_access_controlstringDevice-access policy configured for the course.
allowed_devicesstringHuman-readable list of devices on which the course can be accessed.
layoutstringCourse-content layout, such as list or tree.
tag_idsarrayIDs of tags associated with the course. Resolve these IDs using results.tags.
enable_progressive_lockbooleanWhether course contents use progressive locking.
max_allowed_views_per_videointeger or nullMaximum permitted views of each video, or null when unrestricted.
max_allowed_watch_minutesinteger or nullMaximum permitted video watch time in minutes, or null when unrestricted.
allow_custom_test_generationbooleanWhether the student can generate custom tests for this course.

Response

The example contains one record of each type. The courses, tags, and user_course_credits arrays may be empty.

{
"count": 480,
"next": "https://lmsdemo.testpress.in/api/v3/courses/?page=2",
"previous": null,
"per_page": 20,
"results": {
"courses": [
{
"id": 1583,
"title": "Course that has all the types of contents",
"description": "",
"image": "https://d36vpug2b5drql.cloudfront.net/institute/lmsdemo/custom_icons/course.png",
"created_by": 74,
"created": "2026-04-16T12:46:12.864386+05:30",
"modified": "2026-08-18T13:24:58.610361+05:30",
"contents_url": "https://lmsdemo.testpress.in/api/v3/courses/1583/contents/",
"slug": "course-that-has-all-the-types-of-contents",
"chapters_count": 19,
"contents_count": 217,
"exams_count": 40,
"videos_count": 72,
"attachments_count": 9,
"html_contents_count": 14,
"video_conferences_count": 49,
"live_streams_count": 67,
"order": 7,
"external_content_link": null,
"external_link_label": "Register Here",
"enable_discussions": true,
"device_access_control": "All Platforms",
"allowed_devices": "web, mobile app, desktop app",
"layout": "list",
"tag_ids": [208],
"enable_progressive_lock": false,
"max_allowed_views_per_video": null,
"max_allowed_watch_minutes": null,
"allow_custom_test_generation": true
}
],
"tags": [
{
"id": 208,
"name": "videos"
}
],
"user_course_credits": [
{
"id": 32466,
"user": 1639,
"course_id": 1583,
"total_video_attempts": 1,
"total_unique_video_attempts": 1,
"total_html_attempts": 0,
"total_unique_html_attempts": 0,
"total_exam_attempts": 0,
"total_unique_exam_attempts": 0,
"total_quiz_attempts": 0,
"total_unique_quiz_attempts": 0,
"video_watched_duration": "15.0000",
"total_video_conference_attempts": 0,
"total_unique_video_conference_attempts": 0,
"total_attachment_attempts": 0,
"total_unique_attachment_attempts": 0,
"total_live_stream_attempts": 0,
"total_unique_live_stream_attempts": 0,
"total_assignment_attempts": 0,
"total_unique_assignment_attempts": 0,
"total_unique_attempts": 1,
"course_completion_percentage": 0.46
}
]
}
}

Match a progress record to its course using user_course_credits[].course_id. The course_completion_percentage is based on unique attempted contents divided by the course's contents_count, capped at 100.

Get Course Details

This endpoint retrieves one published course. The student must be permitted to view and start the course.

HTTP Request

GET /api/v3/courses/<course_id>/

URL Parameters

ParameterTypeDescription
course_idintegerID of the course to retrieve.
curl --request GET \
--url 'https://lmsdemo.testpress.in/api/v3/courses/1583/' \
--header 'authorization: JWT your_jwt_token' \
--header 'cache-control: no-cache'

Response

{
"id": 1583,
"url": "https://lmsdemo.testpress.in/api/v3/courses/1583/",
"title": "Course that has all the types of contents",
"expiry_date": null,
"description": "",
"image": "https://d36vpug2b5drql.cloudfront.net/institute/lmsdemo/custom_icons/course.png",
"created_by": 74,
"created": "2026-04-16T12:46:12.864386+05:30",
"modified": "2026-08-18T13:24:58.610361+05:30",
"contents_url": "https://lmsdemo.testpress.in/api/v3/courses/1583/contents/",
"chapters_url": "https://lmsdemo.testpress.in/api/v3/courses/1583/chapters/",
"slug": "course-that-has-all-the-types-of-contents",
"chapters_count": 19,
"contents_count": 217,
"exams_count": 40,
"videos_count": 72,
"attachments_count": 9,
"html_contents_count": 14,
"order": 7,
"external_content_link": null,
"external_link_label": "Register Here",
"enable_discussions": true,
"device_access_control": "All Platforms",
"allowed_devices": "web, mobile app, desktop app",
"layout": "list",
"tags": ["videos"],
"enable_progressive_lock": false,
"max_allowed_views_per_video": null,
"max_allowed_watch_minutes": null,
"allow_custom_test_generation": true,
"enable_certificate": false
}

The external link and its label can reflect the authenticated student's enrollment or approval state.

Get Course Chapters

This endpoint retrieves the chapters in a course and the authenticated student's progress in those chapters.

HTTP Request

GET /api/v3/courses/<course_id>/chapters/

URL Parameters

ParameterTypeDescription
course_idintegerID of the course whose chapters should be retrieved.

Query Parameters

ParameterTypeDescription
pageintegerOptional. Page number to retrieve. Defaults to 1.
page_sizeintegerOptional. Number of chapters per page. Defaults to 250.
parent_idinteger or nullOptional. Filters by parent chapter ID. Use null to retrieve root chapters.
order_bystringOptional. Student-specific order: last_opened, most_completed, or least_completed.
curl --request GET \
--url 'https://lmsdemo.testpress.in/api/v3/courses/1583/chapters/?parent_id=null' \
--header 'authorization: JWT your_jwt_token' \
--header 'cache-control: no-cache'

Response

The response separates chapter records from the authenticated student's progress. Match them using participant_progress[].chapter_id.

{
"count": 19,
"next": null,
"previous": null,
"per_page": 250,
"results": {
"chapters": [
{
"id": 3256,
"name": "Live Classes",
"description": "",
"slug": "live-classes",
"modified": "2026-08-18T13:24:58.610361+05:30",
"image": "https://d36vpug2b5drql.cloudfront.net/static/courses/general/chapter.png",
"course_id": 1583,
"parent_id": null,
"instructor_id": null,
"leaf": true,
"required_trophy_count": 0,
"order": 1,
"contents_count": 7,
"exams_count": 1,
"quizzes_count": 0,
"videos_count": 2,
"html_contents_count": 1,
"attachments_count": 1,
"video_conferences_count": 1,
"live_streams_count": 1
}
],
"participant_progress": [
{
"id": 901,
"user_id": 1639,
"chapter_id": 3256,
"contents_count": 7,
"completed_contents_count": 2,
"total_exam_attempts": 1,
"total_quiz_attempts": 0,
"total_html_attempts": 1,
"total_video_attempts": 1,
"total_attachment_attempts": 0,
"total_video_conference_attempts": 0,
"total_live_stream_attempts": 0,
"total_unique_exam_attempts": 1,
"total_unique_quiz_attempts": 0,
"total_unique_html_attempts": 1,
"total_unique_video_attempts": 0,
"total_unique_attachment_attempts": 0,
"total_unique_video_conference_attempts": 0,
"total_unique_live_stream_attempts": 0
}
]
}
}

Get Course Contents

This endpoint retrieves contents available to the authenticated student within a course. Each page contains lightweight content records and the related type-specific records needed to render them.

HTTP Request

GET /api/v3/courses/<course_id>/contents/

URL Parameters

ParameterTypeDescription
course_idintegerID of the course whose contents should be retrieved.

Query Parameters

ParameterTypeDescription
pageintegerOptional. Page number to retrieve. Defaults to 1.
page_sizeintegerOptional. Number of contents per page. Defaults to 100.
idsstringOptional. Comma-separated chapter-content IDs.
tagstringOptional. Filters by an exact content tag name.
chapterintegerOptional. Filters by chapter ID.
statestringOptional. running returns started content that has not ended; upcoming returns content starting in the future.
attempt_statusstringOptional. attempt_started or unattempted, evaluated for the authenticated student.
free_previewbooleanOptional. Filters by free-preview availability.
typestringOptional. One of video, quiz, exam, pdf, attachment, notes, videoconference, livestream, or assignment.
ostringOptional. Sort by -start, start, -end, end, title, or -title.
curl --request GET \
--url 'https://lmsdemo.testpress.in/api/v3/courses/1583/contents/?chapter=3256&type=exam' \
--header 'authorization: JWT your_jwt_token' \
--header 'cache-control: no-cache'

Response Structure

KeyDescription
contentsCommon metadata for each chapter content on the current page. Use its type-specific ID, such as exam_id or video_id, to resolve details from the corresponding array.
examsExam details referenced by contents[].exam_id.
videosVideo details referenced by contents[].video_id.
video_conferencesVideo-conference details for the returned contents.
live_streamsLive-stream details for the returned contents.
attachmentsAttachment details referenced by contents[].attachment_id.
text_contentsNotes or HTML details referenced by contents[].content_id.
tagsTags used by the returned contents.
chaptersChapters containing the returned contents.
instructorsInstructors associated with those chapters.
content_attemptsThe authenticated student's attempts for contents on the current page. Match using chapter_content_id.

Response

This shortened example contains one exam content. Type-specific arrays that do not apply are empty.

{
"count": 1,
"next": null,
"previous": null,
"per_page": 100,
"results": {
"contents": [
{
"id": 10615,
"order": 1,
"chapter_id": 3256,
"free_preview": false,
"title": "Sample Exam",
"course_id": 1583,
"exam_id": 3239,
"content_id": null,
"video_id": null,
"attachment_id": null,
"content_type": "Exam",
"icon": "https://static.testpress.in/static/img/exam-icon.png",
"cover_image": "https://static.testpress.in/static/img/exam-icon.jpg",
"cover_image_medium": "https://static.testpress.in/static/img/exam-icon-medium.jpg",
"cover_image_small": "https://static.testpress.in/static/img/exam-icon-small.jpg",
"start": "2026-08-13T17:48:50+05:30",
"end": null,
"tags": [208],
"description": "",
"average_rating": "4.50",
"number_of_ratings": 5
}
],
"exams": [
{
"id": 3239,
"slug": "sample-exam",
"title": "Sample Exam",
"description": "",
"instructions": "",
"start_date": "2026-08-13T17:48:50+05:30",
"end_date": null,
"duration": "0:30:00",
"allow_retake": true,
"number_of_questions": 20,
"is_adaptive": false,
"sections": []
}
],
"videos": [],
"video_conferences": [],
"live_streams": [],
"attachments": [],
"text_contents": [],
"tags": [
{
"id": 208,
"name": "videos"
}
],
"chapters": [
{
"id": 3256,
"name": "Live Classes",
"course_id": 1583,
"parent_id": null,
"instructor_id": null,
"leaf": true,
"order": 1
}
],
"instructors": [],
"content_attempts": [
{
"id": 105236,
"user_id": 1639,
"course_id": 1583,
"chapter_id": 3256,
"chapter_content_id": 10615,
"content_type": "assessment",
"state": "Started",
"remaining_time": "1171.627827",
"assessment_id": 95537,
"user_video_conference_id": null,
"user_video_id": null,
"user_live_stream_id": null,
"user_content_id": null,
"user_attachment_id": null,
"correct_answers_count": 2,
"incorrect_answers_count": 1,
"created": "2026-08-18T10:00:00+05:30",
"completed_on": null
}
]
}
}

Get Chapter Content Details

This endpoint retrieves a single chapter content and the type-specific data required to display or launch it. The authenticated student must have permission to view the content.

Although course listing uses API v3, this content-detail endpoint is currently available under API v2.4.

HTTP Request

GET /api/v2.4/contents/<chapter_content_id>/

URL Parameters

ParameterTypeDescription
chapter_content_idintegerID of the chapter content to retrieve. This is the id returned in results.contents by the course-contents endpoint.
curl --request GET \
--url 'https://lmsdemo.testpress.in/api/v2.4/contents/10615/' \
--header 'authorization: JWT your_jwt_token' \
--header 'cache-control: no-cache'

Type-Specific Fields

Only the object matching the chapter content's type is populated. The other type-specific fields are null.

FieldPopulated forDescription
examExam or quizExam configuration, availability, sections, attempt information, and scoring rules. Use exam_start_url to launch a new attempt.
videoVideoVideo metadata and either uploaded-video streams or an embed code. Stream URLs can be time-limited.
html_contentNotesHTML content and estimated reading time.
attachmentAttachment or PDFAttachment metadata, download URL, rendering capability, and download permission.
video_conferenceVideo conferenceMeeting metadata and joining information. Access credentials can be short-lived.
live_streamLive streamStream status, playback URL, provider, and chat URL when available.

Common Response Fields

FieldDescription
is_lockedWhether progressive locking currently prevents the student from opening this content.
is_course_availableWhether the parent course is currently available to the student.
attempts_countNumber of attempts made by the authenticated student for this chapter content.
bookmark_idThe student's bookmark ID for this content, or null when it is not bookmarked.
start, end, has_startedThe student's effective availability window and whether it has begun.
previous_content_id, next_content_idIDs used to navigate between adjacent course contents. Either can be null.
related_contentsIDs of related chapter contents.
video_subtitleActive video subtitle metadata, or null.
enable_transcriptWhether transcript display is enabled for the video.

Response

This shortened example represents notes content. Responses for other content types retain the same common fields and populate their corresponding type-specific object.

{
"uuid": "d1456cc5-9c93-4d1f-bb10-cbbcd56c22fd",
"order": 2,
"exam": null,
"html_content_title": "Introduction",
"html_content_url": "https://lmsdemo.testpress.in/api/v2.3/contents/10615/html/",
"free_preview": false,
"url": "https://lmsdemo.testpress.in/api/v2.4/contents/10615/",
"modified": "2026-08-18T13:24:58.610361+05:30",
"attempts_url": "https://lmsdemo.testpress.in/api/v2.3/contents/10615/attempts/",
"chapter_id": 3256,
"chapter_slug": "live-classes",
"chapter_url": "https://lmsdemo.testpress.in/api/v2.4/chapters/live-classes/",
"id": 10615,
"video": null,
"name": "Introduction",
"image": "https://static.testpress.in/static/img/bookicon.png",
"attachment": null,
"live_stream": null,
"description": "",
"is_locked": false,
"attempts_count": 1,
"start": "2026-08-18T09:00:00+05:30",
"end": null,
"has_started": true,
"content_type": "Notes",
"title": "Introduction",
"bookmark_id": null,
"html_content": {
"id": 2048,
"title": "Introduction",
"text_html": "<p>Welcome to the course.</p>",
"read_time": 2
},
"active": true,
"comments_url": "https://lmsdemo.testpress.in/api/v2.3/contents/10615/comments/",
"video_conference": null,
"course_id": 1583,
"is_course_available": true,
"cover_image": null,
"cover_image_medium": null,
"cover_image_small": null,
"next_content_id": 10616,
"previous_content_id": 10614,
"is_uploaded_video": false,
"is_embedded_content": false,
"exam_start_url": null,
"is_ai_enabled": false,
"learnlens_asset_id": null,
"learnlens_asset_status": null,
"can_enable_learnlens_ai": false,
"ai_notes_url": null,
"related_contents": [],
"video_subtitle": null,
"enable_transcript": false
}

Possible access-related responses include 401 Unauthorized, 403 Forbidden, and 404 Not Found. Future scheduled content can return 403 Forbidden with error_code set to scheduled; if scheduled content is hidden by the course configuration, it returns 404 Not Found instead.

Get Chapter Content Artifacts

Artifacts are downloadable attachments that an administrator can add to any chapter content. For example, a video can include a worksheet, an exam can include a reference document, or a live class can include supporting notes.

This endpoint lists the artifacts currently available for a chapter content. The authenticated student must have permission to view that content.

HTTP Request

GET /api/v3/contents/<chapter_content_id>/artifacts/

URL Parameters

ParameterTypeDescription
chapter_content_idintegerNumeric chapter-content ID. Use results.contents[].id from the Course Contents API, not the chapter-content UUID or nested content ID.

Query Parameters

ParameterTypeDescription
pageintegerOptional. Page number to retrieve. Defaults to 1.
page_sizeintegerOptional. Number of artifacts per page. Defaults to 20.
curl --request GET \
--url 'https://lmsdemo.testpress.in/api/v3/contents/10639/artifacts/' \
--header 'authorization: JWT your_student_jwt'

Response Fields

FieldTypeDescription
idintegerUnique artifact ID.
namestringDownload name configured by the administrator.
urlstring or nullSigned download URL. It is null when the artifact requires an attempt and this student has not attempted the chapter content.
accessible_without_attemptbooleanWhether the student may download the artifact before attempting the chapter content.

Response

{
"count": 2,
"next": null,
"previous": null,
"per_page": 20,
"results": [
{
"id": 81,
"name": "Course Worksheet",
"url": "https://d36vpug2b5drql.cloudfront.net/private/course-worksheet.pdf?Policy=...&Signature=...",
"accessible_without_attempt": true
},
{
"id": 82,
"name": "Answer Key",
"url": null,
"accessible_without_attempt": false
}
]
}

Only active artifacts are returned. An artifact is excluded while its configured availability start is in the future or after its availability end has passed.

When accessible_without_attempt is false, the API returns the artifact metadata but withholds its download URL until the authenticated student has an attempt record for the parent chapter content. An attempt does not need to be completed to unlock the URL.

Artifact URLs are generated as signed download links and can expire. Student frontends should request artifacts when displaying or downloading them instead of permanently storing the returned URLs.

Possible responses include:

StatusMeaning
200Artifacts retrieved successfully. The results array can be empty.
401The request is not authenticated.
403The student cannot view the chapter content, it is locked, or course access is unavailable.
404The chapter content does not exist or scheduled content is hidden.