Get Course
This endpoint retrieves a single course by its unique identifier.
Endpoint
GET /api/course/:id
The id can also be supplied as a query parameter:
GET /api/course?id=:id
Authentication
Authentication is optional. Unauthenticated requests can read publicly accessible courses; authenticated requests include user-specific data where applicable.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | Integer | Yes | Unique identifier of the course to retrieve |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
include | String | No | Comma-separated list of associations to eagerly load. Currently supported: tree — embeds the full Course → Collections → Contents outline (see below). |
Response
Success Response (default)
- Status Code: 200 OK
- Content: The course object
{
"id": 42,
"title": "Intro to Stoicism",
"description": "<p>A 6-week journey through the Stoic foundations.</p>",
"image": "1700000000000_tsf.png",
"publishedDate": "2025-01-15T00:00:00.000Z",
"hidden": false,
"PlatformId": 36,
"authorId": 9846,
"createdAt": "2025-01-10T19:24:52.000Z",
"updatedAt": "2025-01-10T19:24:52.000Z"
}
Success Response (?include=tree)
The course object plus a CollectionsManyToMany array. Each collection contains its Contents (lessons) inline:
{
"id": 42,
"title": "Intro to Stoicism",
"description": "<p>...</p>",
"PlatformId": 36,
"CollectionsManyToMany": [
{
"id": 100,
"name": "Module 1 — Foundations",
"slug": "module-1-foundations",
"sortPreference": "manual",
"Contents": [
{
"id": 5001,
"title": "Welcome",
"slug": "welcome",
"type": "video",
"visibility": "public",
"publishedDate": "2025-01-15T00:00:00.000Z"
}
]
}
]
}
Collections are ordered by their position within the course (the CollectionCourses.position junction column). Contents within each collection are ordered by the collection's sortPreference (most recent first, chronological, or manual).
Visibility rules with ?include=tree
- Admins and creators see all contents — hidden, unpublished (future
publishedDate), and expired (pastexpireDate) — to match/api/admin/courses. - Members and unauthenticated requests see only contents that are currently visible: not
visibility: "hidden",publishedDate <= now,expireDate >= now, and not moderation-flagged.
The course row itself is returned regardless of its hidden flag — callers are expected to filter hidden courses client-side if needed (mirrors the existing /api/courses behaviour).
Error Responses
- 404 Not Found — No course exists with the supplied ID.
- 500 Internal Server Error — Unexpected server error.
Notes
- Without
?include=tree, this endpoint returns the core course record only. - Admin / dashboard surfaces that need every association (groups, keywords, junction rows) should keep using List Admin Courses.
- For member-facing course-detail pages,
?include=treeis the lightweight path — non-admin, single round-trip, visibility-filtered.
Example
# Bare course row
curl -X GET "https://api.tribesocial.io/api/course/42" \
-H "Authorization: Bearer YOUR_AUTH_TOKEN"
# Full Course → Collections → Lessons outline
curl -X GET "https://api.tribesocial.io/api/course/42?include=tree" \
-H "Authorization: Bearer YOUR_AUTH_TOKEN"