> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rmz.gg/llms.txt
> Use this file to discover all available pages before exploring further.

# Courses

> Access enrolled courses, track progress, view module content, and mark modules as completed.

All course endpoints require customer authentication. Customers can only access courses they have purchased.

***

## GET /courses

List the authenticated customer's enrolled courses.

### Authentication

Requires Bearer token (`auth:customer_api`).

### Headers

| Header        | Value          | Required |
| ------------- | -------------- | -------- |
| Authorization | Bearer {token} | Yes      |

### Query Parameters

| Parameter | Type    | Required | Description                                        |
| --------- | ------- | -------- | -------------------------------------------------- |
| status    | string  | No       | Filter by status: `active`, `completed`, `expired` |
| per\_page | integer | No       | Items per page (1-50). Default: `10`               |

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://front.rmz.gg/api/courses?status=active&per_page=10" \
    -H "Authorization: Bearer 1|abc123xyz..."
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://front.rmz.gg/api/courses?status=active", {
    headers: { "Authorization": "Bearer 1|abc123xyz..." }
  });
  const data = await response.json();
  ```

  ```python Python theme={null}
  response = requests.get("https://front.rmz.gg/api/courses",
      headers={"Authorization": "Bearer 1|abc123xyz..."},
      params={"status": "active"}
  )
  data = response.json()
  ```

  ```php PHP theme={null}
  $response = Http::withToken("1|abc123xyz...")->get("https://front.rmz.gg/api/courses", [
      "status" => "active"
  ]);
  $data = $response->json();
  ```
</CodeGroup>

### Response

#### Success (200)

```json theme={null}
{
  "success": true,
  "data": [
    {
      "id": 1,
      "progress": 45.5,
      "status": "active",
      "enrolled_at": "2024-06-01 00:00:00",
      "completed_at": null,
      "expires_at": null,
      "last_accessed_at": "2024-06-10 14:30:00",
      "certificate_url": null,
      "is_expired": false,
      "course": {
        "id": 5,
        "name": "Web Development Fundamentals",
        "description": "Learn the basics of web development...",
        "short_description": "Learn the basics of web development...",
        "slug": "web-development-fundamentals",
        "instructor": "Ahmed Ali",
        "level": "beginner",
        "image": null,
        "total_modules": 10,
        "estimated_duration": 0,
        "difficulty_level": "beginner",
        "sequential_modules": false,
        "sections": [
          {
            "id": 1,
            "title": "Getting Started",
            "description": "Introduction to web development",
            "sort_index": 0,
            "modules": [
              {
                "id": 1,
                "title": "Introduction to HTML",
                "description": "Learn the basics of HTML",
                "content": "<h1>HTML Basics</h1>...",
                "video_url": null,
                "duration_minutes": 30,
                "sort_index": 0,
                "type": "text"
              }
            ]
          }
        ]
      },
      "completed_modules": [1, 2, 3],
      "completed_modules_count": 3,
      "is_completed": false,
      "is_active": true,
      "can_access": true,
      "created_at": "2024-06-01 00:00:00",
      "updated_at": "2024-06-10 14:30:00"
    }
  ],
  "pagination": {
    "current_page": 1,
    "last_page": 1,
    "per_page": 10,
    "total": 2,
    "from": 1,
    "to": 2,
    "has_more_pages": false,
    "next_page_url": null,
    "prev_page_url": null
  }
}
```

***

## GET /courses/{id}

Get details of a specific course enrollment, including module listing.

### Authentication

Requires Bearer token (`auth:customer_api`).

### Path Parameters

| Parameter | Type    | Description          |
| --------- | ------- | -------------------- |
| id        | integer | Course enrollment ID |

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://front.rmz.gg/api/courses/1" \
    -H "Authorization: Bearer 1|abc123xyz..."
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://front.rmz.gg/api/courses/1", {
    headers: { "Authorization": "Bearer 1|abc123xyz..." }
  });
  const data = await response.json();
  ```

  ```python Python theme={null}
  response = requests.get("https://front.rmz.gg/api/courses/1", headers={
      "Authorization": "Bearer 1|abc123xyz..."
  })
  data = response.json()
  ```

  ```php PHP theme={null}
  $response = Http::withToken("1|abc123xyz...")->get("https://front.rmz.gg/api/courses/1");
  $data = $response->json();
  ```
</CodeGroup>

### Response

#### Success (200)

```json theme={null}
{
  "success": true,
  "data": {
    "id": 1,
    "progress": 45.5,
    "status": "active",
    "enrolled_at": "2024-06-01 00:00:00",
    "completed_at": null,
    "expires_at": null,
    "last_accessed_at": "2024-06-10 14:30:00",
    "certificate_url": null,
    "is_expired": false,
    "course": {
      "id": 5,
      "name": "Web Development Fundamentals",
      "description": "Learn the basics of web development...",
      "short_description": "Learn the basics of web development...",
      "slug": "web-development-fundamentals",
      "instructor": "Ahmed Ali",
      "level": "beginner",
      "image": null,
      "total_modules": 10,
      "estimated_duration": 0,
      "difficulty_level": "beginner",
      "sequential_modules": false,
      "sections": [
        {
          "id": 1,
          "title": "Getting Started",
          "description": "Introduction to web development",
          "sort_index": 0,
          "modules": [
            {
              "id": 1,
              "title": "Introduction to HTML",
              "description": "Learn the basics of HTML",
              "content": "<h1>HTML Basics</h1>...",
              "video_url": null,
              "duration_minutes": 30,
              "sort_index": 0,
              "type": "text"
            },
            {
              "id": 2,
              "title": "CSS Basics",
              "description": "Learn the fundamentals of CSS styling",
              "content": "<h1>CSS Basics</h1>...",
              "video_url": null,
              "duration_minutes": 45,
              "sort_index": 1,
              "type": "text"
            }
          ]
        }
      ]
    },
    "completed_modules": [1, 2, 3],
    "completed_modules_count": 3,
    "is_completed": false,
    "is_active": true,
    "can_access": true,
    "created_at": "2024-06-01 00:00:00",
    "updated_at": "2024-06-10 14:30:00"
  }
}
```

#### Error Responses

| Status | Description          |
| ------ | -------------------- |
| 401    | Not authenticated    |
| 404    | Enrollment not found |

***

## GET /courses/{id}/progress

Get detailed progress for a course enrollment, including per-module completion status and estimated remaining time.

### Authentication

Requires Bearer token (`auth:customer_api`).

### Path Parameters

| Parameter | Type    | Description          |
| --------- | ------- | -------------------- |
| id        | integer | Course enrollment ID |

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://front.rmz.gg/api/courses/1/progress" \
    -H "Authorization: Bearer 1|abc123xyz..."
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://front.rmz.gg/api/courses/1/progress", {
    headers: { "Authorization": "Bearer 1|abc123xyz..." }
  });
  const data = await response.json();
  ```

  ```python Python theme={null}
  response = requests.get("https://front.rmz.gg/api/courses/1/progress", headers={
      "Authorization": "Bearer 1|abc123xyz..."
  })
  data = response.json()
  ```

  ```php PHP theme={null}
  $response = Http::withToken("1|abc123xyz...")->get("https://front.rmz.gg/api/courses/1/progress");
  $data = $response->json();
  ```
</CodeGroup>

### Response

#### Success (200)

```json theme={null}
{
  "success": true,
  "data": {
    "overall_progress": 50.0,
    "total_modules": 10,
    "completed_modules": 5,
    "estimated_remaining_time": 150,
    "modules": [
      {
        "id": 1,
        "title": "Introduction to HTML",
        "sort_order": 1,
        "is_completed": true,
        "duration_minutes": 30
      },
      {
        "id": 2,
        "title": "CSS Basics",
        "sort_order": 2,
        "is_completed": false,
        "duration_minutes": 45
      }
    ]
  }
}
```

<Note>
  The `estimated_remaining_time` is in minutes and is calculated from the `duration_minutes` of incomplete modules.
</Note>

#### Error Responses

| Status | Description          |
| ------ | -------------------- |
| 401    | Not authenticated    |
| 404    | Enrollment not found |

***

## GET /courses/{courseId}/modules/{moduleId}

Get the full content of a specific course module.

### Authentication

Requires Bearer token (`auth:customer_api`).

### Path Parameters

| Parameter | Type    | Description          |
| --------- | ------- | -------------------- |
| courseId  | integer | Course enrollment ID |
| moduleId  | integer | Module ID            |

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://front.rmz.gg/api/courses/1/modules/2" \
    -H "Authorization: Bearer 1|abc123xyz..."
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://front.rmz.gg/api/courses/1/modules/2", {
    headers: { "Authorization": "Bearer 1|abc123xyz..." }
  });
  const data = await response.json();
  ```

  ```python Python theme={null}
  response = requests.get("https://front.rmz.gg/api/courses/1/modules/2", headers={
      "Authorization": "Bearer 1|abc123xyz..."
  })
  data = response.json()
  ```

  ```php PHP theme={null}
  $response = Http::withToken("1|abc123xyz...")->get("https://front.rmz.gg/api/courses/1/modules/2");
  $data = $response->json();
  ```
</CodeGroup>

### Response

#### Success (200)

```json theme={null}
{
  "success": true,
  "data": {
    "id": 2,
    "title": "CSS Basics",
    "description": "Learn the fundamentals of CSS styling",
    "content": "<h1>CSS Basics</h1><p>In this module...</p>",
    "content_type": "html",
    "duration_minutes": 45,
    "sort_order": 2,
    "is_completed": false,
    "resources": [
      {
        "name": "CSS Reference Guide",
        "url": "https://..."
      }
    ]
  }
}
```

#### Error Responses

| Status | Description                                                                                           |
| ------ | ----------------------------------------------------------------------------------------------------- |
| 401    | Not authenticated                                                                                     |
| 403    | Enrollment not active, enrollment expired, or previous modules not completed (for sequential courses) |
| 404    | Enrollment or module not found                                                                        |

<Warning>
  If the course has `sequential_modules` enabled in its settings, you must complete all previous modules before accessing later ones. Attempting to skip ahead will return a 403 error.
</Warning>

***

## POST /courses/{courseId}/modules/{moduleId}/complete

Mark a course module as completed and update progress.

### Authentication

Requires Bearer token (`auth:customer_api`).

### Path Parameters

| Parameter | Type    | Description          |
| --------- | ------- | -------------------- |
| courseId  | integer | Course enrollment ID |
| moduleId  | integer | Module ID            |

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://front.rmz.gg/api/courses/1/modules/2/complete" \
    -H "Authorization: Bearer 1|abc123xyz..."
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://front.rmz.gg/api/courses/1/modules/2/complete", {
    method: "POST",
    headers: { "Authorization": "Bearer 1|abc123xyz..." }
  });
  const data = await response.json();
  ```

  ```python Python theme={null}
  response = requests.post("https://front.rmz.gg/api/courses/1/modules/2/complete", headers={
      "Authorization": "Bearer 1|abc123xyz..."
  })
  data = response.json()
  ```

  ```php PHP theme={null}
  $response = Http::withToken("1|abc123xyz...")->post("https://front.rmz.gg/api/courses/1/modules/2/complete");
  $data = $response->json();
  ```
</CodeGroup>

### Response

#### Success (200)

```json theme={null}
{
  "success": true,
  "data": {
    "progress": 60.0,
    "is_completed": false
  },
  "message": "Module marked as completed"
}
```

When the last module is completed:

```json theme={null}
{
  "success": true,
  "data": {
    "progress": 100.0,
    "is_completed": true
  },
  "message": "Module marked as completed"
}
```

<Tip>
  Marking a module as complete is idempotent. Completing an already-completed module will not change the progress or return an error.
</Tip>

#### Error Responses

| Status | Description                    |
| ------ | ------------------------------ |
| 401    | Not authenticated              |
| 403    | Enrollment not active          |
| 404    | Enrollment or module not found |

***

## Legacy Course Endpoints

The following endpoints are maintained for backward compatibility. They use the `customer/courses` prefix and are handled by the OrderController.

### GET /customer/courses

List the customer's course enrollments. Same functionality as `GET /courses`.

### GET /customer/courses/{id}

Get a specific course enrollment. Same functionality as `GET /courses/{id}`.

### GET /customer/courses/{id}/modules/{module}

Get a course module with pagination-style navigation (previous/next module links). Returns the module content alongside a `navigation` object.

#### Response

```json theme={null}
{
  "success": true,
  "data": {
    "course": { ... },
    "module": { ... },
    "navigation": {
      "next": 3,
      "previous": 1
    }
  }
}
```

### POST /customer/courses/{courseId}/modules/{moduleId}/complete

Mark a course module as completed. Same functionality as `POST /courses/{courseId}/modules/{moduleId}/complete`.

<Note>
  New integrations should use the `/courses/*` endpoints instead of `/customer/courses/*`. The legacy endpoints remain available for backward compatibility.
</Note>
