Get All Courses
URL: https://api.gradual-api.com/public-api/v1/courses
HTTP Method: GET
Content type: application/json
Tier: Medium
Query Parameters:
pageNum, number, optional, default 1pageSize, number, optional, default 50, max 200category, string, optional, course category name (e.g.Leadership). Must match an existing category exactly; an unknown name returns a 400 error.courseType, string, optional,StandardorSCORMstatus, string, optional,PublishedorUnpublishedfromDate, string, optional, format:YYYY-MM-DD, date will be padded to the start of the day. If afromDateis specified, the response will include courses created at or after 00:00 of the providedfromDate.toDate, string, optional, format:YYYY-MM-DD, date will be padded to the end of the day. Similarly, if atoDateis specified, the response will include courses created at or before 23:59 of the providedtoDate.
Response Example:
{"size": 2,"pageNumber": 1,"pageSize": 50,"results": [{"courseId": "665a1b2c3d4e5f6a7b8c9d0e","courseTitle": "Engineering Leadership Fundamentals","courseType": "Standard","courseStatus": "Published","courseCategory": "Leadership","courseTags": ["Onboarding","Leadership"],"access": "All Members","spaces": [],"courseUrl": "https://community.gradual/home/courses/engineering-leadership-fundamentals-ab12c","courseCoverUrl": "https://abc.cloudfront.net/uploads/test/cover-12345.png","instructor": "Sarah Chen","totalEnrolled": 45,"totalCompleted": 12,"courseCreatedTime": "2026-01-15T10:30:00.000Z","courseUpdatedTime": "2026-03-20T14:00:00.000Z"},{"courseId": "665a1b2c3d4e5f6a7b8c9d0f","courseTitle": "Compliance Training Module","courseType": "SCORM","courseStatus": "Published","courseCategory": "Compliance","courseTags": [],"access": "Selected Spaces Only","spaces": ["New Members","Moderators"],"courseUrl": "https://community.gradual/home/courses/compliance-training-module-cd34e","courseCoverUrl": "","instructor": "","totalEnrolled": 128,"totalCompleted": 89,"courseCreatedTime": "2025-11-01T08:00:00.000Z","courseUpdatedTime": "2026-04-10T09:15:00.000Z"}]}
Field notes:
courseStatusisPublishedfor published courses andUnpublishedfor drafts.courseTypeisStandardfor native courses andSCORMfor SCORM-uploaded courses. Learning Path containers are excluded from this listing.accessisAll Memberswhen the course has no space restriction, orSelected Spaces Onlywhen one or more spaces are listed inspaces.totalEnrolledandtotalCompletedreflect cumulative counts at the time of the request.
Get a Course by Course ID
URL: https://api.gradual-api.com/public-api/v1/courses/:courseId
HTTP Method: GET
Content type: application/json
Tier: Light
Path Parameters:
courseId, string, required, this is the unique identifier of the course
Response Example:
{"courseId": "665a1b2c3d4e5f6a7b8c9d0e","courseTitle": "Engineering Leadership Fundamentals","courseType": "Standard","courseStatus": "Published","courseCategory": "Leadership","courseTags": ["Onboarding","Leadership"],"access": "All Members","spaces": [],"courseUrl": "https://community.gradual/home/courses/engineering-leadership-fundamentals-ab12c","courseCoverUrl": "https://abc.cloudfront.net/uploads/test/cover-12345.png","instructor": "Sarah Chen","totalEnrolled": 45,"totalCompleted": 12,"courseCreatedTime": "2026-01-15T10:30:00.000Z","courseUpdatedTime": "2026-03-20T14:00:00.000Z"}
Response Example (course not found, 404):
{"message": "Course not found."}
Get Course Enrollees
URL: https://api.gradual-api.com/public-api/v1/courses/:courseId/enrollees
HTTP Method: GET
Content type: application/json
Tier: Medium
Path Parameters:
courseId, string, required, this is the unique identifier of the course
Query Parameters:
pageNum, number, optional, default 1pageSize, number, optional, default 50, max 200userEmail, string, optional, filter enrollees by their email address. Special characters must be URL-encoded — for example[email protected]must be sent asuser%[email protected]. Unencoded+is decoded as space by the URL parser and will be rejected with a400 invalid emailerror.userId, string, optional, filter enrollees by their user ID. This is the tenant-scoped user ID (the same ID returned in theuserIdresponse field) — not an internal account ID.
Response Example:
{"size": 2,"pageNumber": 1,"pageSize": 50,"results": [{"userId": "654d6623ea532ea2ac8ced28","enrolleeFirstName": "Jane","enrolleeLastName": "Doe","enrolleeDisplayName": "Jane Doe","enrolleePosition": "Software Engineer","enrolleeCompany": "Test Company","enrolledAt": "2026-01-20T14:30:00.000Z","status": "Completed","completedAt": "2026-02-15T09:00:00.000Z","progress": "100%","score": "90","enrolledInLearningPaths": "Leadership Track, Onboarding Path"},{"userId": "6553ce608b3f645e79d95034","enrolleeFirstName": "John","enrolleeLastName": "Smith","enrolleeDisplayName": "John Smith","enrolleePosition": "Product Manager","enrolleeCompany": "Gradual Inc","enrolledAt": "2026-03-10T08:00:00.000Z","status": "In Progress","completedAt": "","progress": "75%","score": "","enrolledInLearningPaths": ""}]}
Field notes:
statusis one ofEnrolled(enrolled but not started),In Progress,Completed,Incomplete,Passed, orFailed.progressis a percentage string (e.g."75%") computed from completed lessons. Always"100%"oncestatusisCompletedorPassed.scoreis the recorded quiz/assessment score, or empty string when not set.enrolledInLearningPathsis a comma-separated list of Learning Path names this specific enrollee is enrolled in that include this course. Empty string when the enrollee is enrolled directly without a Learning Path.
Response Example (course not found, 404):
{"message": "Course not found."}
Get Course Certificate Recipients
URL: https://api.gradual-api.com/public-api/v1/courses/:courseId/certificates
HTTP Method: GET
Content type: application/json
Tier: Medium
Path Parameters:
courseId, string, required, this is the unique identifier of the course
Query Parameters:
pageNum, number, optional, default 1pageSize, number, optional, default 50, max 200userEmail, string, optional, filter recipients by their email address. Special characters must be URL-encoded — for example[email protected]must be sent asuser%[email protected]. Unencoded+is decoded as space by the URL parser and will be rejected with a400 invalid emailerror.userId, string, optional, filter recipients by their user ID. This is the tenant-scoped user ID (the same ID returned in theuserIdresponse field) — not an internal account ID.certificateStatus, string, optional,IssuedorExpired
Response Example:
{"size": 2,"pageNumber": 1,"pageSize": 50,"results": [{"certificateId": "665a1b2c3d4e5f6a7b8c9d10","certificateName": "Engineering Leadership Certificate","userId": "654d6623ea532ea2ac8ced28","recipientName": "Jane Doe","recipientTitle": "Software Engineer","recipientCompany": "Test Company","certificateStatus": "Issued","issuedAt": "2026-02-15T09:00:00.000Z","expiryDate": "2028-02-15T00:00:00.000Z","certificateUrl": "https://community.gradual/home/certificate/abcd1234567890"},{"certificateId": "665a1b2c3d4e5f6a7b8c9d11","certificateName": "Engineering Leadership Certificate","userId": "6553ce608b3f645e79d95034","recipientName": "John Smith","recipientTitle": "Product Manager","recipientCompany": "Gradual Inc","certificateStatus": "Expired","issuedAt": "2025-06-01T10:00:00.000Z","expiryDate": "2026-06-01T00:00:00.000Z","certificateUrl": "https://community.gradual/home/certificate/efgh5678901234"}]}
Field notes:
certificateStatusisIssuedfor active certificates,Expiredfor certificates whoseexpiryDatehas passed, orRevokedfor certificates that have been manually revoked. TheExpiredfilter matches both certificates explicitly marked expired and issued certificates whose expiry date has elapsed. ThecertificateStatusquery filter accepts onlyIssuedorExpired; revoked certificates are returned in unfiltered results but cannot be filtered by status.expiryDateis empty string when the certificate has no expiry.recipientTitleandrecipientCompanyare captured from the recipient's profile at the time the certificate was issued; subsequent profile changes do not update them.
Response Example (course not found, 404):
{"message": "Course not found."}