Discovery API Documentation

Discovery API Documentation

This document describes the Discovery API endpoints for retrieving course and program information.

Authentication

All endpoints support two authentication methods:

  1. Session Authentication (for authenticated users)

    • Uses session cookies from a logged-in session
    • No additional headers required
  2. Action Secret Authentication (for unauthenticated/public access)

    • Header: actionsecret: <your_action_secret>
    • Required when making requests without an active session
    • Value must match the ACTION_SECRET setting

Note: If a user is authenticated via session, the actionsecret header is not required.


GET /blendxapi/discovery/courses/

Description: Retrieves a list of available courses with support for pagination, search, and filtering.

Endpoint: GET <https://lms_endpoint/blendxapi/discovery/courses/>

Request Parameters

Parameter Type Required Description
limit integer No Number of records to return per page (default: 8, min: 1, max: 100). Values outside this range are automatically clamped.
page integer No Page number (default: 1, 1-indexed).
search string No Search term for course name, description, or overview.
org string No Comma-separated list of organizations to filter by.
tags string No Comma-separated list of tags to filter by.
order_by string No Sort order in format {field}.{direction} (e.g., created_at.desc, display_name.asc). Default: created_at.desc. Direction defaults to desc if not specified. Note: display_name sorting requires Hasura configuration.
fields string No Response optimization parameter. Values: light (default) or full. light excludes heavy fields like overview (~70% smaller response, faster). full includes all fields including overview HTML content.

Response Format

The response is a JSON object containing the list of courses and pagination metadata.

Field Type Description
courses array List of course objects (see details below).
total_count integer Total number of courses matching the criteria.
has_more boolean Indicates if more pages are available.
limit integer The limit used for the current page.
page integer The current page number.
offset integer The offset calculated from the page number.
partial_errors object (optional) Included when some courses fail to serialize. Contains count (integer) and errors (array of error objects with course_id, error_type, error_message).

Course Object Attributes

The fields included depend on the fields parameter:

Light Mode (default) - Includes:

  • id (string): Unique UUID for the course
  • openedx_course_id (string): Open edX course identifier string
  • display_name (string): Course title
  • display_image (string): URL to the course card image
  • short_description (string): Brief course description
  • price (integer): Minimum price of the course (0 if free)
  • currency (string): Currency code for the price (e.g., “usd”)
  • start (string): Course start date (ISO 8601)
  • end (string): Course end date (ISO 8601)
  • org (string): Organization identifier
  • org_logo_url (string|null): URL to the organization logo
  • org_favicon_url (string|null): URL to the organization favicon
  • course_mode (string): The slug of the default (lowest price) mode (e.g., “honor”)
  • tags (array): List of tags associated with the course
  • is_invite_only (boolean): Indicates if the course is by invitation only
  • is_published (boolean): Indicates if the course is currently published
  • avg_rating (number): Average rating for the course (defaults to 0 if unavailable)

Full Mode - Includes all Light Mode fields plus:

  • overview (string): Full HTML description of the course
  • effort (string): Estimated time effort
  • enrollment_start (string): Enrollment start date (ISO 8601)
  • enrollment_end (string): Enrollment end date (ISO 8601)
  • certificate_available_date (string): Date when certificates become available
  • has_any_active_web_certificate (boolean): Indicates if an active web certificate exists
  • link_to_course (string): Direct URL to the course dashboard
  • language (string): Course language code (e.g., “en”)
  • self_paced (boolean): true if self-paced, false if instructor-led
  • number (string): Course number/code
  • course_video_url (string|null): URL to the course introduction video
  • available_course_modes (array): List of all available modes for this course

Example Request

# Light mode (fast, default)
curl -X GET "https://lms_endpoint/blendxapi/discovery/courses/?limit=20&page=2&search=python&fields=light" \
  -H "actionsecret: your_secret"

# Full mode (complete)
curl -X GET "https://lms_endpoint/blendxapi/discovery/courses/?limit=20&page=2&search=python&fields=full" \
  -H "actionsecret: your_secret"

# With filters
curl -X GET "https://lms_endpoint/blendxapi/discovery/courses/?org=TestOrg&tags=health,midwifery&order_by=display_name.asc" \
  -H "actionsecret: your_secret"

Example Response (Light Mode)

{
  "courses": [
    {
      "id": "267ce96d-1454-4292-aa42-1a0487c7eaaa",
      "openedx_course_id": "course-v1:Fundacion-Santa-Fe-de-Bogota+HOC201+2025_T2",
      "display_name": "Proyecto Warra Jaramia",
      "display_image": "https://lms.lms_endpoint/asset-v1:ZamsOrg+FOO346+type@asset+block@thumb.jpg",
      "short_description": "Sabiduría Ancestral en la Atención del Parto...",
      "price": 0,
      "currency": "usd",
      "start": "2025-02-01T00:00:00Z",
      "end": "2027-02-01T00:30:00Z",
      "org": "TestOrg",
      "org_logo_url": "https://lms_endpoint/static/org_logos/testorg.png",
      "org_favicon_url": "https://lms_endpoint/static/org_favicons/testorg.ico",
      "course_mode": "honor",
      "tags": ["health", "midwifery"],
      "is_invite_only": false,
      "is_published": true,
      "avg_rating": 4.5
    }
  ],
  "total_count": 1,
  "has_more": false,
  "limit": 20,
  "page": 2,
  "offset": 20
}

Example Response (Full Mode)

{
  "courses": [
    {
      "id": "267ce96d-1454-4292-aa42-1a0487c7eaaa",
      "openedx_course_id": "course-v1:Fundacion-Santa-Fe-de-Bogota+HOC201+2025_T2",
      "display_name": "Proyecto Warra Jaramia",
      "display_image": "https://lms.lms_endpoint/asset-v1:ZamsOrg+FOO346+type@asset+block@thumb.jpg",
      "short_description": "Sabiduría Ancestral en la Atención del Parto...",
      "overview": "<!DOCTYPE html>...",
      "price": 0,
      "currency": "usd",
      "start": "2025-02-01T00:00:00Z",
      "end": "2027-02-01T00:30:00Z",
      "effort": "01:00",
      "enrollment_start": "2025-01-01T00:00:00Z",
      "enrollment_end": "2025-03-01T00:00:00Z",
      "certificate_available_date": "2027-02-03T00:30:00Z",
      "has_any_active_web_certificate": false,
      "link_to_course": "https://apps.lms_endpoint/dashboard/course/course-v1:Fundacion...",
      "language": "en",
      "self_paced": false,
      "org": "TestOrg",
      "org_logo_url": "https://lms_endpoint/static/org_logos/testorg.png",
      "org_favicon_url": "https://lms_endpoint/static/org_favicons/testorg.ico",
      "number": "FOO346",
      "course_video_url": null,
      "course_mode": "honor",
      "available_course_modes": [
        {
          "modeSlug": "honor",
          "minPrice": 0,
          "modeDisplayName": "Honor",
          "currency": "usd",
          "visible": true
        }
      ],
      "tags": ["health", "midwifery"],
      "is_invite_only": false,
      "is_published": true,
      "avg_rating": 4.5
    }
  ],
  "total_count": 1,
  "has_more": false,
  "limit": 8,
  "page": 1,
  "offset": 0
}

Error Responses

401 Unauthorized

{
  "message": "Unauthorized",
  "status": "failed"
}

Cause: Invalid or missing actionsecret header for unauthenticated requests.

500 Internal Server Error

{
  "message": "Error fetching courses",
  "status": "failed"
}

Cause: Server error during course retrieval.


GET /blendxapi/discovery/course/{openedx_course_id}/

Description: Retrieves detailed information about a specific course.

Endpoint: GET <https://lms_endpoint/blendxapi/discovery/course/{openedx_course_id}/>

Path Parameters

Parameter Type Required Description
openedx_course_id string Yes Open edX course identifier (e.g., course-v1:org+course+run)

Request Parameters

None (all information comes from the path parameter).

Response Format

The response is a JSON object containing complete course details.

Course Object Attributes

Field Type Description
id string Unique UUID for the course
openedx_course_id string Open edX course identifier string
display_name string Course title
short_description string Brief course description
overview string Full HTML description of the course
course_image_url string Full URL to course image (note: different field name than display_image in list endpoint)
course_video_url string|null URL to the course introduction video
start string Course start date (ISO 8601)
start_display string Human-readable start date display
end string Course end date (ISO 8601)
effort string Estimated time effort
enrollment_start string Enrollment start date (ISO 8601)
enrollment_end string Enrollment end date (ISO 8601)
certificate_available_date string Date when certificates become available
has_any_active_web_certificate boolean Indicates if an active web certificate exists
language string Course language code (e.g., “en”)
self_paced boolean true if self-paced, false if instructor-led
is_invite_only boolean Indicates if the course is by invitation only
is_published boolean Indicates if the course is currently published
price integer Minimum price of the course (0 if free)
course_mode string The slug of the default (lowest price) mode (e.g., “honor”)
available_course_modes array List of all available modes for this course
organisation string Organization name (note: string, not an object like in list endpoint)
organisation_id string UUID of the organization
organisation_logo_url string|null URL to the organization logo
organisation_favicon_url string|null URL to the organization favicon
course_structure object Hierarchical course structure with sections and subsections (see structure below)
avg_rating number Average rating for the course
reviews array List of review objects for the course

Course Structure Object

The course_structure field contains:

Field Type Description
sections array List of course sections, each containing name, usage_key, hide_from_toc, visible_to_staff_only, and subsections array
total_sections integer Total number of sections
total_subsections integer Total number of subsections
course_info object Course metadata including course_key, title, published_at, published_version, days_early_for_beta, entrance_exam_id, self_paced, course_visibility

Example Request

curl -X GET "https://lms_endpoint/blendxapi/discovery/course/course-v1:Fundacion-Santa-Fe-de-Bogota+HOC201+2025_T2/" \
  -H "actionsecret: your_secret"

Example Response

{
  "id": "267ce96d-1454-4292-aa42-1a0487c7eaaa",
  "openedx_course_id": "course-v1:Fundacion-Santa-Fe-de-Bogota+HOC201+2025_T2",
  "display_name": "Proyecto Warra Jaramia",
  "short_description": "Sabiduría Ancestral en la Atención del Parto...",
  "overview": "<!DOCTYPE html>...",
  "course_image_url": "https://lms.lms_endpoint/asset-v1:ZamsOrg+FOO346+type@asset+block@thumb.jpg",
  "course_video_url": null,
  "start": "2025-02-01T00:00:00Z",
  "start_display": "February 1, 2025",
  "end": "2027-02-01T00:30:00Z",
  "effort": "01:00",
  "enrollment_start": "2025-01-01T00:00:00Z",
  "enrollment_end": "2025-03-01T00:00:00Z",
  "certificate_available_date": "2027-02-03T00:30:00Z",
  "has_any_active_web_certificate": false,
  "language": "en",
  "self_paced": false,
  "is_invite_only": false,
  "is_published": true,
  "price": 0,
  "course_mode": "honor",
  "available_course_modes": [
    {
      "modeSlug": "honor",
      "minPrice": 0,
      "modeDisplayName": "Honor",
      "currency": "usd",
      "visible": true
    }
  ],
  "organisation": "Fundacion Santa Fe de Bogota",
  "organisation_id": "123e4567-e89b-12d3-a456-426614174000",
  "organisation_logo_url": "https://lms_endpoint/static/org_logos/fundacion.png",
  "organisation_favicon_url": "https://lms_endpoint/static/org_favicons/fundacion.ico",
  "course_structure": {
    "sections": [
      {
        "name": "Introduction",
        "usage_key": "block-v1:...",
        "hide_from_toc": false,
        "visible_to_staff_only": false,
        "subsections": [
          {
            "name": "Getting Started",
            "usage_key": "block-v1:...",
            "inaccessible_after_due": false,
            "hide_from_toc": false,
            "visible_to_staff_only": false,
            "exam": null
          }
        ]
      }
    ],
    "total_sections": 1,
    "total_subsections": 1,
    "course_info": {
      "course_key": "course-v1:Fundacion-Santa-Fe-de-Bogota+HOC201+2025_T2",
      "title": "Proyecto Warra Jaramia",
      "published_at": "2024-01-01T00:00:00Z",
      "published_version": "abc123",
      "days_early_for_beta": 0,
      "entrance_exam_id": null,
      "self_paced": false,
      "course_visibility": "public"
    }
  },
  "avg_rating": 4.5,
  "reviews": [
    {
      "id": "review-uuid",
      "user": "John Doe",
      "rating": 5,
      "comment": "Excellent course!",
      "created_at": "2025-01-15T10:00:00Z"
    }
  ]
}

Error Responses

401 Unauthorized

{
  "message": "Unauthorized",
  "status": "failed"
}

Cause: Invalid or missing actionsecret header for unauthenticated requests.

404 Not Found

{
  "message": "Course not found",
  "status": "failed"
}

Cause: Course with the specified openedx_course_id does not exist.

500 Internal Server Error

{
  "message": "Error fetching course details",
  "status": "failed"
}

Cause: Server error during course detail retrieval.


POST /search/course_discovery/

Description: Searches for courses based on a given search string.

Endpoint: POST <https://lms_endpoint/search/course_discovery/>

Note: This endpoint is part of a separate external service (not part of the main discovery API codebase).

Request Parameters

The request must be sent as application/x-www-form-urlencoded.

Parameter Type Required Description
search_string string No The text to search for in course titles and descriptions.
page_size integer No Number of results per page (default: 20, max: 100).
page_index integer No Zero-based page index (default: 0).

Response Format

Field Type Description
took integer Time taken for the search (milliseconds).
total integer Total number of matching results.
max_score float Maximum relevance score of results.
results array List of matching course objects.
error string Error message (if any).

Example Request

curl -X POST "https://lms_endpoint/search/course_discovery/" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "search_string=AI" \
  -d "page_size=10" \
  -d "page_index=1"

Example Response

{
  "took": 8,
  "total": 6,
  "max_score": 1,
  "results": [
    {
      "_index": "course_info",
      "_type": "_doc",
      "_id": "course-v1:HealthOnCloud+Test101+2025_T1",
      "_ignored": [
        "content.overview.keyword"
      ],
      "data": {
        "id": "course-v1:HealthOnCloud+Test101+2025_T1",
        "course": "course-v1:HealthOnCloud+Test101+2025_T1",
        "content": {
          "display_name": "Health on Cloud Test",
          "overview": " About This Course Include your long course description here... ",
          "number": "Test101",
          "short_description": "It is a testing course "
        },
        "image_url": "/static/studio/images/pencils.jpg",
        "start": "2030-01-01T00:00:00+00:00",
        "number": "Test101",
        "org": "HealthOnCloud",
        "modes": ["honor"],
        "language": "ar",
        "invitation_only": true,
        "catalog_visibility": "both"
      },
      "score": 1
    }
  ]
}

Field Differences Between Endpoints

List Endpoint vs Single Course Endpoint

List Endpoint Field Single Course Endpoint Field Notes
display_image course_image_url Different field names for the same data
organisation (object) organisation (string) List endpoint may return organization object, detail endpoint returns name string
N/A organisation_id Only available in detail endpoint
N/A start_display Only available in detail endpoint
N/A course_structure Only available in detail endpoint
N/A reviews Only available in detail endpoint (list endpoint only has avg_rating)

Notes

  • The fields parameter on the list endpoint significantly affects response size. Use light mode for list views and full mode when detailed information is needed.
  • Organization filtering uses the Organization model as the source of truth - organization names are resolved to their short names internally.
  • Tag filtering supports comma-separated values and matches any of the provided tags.
  • The order_by parameter format is {field}.{direction} where direction can be asc or desc.
  • Partial errors may be included in list responses when some courses fail to serialize, allowing the response to succeed even if individual courses have issues.