Courses API
Retrieve the full catalog of publicly available courses on the Edraak e-learning platform. The API returns paginated course listings with bilingual metadata, category, enrollment stats, and parent program information.
https://www.edraak.org/api/marketing/courses/
01 Authentication
This endpoint is publicly accessible and does not require any authentication headers or API keys. You can make requests directly from a browser, server, or any HTTP client without credentials.
02 Pagination
The API uses offset-based pagination. Each response contains a count of total records, a next URL, and a previous URL. The default page size is 100 courses per request.
Example — traversing pages
offset=0 → Page 2
offset=100 → Page 3
offset=200 → null (end)
count field from any response to get the live total.
03 Endpoints
Returns a paginated list of all publicly available Edraak courses, including their metadata, category classification, enrollment numbers, and parent program associations.
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| limit | integer | optional | 100 |
Maximum number of results to return per page. |
| offset | integer | optional | 0 |
Number of records to skip. Use with limit for pagination. |
Example Request
GET https://www.edraak.org/api/marketing/courses/?limit=10&offset=0
Accept: application/json
04 Response Schema
All successful responses return a JSON object with the following top-level structure:
| Field | Type | Description |
|---|---|---|
| count | integer | Total number of courses available across all pages. |
| next | string nullable | Full URL to the next page of results. null on the last page. |
| previous | string nullable | Full URL to the previous page. null on the first page. |
| results | Course[] | Array of course objects for the current page. |
| Field | Type | Description |
|---|---|---|
| id | string | Unique course identifier. Format: course/<slug> |
| slug | string | URL-safe identifier for the course, identical to id. |
| name_ar | string | Course name in Arabic. |
| name_en | string | Course name in English. |
| cover_image | string (URL) | Absolute URL to the course cover image hosted on Edraak's CDN. |
| self_paced | boolean | true if learners can progress at their own pace, false for scheduled/instructor-led courses. |
| short_description | string | Brief Arabic summary of the course content. |
| category | Category nullable | Category object the course belongs to. May be null for uncategorized courses. |
| course_url | string (URL) | Full URL to the course info page on edraak.org. |
| program_type | string | Always "course" for this endpoint. |
| level | string | Difficulty level of the course. See enum values below. |
| enrollment_count | integer | Total number of learners enrolled in the course. |
| effort | integer | Estimated hours of effort required to complete the course. |
| parent_program | ParentProgram nullable | If the course belongs to a specialization, this contains its parent program. Otherwise null. |
level — Enum Values
| Field | Type | Description |
|---|---|---|
| id | integer | Unique numeric identifier for the category. |
| slug | string | URL-safe identifier for the category (e.g. technology). |
| name_en | string | Category name in English. |
| name_ar | string | Category name in Arabic. |
| ar | string | Alias for name_ar. |
| en | string | Alias for name_en. |
| pinned_on_top | boolean | Whether this category is pinned at the top of category listings. |
| Field | Type | Description |
|---|---|---|
| name_ar | string | Name of the parent specialization in Arabic. |
| name_en | string | Name of the parent specialization in English. |
| slug | string | Unique slug for the parent program. Format: specialization/<id> |
| program_type | string | Always "specialization" for parent programs. |
Sample Response
{
"count": 245,
"next": "https://www.edraak.org/api/marketing/courses/?limit=100&offset=100",
"previous": null,
"results": [
{
"id": "course/gamedeign-v1",
"slug": "course/gamedeign-v1",
"name_ar": "تصميم الألعاب الإلكترونية",
"name_en": "Game Design",
"cover_image": "https://edraak-marketing-uploads.edraak.org/...",
"self_paced": true,
"short_description": "تهدف هذه الدورة إلى توفير أساس أكاديمي...",
"category": {
"id": 14,
"slug": "technology",
"name_en": "Technology",
"name_ar": "التكنولوجيا",
"ar": "التكنولوجيا",
"en": "Technology",
"pinned_on_top": false
},
"course_url": "https://www.edraak.org/courses/course/gamedeign-v1/info",
"program_type": "course",
"level": "entry",
"enrollment_count": 67346,
"effort": 3,
"parent_program": {
"name_ar": "تصميم الألعاب الإلكترونية باستخدام Unity",
"name_en": "Game development using Unity",
"slug": "specialization/unity-v1",
"program_type": "specialization"
}
}
]
}
05 Errors
The API uses standard HTTP status codes.
06 Code Examples
# pip install requests import requests BASE_URL = "https://www.edraak.org/api/marketing/courses/" def fetch_all_courses(): courses = [] url = BASE_URL params = {"limit": 100, "offset": 0} while url: response = requests.get(BASE_URL, params=params) response.raise_for_status() data = response.json() courses.extend(data["results"]) params["offset"] += params["limit"] # Stop when there's no next page if not data["next"]: break return courses # Fetch first page only resp = requests.get(BASE_URL, params={"limit": 10, "offset": 0}) data = resp.json() print(f"Total courses: {data['count']}") for course in data["results"]: print(f" [{course['level']}] {course['name_en']} — {course['enrollment_count']} enrolled")
// Custom hook — useCourses.js import { useState, useEffect } from "react"; const BASE_URL = "https://www.edraak.org/api/marketing/courses/"; export function useCourses({ limit = 20, offset = 0 } = {}) { const [courses, setCourses] = useState([]); const [total, setTotal] = useState(0); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const params = new URLSearchParams({ limit, offset }); fetch(`${BASE_URL}?${params}`) .then((r) => r.json()) .then((data) => { setCourses(data.results); setTotal(data.count); }) .catch(setError) .finally(() => setLoading(false)); }, [limit, offset]); return { courses, total, loading, error }; } // CourseList.jsx — example component export default function CourseList() { const { courses, total, loading } = useCourses({ limit: 20 }); if (loading) return <p>Loading...</p>; return ( <div> <h1>{total} Courses Available</h1> {courses.map((course) => ( <div key={course.id}> <img src={course.cover_image} alt={course.name_en} /> <h2>{course.name_en}</h2> <p>Level: {course.level} · Effort: {course.effort}h</p> <p>Enrolled: {course.enrollment_count.toLocaleString()}</p> <a href={course.course_url}>View Course →</a> </div> ))} </div> ); }
# First page (default 100 results) curl -X GET \ "https://www.edraak.org/api/marketing/courses/" \ -H "Accept: application/json" | python3 -m json.tool # Custom page size and offset curl -G "https://www.edraak.org/api/marketing/courses/" \ --data-urlencode "limit=20" \ --data-urlencode "offset=40" # Pretty print with jq — show course names and enrollment curl -s "https://www.edraak.org/api/marketing/courses/" \ | jq '.results[] | {name: .name_en, enrolled: .enrollment_count}'
07 Known Categories
The following category IDs and slugs are observed in the API:
| ID | Slug | Name (EN) | Name (AR) |
|---|---|---|---|
| 1 | business-and-entrepreneurship | Business and Entrepreneurship | الأعمال والريادة |
| 2 | health | Health and Nutrition | الصحة والتغذية |
| 4 | stem | Science & Environment | العلوم والبيئة |
| 12 | education-and-teaching | Education and Teaching | التعليم وتدريب المعلمين |
| 13 | personal-development | Personal Development | تطوير الذات |
| 14 | technology | Technology | التكنولوجيا |
| 15 | humanities | Humanities | العلوم الإنسانية |
| 17 | art-design-media | Art, Design & Media | الفن، التصميم والإعلام |
| 18 | career-readiness | Career Readiness | الاستعداد الوظيفي |
| 19 | languages | Languages | اللغات |
| 20 | built-environment | Built Environment | البيئة المبنية |