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 1
  • pageSize, number, optional, default 50, max 200
  • category, string, optional, course category name (e.g. Leadership). Must match an existing category exactly; an unknown name returns a 400 error.
  • courseType, string, optional, Standard or SCORM
  • status, string, optional, Published or Unpublished
  • fromDate, string, optional, format: YYYY-MM-DD, date will be padded to the start of the day. If a fromDate is specified, the response will include courses created at or after 00:00 of the provided fromDate.
  • toDate, string, optional, format: YYYY-MM-DD, date will be padded to the end of the day. Similarly, if a toDate is specified, the response will include courses created at or before 23:59 of the provided toDate.

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:

  • courseStatus is Published for published courses and Unpublished for drafts.
  • courseType is Standard for native courses and SCORM for SCORM-uploaded courses. Learning Path containers are excluded from this listing.
  • access is All Members when the course has no space restriction, or Selected Spaces Only when one or more spaces are listed in spaces.
  • totalEnrolled and totalCompleted reflect 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 1
  • pageSize, number, optional, default 50, max 200
  • userEmail, string, optional, filter enrollees by their email address. Special characters must be URL-encoded — for example [email protected] must be sent as user%[email protected]. Unencoded + is decoded as space by the URL parser and will be rejected with a 400 invalid email error.
  • userId, string, optional, filter enrollees by their user ID. This is the tenant-scoped user ID (the same ID returned in the userId response field) — not an internal account ID.

Response Example:

{
"size": 2,
"pageNumber": 1,
"pageSize": 50,
"results": [
{
"userId": "654d6623ea532ea2ac8ced28",
"enrolleeFirstName": "Jane",
"enrolleeLastName": "Doe",
"enrolleeDisplayName": "Jane Doe",
"enrolleeEmail": "[email protected]",
"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",
"enrolleeEmail": "[email protected]",
"enrolleePosition": "Product Manager",
"enrolleeCompany": "Gradual Inc",
"enrolledAt": "2026-03-10T08:00:00.000Z",
"status": "In Progress",
"completedAt": "",
"progress": "75%",
"score": "",
"enrolledInLearningPaths": ""
}
]
}

Field notes:

  • status is one of Enrolled (enrolled but not started), In Progress, Completed, Incomplete, Passed, or Failed.
  • progress is a percentage string (e.g. "75%") computed from completed lessons. Always "100%" once status is Completed or Passed.
  • score is the recorded quiz/assessment score, or empty string when not set.
  • enrolledInLearningPaths is 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 1
  • pageSize, number, optional, default 50, max 200
  • userEmail, string, optional, filter recipients by their email address. Special characters must be URL-encoded — for example [email protected] must be sent as user%[email protected]. Unencoded + is decoded as space by the URL parser and will be rejected with a 400 invalid email error.
  • userId, string, optional, filter recipients by their user ID. This is the tenant-scoped user ID (the same ID returned in the userId response field) — not an internal account ID.
  • certificateStatus, string, optional, Issued or Expired

Response Example:

{
"size": 2,
"pageNumber": 1,
"pageSize": 50,
"results": [
{
"certificateId": "665a1b2c3d4e5f6a7b8c9d10",
"certificateName": "Engineering Leadership Certificate",
"userId": "654d6623ea532ea2ac8ced28",
"recipientName": "Jane Doe",
"recipientEmail": "[email protected]",
"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",
"recipientEmail": "[email protected]",
"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:

  • certificateStatus is Issued for active certificates, Expired for certificates whose expiryDate has passed, or Revoked for certificates that have been manually revoked. The Expired filter matches both certificates explicitly marked expired and issued certificates whose expiry date has elapsed. The certificateStatus query filter accepts only Issued or Expired; revoked certificates are returned in unfiltered results but cannot be filtered by status.
  • expiryDate is empty string when the certificate has no expiry.
  • recipientTitle and recipientCompany are 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."
}