# API Integration Coverage & Backend Requirements

**Document Version:** 1.1  
**Date:** 2024-12-19  
**Last Updated:** 2024-12-19  
**Frontend Framework:** Nuxt 3  
**Backend Framework:** Laravel  
**API Base URL:** `https://research-api.zentiaai.com/public/api`

---

## Important Notes

### Route Decisions

1. **Job Applications**: Changed from `POST /job-posts/{id}/apply` to `POST /job-applications` (with `job_post_id` in request body) for better RESTful design.

2. **Exam Attempts**: Kept as `/exam-attempts/{id}` (top-level resource) for flexibility - allows accessing attempts independently and filtering by `exam_id` via query parameters.

3. **Researcher Team**: Changed to `/researchers/{id}/team` (multi-purpose endpoint) - `{id}` can be current user's researcher ID to get their own team, or any other researcher's ID to view their team.

4. **Project Versions**: Kept as nested `/projects/{id}/versions` - versions are always scoped to a project.

---

## Table of Contents

1. [Executive Summary](#executive-summary)
2. [Currently Integrated APIs](#currently-integrated-apis)
3. [Missing API Integrations](#missing-api-integrations)
4. [Detailed Endpoint Specifications](#detailed-endpoint-specifications)
5. [Authentication & Authorization](#authentication--authorization)
6. [Error Handling Standards](#error-handling-standards)
7. [Implementation Priority](#implementation-priority)

---

## Executive Summary

### Integration Status Overview

| Feature Area | Integrated | Missing | Total Endpoints |
|-------------|-----------|---------|----------------|
| Authentication | 7 | 3 | 10 |
| User Management | 4 | 2 | 6 |
| Researcher Search | 5 | 0 | 5 |
| Jobs | 4 | 5 | 9 |
| Courses | 4 | 8 | 12 |
| Projects | 4 | 7 | 11 |
| Exams & Certifications | 0 | 12 | 12 |
| Subscriptions & Payments | 0 | 8 | 8 |
| Notifications | 0 | 5 | 5 |
| File Uploads | 0 | 3 | 3 |
| Profile Management | 1 | 3 | 4 |
| **TOTAL** | **29** | **56** | **85** |

### Key Findings

- **34% Integration Coverage**: 29 out of 85 endpoints are currently integrated
- **Critical Missing Areas**: Exams, Subscriptions, Notifications, File Uploads
- **Partially Integrated**: Jobs (applications missing), Courses (enrollment/progress missing), Projects (collaboration missing)

---

## Currently Integrated APIs

### 1. Authentication & Authorization

#### ✅ POST `/auth/login`
- **Status**: ✅ Integrated
- **Request Body**:
  ```json
  {
    "email": "string",
    "password": "string"
  }
  ```
- **Response**:
  ```json
  {
    "token": "string",
    "user": { ... }
  }
  ```

#### ✅ GET `/auth/me`
- **Status**: ✅ Integrated
- **Headers**: `Authorization: Bearer {token}`
- **Response**:
  ```json
  {
    "user": {
      "id": "integer",
      "name": "string",
      "email": "string",
      "role": "string",
      ...
    }
  }
  ```

#### ✅ POST `/auth/signup`
- **Status**: ✅ Integrated

#### ✅ POST `/auth/logout`
- **Status**: ✅ Integrated

#### ✅ POST `/auth/forgot-password`
- **Status**: ✅ Integrated

#### ✅ POST `/auth/reset-password`
- **Status**: ✅ Integrated

#### ✅ POST `/auth/google/verify`
- **Status**: ✅ Integrated (via useGoogleAuth composable)

### 2. User Management

#### ✅ GET `/users`
- **Status**: ✅ Integrated

#### ✅ PUT `/users/{id}`
- **Status**: ✅ Integrated

#### ✅ POST `/users/{id}` (Profile Picture)
- **Status**: ✅ Integrated

#### ✅ DELETE `/users/{id}`
- **Status**: ✅ Integrated

### 3. Researcher Search

#### ✅ POST `/search/intelligent`
- **Status**: ✅ Integrated
- **Request Body**:
  ```json
  {
    "query": "string",
    "source": "frontend",
    "filters": {}
  }
  ```
- **Response**:
  ```json
  {
    "data": {
      "researchers": [],
      "insights": {},
      "suggestions": [],
      "total": "integer",
      "search_time_ms": "integer"
    }
  }
  ```

#### ✅ GET `/search/suggestions`
- **Status**: ✅ Integrated

#### ✅ GET `/search/categories`
- **Status**: ✅ Integrated

#### ✅ GET `/search/popular`
- **Status**: ✅ Integrated

#### ✅ POST `/search/track-click`
- **Status**: ✅ Integrated

### 4. Researchers

#### ✅ GET `/researchers`
- **Status**: ✅ Integrated
- **Query Parameters**: `verified`, filters

#### ✅ GET `/researchers/details/{id}`
- **Status**: ✅ Integrated

#### ✅ DELETE `/researchers/{id}`
- **Status**: ✅ Integrated

### 5. Jobs

#### ✅ GET `/job-posts`
- **Status**: ✅ Integrated

#### ✅ POST `/job-posts`
- **Status**: ✅ Integrated

#### ✅ PUT `/job-posts/{id}`
- **Status**: ✅ Integrated

#### ✅ DELETE `/job-posts/{id}`
- **Status**: ✅ Integrated

### 6. Courses

#### ✅ GET `/courses`
- **Status**: ✅ Integrated

#### ✅ POST `/courses`
- **Status**: ✅ Integrated

#### ✅ PUT `/courses/{id}`
- **Status**: ✅ Integrated

#### ✅ DELETE `/courses/{id}`
- **Status**: ✅ Integrated

### 7. Projects

#### ✅ GET `/projects`
- **Status**: ✅ Integrated

#### ✅ POST `/projects`
- **Status**: ✅ Integrated

#### ✅ PUT `/projects/{id}`
- **Status**: ✅ Integrated

#### ✅ DELETE `/projects/{id}`
- **Status**: ✅ Integrated

### 8. Profile Management

#### ✅ POST `/profile/upgrade`
- **Status**: ✅ Integrated (Learner to Researcher upgrade)

---

## Missing API Integrations

### 1. Authentication & OAuth (3 endpoints)

#### ❌ GET `/auth/{provider}/redirect`
**Purpose**: Initiate OAuth flow for Google/LinkedIn  
**Method**: GET  
**Query Parameters**:
- `action`: `string` (required) - 'login', 'signup', or 'link'
- `redirect_uri`: `string` (required) - Frontend callback URL

**Expected Response**: Redirect to OAuth provider

**Laravel Implementation Notes**:
- Should redirect user to OAuth provider (Google/LinkedIn)
- Store state parameter for CSRF protection
- Store action and redirect_uri in session

---

#### ❌ POST `/auth/{provider}/callback`
**Purpose**: Handle OAuth callback and exchange code for token  
**Method**: POST  
**Request Body**:
```json
{
  "code": "string",
  "state": "string",
  "action": "string",
  "role": "string|null",
  "redirect_uri": "string"
}
```

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "OAuth authentication successful",
  "data": {
    "token": "string",
    "user": {
      "id": "integer",
      "name": "string",
      "email": "string",
      "role": "string",
      "profile_complete": "boolean"
    },
    "requires_profile_completion": "boolean"
  }
}
```

**Laravel Implementation Notes**:
- Verify state parameter
- Exchange authorization code for access token
- Fetch user info from provider
- Create or update user account
- Generate JWT token
- Return user data with token

---

#### ❌ POST `/auth/{provider}/unlink`
**Purpose**: Unlink OAuth account from user profile  
**Method**: POST  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Application status updated successfully"
}
```

**Laravel Implementation Notes**:
- Verify user is authenticated
- Remove OAuth connection from database
- Ensure user has at least one login method remaining

---

### 2. User Management (2 endpoints)

#### ❌ POST `/users/{id}/upload-avatar`
**Purpose**: Upload user profile picture  
**Method**: POST  
**Headers**: 
- `Authorization: Bearer {token}`
- `Content-Type: multipart/form-data`

**Request Body** (FormData):
- `avatar`: `file` (required) - Image file (jpg, png, webp)
- Max size: 5MB

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Avatar uploaded successfully",
  "data": {
    "avatar_url": "string"
  }
}
```

**Laravel Implementation Notes**:
- Validate file type and size
- Store in `storage/app/public/avatars`
- Generate thumbnail if needed
- Update user record with avatar URL
- Return public URL

---

#### ❌ GET `/users/{id}/activity`
**Purpose**: Get user activity log  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Query Parameters**:
- `page`: `integer` (optional, default: 1)
- `limit`: `integer` (optional, default: 20)
- `type`: `string` (optional) - Filter by activity type

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "User activity retrieved successfully",
  "data": [
    {
      "id": "integer",
      "type": "string",
      "description": "string",
      "created_at": "datetime",
      "metadata": {}
    }
  ],
  "meta": {
    "current_page": "integer",
    "per_page": "integer",
    "total": "integer",
    "last_page": "integer",
    "from": "integer",
    "to": "integer",
    "path": "/api/users/{id}/activity",
    "first_page_url": "string",
    "last_page_url": "string",
    "next_page_url": "string|null",
    "prev_page_url": "string|null"
  }
}
```

---

### 3. Jobs (5 endpoints)

#### ❌ POST `/job-applications`
**Purpose**: Submit job application  
**Method**: POST  
**Headers**: 
- `Authorization: Bearer {token}`
- `Content-Type: multipart/form-data`

**Request Body** (FormData):
```json
{
  "job_post_id": "integer",
  "first_name": "string",
  "last_name": "string",
  "email": "string",
  "phone": "string",
  "resume": "file",
  "cover_letter": "string",
  "experience_level": "string",
  "available_date": "date",
  "notice_period": "string",
  "salary_expectation": "integer|null",
  "remote_interested": "boolean",
  "additional_answers": "array",
  "consent_data": "boolean",
  "consent_marketing": "boolean"
}
```

**Response**:
```json
{
  "code": 201,
  "error": false,
  "status": "success",
  "message": "Job application submitted successfully",
  "data": {
    "id": "integer",
    "job_post_id": "integer",
    "application_id": "integer"
  }
}
```

**Laravel Implementation Notes**:
- Validate all required fields
- Store resume file in `storage/app/public/resumes`
- Create application record
- Send notification to recruiter
- Return application ID

---

#### ❌ GET `/job-posts/{id}/applicants`
**Purpose**: Get list of applicants for a job posting  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Query Parameters**:
- `status`: `string` (optional) - Filter by status (applied, reviewing, shortlisted, rejected, hired)
- `page`: `integer` (optional)
- `limit`: `integer` (optional)
- `search`: `string` (optional) - Search by name/email

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Applicants retrieved successfully",
  "data": [
    {
      "id": "integer",
      "name": "string",
      "email": "string",
      "phone": "string",
      "location": "string",
      "experience_level": "string",
      "status": "string",
      "applied_at": "datetime",
      "cover_letter": "string",
      "salary_expectation": "integer|null",
      "skills": ["string"],
      "profile_photo": "string|null",
      "resume_url": "string"
    }
  ],
  "meta": {
    "current_page": "integer",
    "per_page": "integer",
    "total": "integer",
    "last_page": "integer",
    "from": "integer",
    "to": "integer",
    "path": "/api/job-posts/{id}/applicants",
    "first_page_url": "string",
    "last_page_url": "string",
    "next_page_url": "string|null",
    "prev_page_url": "string|null"
  }
}
```

---

#### ❌ PUT `/job-applications/{id}/status`
**Purpose**: Update application status  
**Method**: PUT  
**Headers**: `Authorization: Bearer {token}`

**Request Body**:
```json
{
  "status": "string"
}
```

**Valid Status Values**: `applied`, `reviewing`, `shortlisted`, `rejected`, `hired`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Application status updated successfully"
}
```

---

#### ❌ GET `/job-applications/{id}/resume`
**Purpose**: Download applicant resume  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Response**: File download (PDF/DOC/DOCX)

**Laravel Implementation Notes**:
- Verify user has permission to view application
- Return file with appropriate headers
- Log download activity

---

#### ❌ POST `/job-posts/{id}/schedule-interview`
**Purpose**: Schedule interview with applicant  
**Method**: POST  
**Headers**: `Authorization: Bearer {token}`

**Request Body**:
```json
{
  "application_id": "integer",
  "interview_date": "datetime",
  "interview_time": "time",
  "location": "string",
  "interview_type": "string",
  "notes": "string|null"
}
```

**Response**:
```json
{
  "code": 201,
  "error": false,
  "status": "success",
  "message": "Interview scheduled successfully",
  "data": {
    "interview_id": "integer"
  }
}
```

---

### 4. Courses (8 endpoints)

#### ❌ POST `/courses/{id}/enroll`
**Purpose**: Enroll user in a course  
**Method**: POST  
**Headers**: `Authorization: Bearer {token}`

**Request Body**:
```json
{
  "payment_method_id": "integer|null"
}
```

**Response**:
```json
{
  "code": 201,
  "error": false,
  "status": "success",
  "message": "Enrolled in course successfully",
  "data": {
    "enrollment": {
      "id": "integer",
      "course_id": "integer",
      "user_id": "integer",
      "enrolled_at": "datetime",
      "progress": "integer",
      "status": "string"
    }
  }
}
```

**Laravel Implementation Notes**:
- Check course availability
- Verify prerequisites if applicable
- Process payment if course is paid
- Create enrollment record
- Grant access to course content

---

#### ❌ GET `/courses/{id}/progress`
**Purpose**: Get user's progress in a course  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Course progress retrieved successfully",
  "data": {
    "enrollment_id": "integer",
    "course_id": "integer",
    "progress_percentage": "integer",
    "lessons_completed": "integer",
    "total_lessons": "integer",
    "time_spent_minutes": "integer",
    "last_accessed_at": "datetime",
    "completed_at": "datetime|null",
    "certificate_eligible": "boolean"
  }
}
```

---

#### ❌ PUT `/courses/{id}/progress`
**Purpose**: Update course progress  
**Method**: PUT  
**Headers**: `Authorization: Bearer {token}`

**Request Body**:
```json
{
  "lesson_id": "integer",
  "completed": "boolean",
  "time_spent_seconds": "integer"
}
```

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Course progress updated successfully",
  "data": {
    "progress_percentage": "integer",
    "lessons_completed": "integer"
  }
}
```

---

#### ❌ GET `/courses/{id}/lessons`
**Purpose**: Get course lessons  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Course lessons retrieved successfully",
  "data": [
    {
      "id": "integer",
      "title": "string",
      "description": "string",
      "duration_minutes": "integer",
      "video_url": "string|null",
      "content_url": "string|null",
      "order": "integer",
      "completed": "boolean",
      "unlocked": "boolean"
    }
  ]
}
```

---

#### ❌ GET `/courses/{id}/download`
**Purpose**: Download course for offline access  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Response**: 
- Content-Type: `application/zip` or streaming download
- Course content packaged for offline use

**Laravel Implementation Notes**:
- Package course videos, PDFs, and materials
- Generate secure download link
- Track download activity
- Set expiration for download link

---

#### ❌ POST `/courses/{id}/complete`
**Purpose**: Mark course as completed  
**Method**: POST  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Course completed successfully",
  "data": {
    "certificate_eligible": "boolean",
    "certificate_url": "string|null"
  }
}
```

---

#### ❌ GET `/courses/enrolled`
**Purpose**: Get user's enrolled courses  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Query Parameters**:
- `status`: `string` (optional) - `active`, `completed`, `paused`
- `page`: `integer` (optional)
- `limit`: `integer` (optional)

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Enrolled courses retrieved successfully",
  "data": [
    {
      "id": "integer",
      "course": {
        "id": "integer",
        "title": "string",
        "description": "string",
        "thumbnail": "string"
      },
      "progress": "integer",
      "enrolled_at": "datetime",
      "last_accessed_at": "datetime",
      "status": "string"
    }
  ],
  "meta": {
    "current_page": "integer",
    "per_page": "integer",
    "total": "integer",
    "last_page": "integer",
    "from": "integer",
    "to": "integer",
    "path": "/api/courses/enrolled",
    "first_page_url": "string",
    "last_page_url": "string",
    "next_page_url": "string|null",
    "prev_page_url": "string|null"
  }
}
```

---

#### ❌ POST `/courses/{id}/sync-progress`
**Purpose**: Sync offline course progress with server  
**Method**: POST  
**Headers**: `Authorization: Bearer {token}`

**Request Body**:
```json
{
  "lessons_completed": [
    {
      "lesson_id": "integer",
      "completed_at": "datetime",
      "time_spent_seconds": "integer"
    }
  ],
  "last_sync_at": "datetime"
}
```

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Course progress synced successfully",
  "data": {
    "synced_count": "integer",
    "updated_progress": "integer"
  }
}
```

---

### 5. Projects (7 endpoints)

#### ❌ POST `/projects/{id}/versions`
**Purpose**: Upload new project version  
**Method**: POST  
**Headers**: 
- `Authorization: Bearer {token}`
- `Content-Type: multipart/form-data`

**Request Body** (FormData):
```json
{
  "file": "file",
  "version_number": "string",
  "notes": "string|null",
  "changes_summary": "string|null"
}
```

**Response**:
```json
{
  "code": 201,
  "error": false,
  "status": "success",
  "message": "Project version uploaded successfully",
  "data": {
    "version": {
      "id": "integer",
      "version_number": "string",
      "file_url": "string",
      "uploaded_at": "datetime",
      "notes": "string",
      "changes_summary": "string"
    }
  }
}
```

---

#### ❌ GET `/projects/{id}/versions`
**Purpose**: Get project versions  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Project versions retrieved successfully",
  "data": [
    {
      "id": "integer",
      "version_number": "string",
      "file_url": "string",
      "uploaded_at": "datetime",
      "uploaded_by": {
        "id": "integer",
        "name": "string"
      },
      "notes": "string",
      "changes_summary": "string",
      "file_size": "integer"
    }
  ]
}
```

---

#### ❌ GET `/projects/{id}/milestones`
**Purpose**: Get project milestones  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Project milestones retrieved successfully",
  "data": [
    {
      "id": "integer",
      "title": "string",
      "description": "string",
      "due_date": "date",
      "status": "string",
      "completion_criteria": "string",
      "completed_at": "datetime|null",
      "order": "integer"
    }
  ],
  "meta": {
    "summary": {
      "total": "integer",
      "completed": "integer",
      "in_progress": "integer",
      "not_started": "integer"
    }
  }
}
```

---

#### ❌ PUT `/projects/{id}/milestones/{milestone_id}`
**Purpose**: Update milestone status  
**Method**: PUT  
**Headers**: `Authorization: Bearer {token}`

**Request Body**:
```json
{
  "status": "string",
  "notes": "string|null"
}
```

**Valid Status Values**: `not_started`, `in_progress`, `in_review`, `completed`, `blocked`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Milestone updated successfully",
  "data": {
    "milestone": { ... }
  }
}
```

---

#### ❌ GET `/projects/{id}/collaborators`
**Purpose**: Get project collaborators  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Project collaborators retrieved successfully",
  "data": [
    {
      "id": "integer",
      "user": {
        "id": "integer",
        "name": "string",
        "email": "string",
        "profile_photo": "string"
      },
      "role": "string",
      "added_at": "datetime",
      "permissions": {
        "can_edit": "boolean",
        "can_upload_versions": "boolean",
        "can_manage_milestones": "boolean"
      }
    }
  ]
}
```

---

#### ❌ POST `/projects/{id}/collaborators`
**Purpose**: Add collaborator to project  
**Method**: POST  
**Headers**: `Authorization: Bearer {token}`

**Request Body**:
```json
{
  "user_id": "integer",
  "role": "string",
  "permissions": {
    "can_edit": "boolean",
    "can_upload_versions": "boolean",
    "can_manage_milestones": "boolean"
  }
}
```

**Response**:
```json
{
  "code": 201,
  "error": false,
  "status": "success",
  "message": "Collaborator added successfully",
  "data": {
    "collaborator": { ... }
  }
}
```

---

#### ❌ DELETE `/projects/{id}/collaborators/{collaborator_id}`
**Purpose**: Remove collaborator from project  
**Method**: DELETE  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Application status updated successfully"
}
```

---

#### ❌ POST `/projects/{id}/scope-document`
**Purpose**: Upload scope document for project  
**Method**: POST  
**Headers**: 
- `Authorization: Bearer {token}`
- `Content-Type: multipart/form-data`

**Request Body** (FormData):
```json
{
  "file": "file",
  "document_type": "string"
}
```

**Response**:
```json
{
  "code": 201,
  "error": false,
  "status": "success",
  "message": "Scope document uploaded successfully",
  "data": {
    "document_url": "string"
  }
}
```

---

### 6. Exams & Certifications (12 endpoints)

#### ❌ GET `/exams`
**Purpose**: Get available exams  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Query Parameters**:
- `status`: `string` (optional) - `available`, `upcoming`, `completed`
- `category`: `string` (optional)
- `page`: `integer` (optional)

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Exams retrieved successfully",
  "data": [
    {
      "id": "integer",
      "title": "string",
      "description": "string",
      "duration_minutes": "integer",
      "passing_score": "integer",
      "max_attempts": "integer",
      "attempts_used": "integer",
      "questions_count": "integer",
      "category": "string",
      "available_from": "datetime",
      "available_until": "datetime|null",
      "status": "string",
      "passed": "boolean|null"
    }
  ],
  "meta": {
    "current_page": "integer",
    "per_page": "integer",
    "total": "integer",
    "last_page": "integer",
    "from": "integer",
    "to": "integer",
    "path": "/api/exams",
    "first_page_url": "string",
    "last_page_url": "string",
    "next_page_url": "string|null",
    "prev_page_url": "string|null"
  }
}
```

---

#### ❌ GET `/exams/{id}`
**Purpose**: Get exam details  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Exam details retrieved successfully",
  "data": {
    "id": "integer",
    "title": "string",
    "description": "string",
    "duration_minutes": "integer",
    "passing_score": "integer",
    "max_attempts": "integer",
    "attempts_used": "integer",
    "questions_count": "integer",
    "instructions": "string",
    "available_from": "datetime",
    "available_until": "datetime|null",
    "can_take": "boolean",
    "attempts_remaining": "integer"
  }
}
```

---

#### ❌ POST `/exams/{id}/start`
**Purpose**: Start exam attempt  
**Method**: POST  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 201,
  "error": false,
  "status": "success",
  "message": "Exam attempt started successfully",
  "data": {
    "attempt": {
      "id": "integer",
      "exam_id": "integer",
      "started_at": "datetime",
      "expires_at": "datetime",
      "time_remaining_seconds": "integer",
      "questions": [
        {
          "id": "integer",
          "question": "string",
          "type": "string",
          "options": ["string"],
          "points": "integer"
        }
      ]
    }
  }
}
```

**Laravel Implementation Notes**:
- Verify user has attempts remaining
- Check exam availability
- Create exam attempt record
- Randomize question order
- Set expiration time
- Return questions (without correct answers)

---

#### ❌ GET `/exam-attempts/{id}`
**Purpose**: Get exam attempt details (for resuming)  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Exam attempt retrieved successfully",
  "data": {
    "id": "integer",
    "exam_id": "integer",
    "status": "string",
    "started_at": "datetime",
    "submitted_at": "datetime|null",
    "expires_at": "datetime",
    "time_remaining_seconds": "integer",
    "answers": {
      "question_id": "answer_value"
    },
    "questions": [ ... ]
  }
}
```

---

#### ❌ PUT `/exam-attempts/{id}/answers`
**Purpose**: Save exam answers (auto-save)  
**Method**: PUT  
**Headers**: `Authorization: Bearer {token}`

**Request Body**:
```json
{
  "answers": {
    "question_id": "answer_value"
  }
}
```

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Answers saved successfully",
  "data": {
    "saved_at": "datetime"
  }
}
```

---

#### ❌ POST `/exam-attempts/{id}/submit`
**Purpose**: Submit exam for grading  
**Method**: POST  
**Headers**: `Authorization: Bearer {token}`

**Request Body**:
```json
{
  "answers": {
    "question_id": "answer_value"
  }
}
```

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Exam submitted successfully",
  "data": {
    "result": {
      "attempt_id": "integer",
      "score": "integer",
      "passing_score": "integer",
      "passed": "boolean",
      "questions_answered": "integer",
      "total_questions": "integer",
      "correct_answers": "integer",
      "incorrect_answers": "integer",
      "time_taken_seconds": "integer",
      "attempt_number": "integer",
      "max_attempts": "integer",
      "attempts_remaining": "integer",
      "certificate_eligible": "boolean"
    }
  }
}
```

**Laravel Implementation Notes**:
- Validate all questions answered
- Calculate score
- Check if passing
- Update attempt record
- Increment attempts used
- Generate certificate if eligible
- Return detailed results

---

#### ❌ GET `/exam-attempts`
**Purpose**: Get user's exam attempts  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Query Parameters**:
- `exam_id`: `integer` (optional)
- `status`: `string` (optional) - `in_progress`, `submitted`, `expired`
- `page`: `integer` (optional)

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Exam attempts retrieved successfully",
  "data": [
    {
      "id": "integer",
      "exam": {
        "id": "integer",
        "title": "string"
      },
      "status": "string",
      "score": "integer|null",
      "passed": "boolean|null",
      "started_at": "datetime",
      "submitted_at": "datetime|null"
    }
  ],
  "meta": {
    "current_page": "integer",
    "per_page": "integer",
    "total": "integer",
    "last_page": "integer",
    "from": "integer",
    "to": "integer",
    "path": "/api/exam-attempts",
    "first_page_url": "string",
    "last_page_url": "string",
    "next_page_url": "string|null",
    "prev_page_url": "string|null"
  }
}
```

---

#### ❌ POST `/exams/{id}/book`
**Purpose**: Book exam slot  
**Method**: POST  
**Headers**: `Authorization: Bearer {token}`

**Request Body**:
```json
{
  "exam_type": "string",
  "date": "date",
  "time": "time",
  "location": "string"
}
```

**Response**:
```json
{
  "code": 201,
  "error": false,
  "status": "success",
  "message": "Exam slot booked successfully",
  "data": {
    "booking": {
      "id": "integer",
      "exam_id": "integer",
      "date": "date",
      "time": "time",
      "location": "string",
      "status": "string"
    }
  }
}
```

---

#### ❌ GET `/certificates`
**Purpose**: Get user's certificates  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Certificates retrieved successfully",
  "data": [
    {
      "id": "integer",
      "title": "string",
      "issuer": "string",
      "issued_date": "date",
      "certificate_url": "string",
      "verification_code": "string",
      "verified": "boolean",
      "badge": "string"
    }
  ]
}
```

---

#### ❌ GET `/certificates/{id}`
**Purpose**: Get certificate details  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Certificate details retrieved successfully",
  "data": {
    "id": "integer",
    "title": "string",
    "issuer": "string",
    "issued_date": "date",
    "certificate_url": "string",
    "verification_code": "string",
    "verified": "boolean",
    "exam": {
      "id": "integer",
      "title": "string"
    },
    "score": "integer",
    "pdf_download_url": "string"
  }
}
```

---

#### ❌ GET `/certificates/{id}/download`
**Purpose**: Download certificate PDF  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Response**: PDF file download

---

#### ❌ GET `/exams/{id}/study-materials`
**Purpose**: Get study materials for exam  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Study materials retrieved successfully",
  "data": [
    {
      "id": "integer",
      "title": "string",
      "type": "string",
      "file_url": "string",
      "size": "integer",
      "download_count": "integer"
    }
  ]
}
```

---

### 7. Subscriptions & Payments (8 endpoints)

#### ❌ GET `/subscriptions/plans`
**Purpose**: Get available subscription plans  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}` (optional)

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Subscription plans retrieved successfully",
  "data": [
    {
      "id": "string",
      "name": "string",
      "description": "string",
      "price": "decimal",
      "currency": "string",
      "interval": "string",
      "popular": "boolean",
      "features": ["string"],
      "limits": {
        "job_postings": "integer",
        "candidate_searches": "integer",
        "team_members": "integer"
      }
    }
  ]
}
```

---

#### ❌ GET `/subscriptions/current`
**Purpose**: Get user's current subscription  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Current subscription retrieved successfully",
  "data": {
    "id": "integer",
    "plan": {
      "id": "string",
      "name": "string",
      "price": "decimal",
      "currency": "string",
      "interval": "string"
    },
    "status": "string",
    "started_at": "datetime",
    "expires_at": "datetime|null",
    "next_billing_date": "datetime|null",
    "canceled_at": "datetime|null",
    "usage": {
      "job_postings": {
        "used": "integer",
        "limit": "integer"
      },
      "candidate_searches": {
        "used": "integer",
        "limit": "integer"
      },
      "team_members": {
        "used": "integer",
        "limit": "integer"
      }
    }
  }
}
```

---

#### ❌ POST `/subscriptions/subscribe`
**Purpose**: Subscribe to a plan  
**Method**: POST  
**Headers**: `Authorization: Bearer {token}`

**Request Body**:
```json
{
  "plan_id": "string",
  "payment_method_id": "integer",
  "coupon_code": "string|null"
}
```

**Response**:
```json
{
  "code": 201,
  "error": false,
  "status": "success",
  "message": "Subscription created successfully",
  "data": {
    "subscription": { ... },
    "payment": {
      "id": "integer",
      "status": "string",
      "amount": "decimal",
      "currency": "string"
    }
  }
}
```

**Laravel Implementation Notes**:
- Process payment via payment gateway
- Create subscription record
- Set up recurring billing if applicable
- Grant plan features
- Send confirmation email

---

#### ❌ POST `/subscriptions/cancel`
**Purpose**: Cancel subscription  
**Method**: POST  
**Headers**: `Authorization: Bearer {token}`

**Request Body**:
```json
{
  "reason": "string|null",
  "cancel_immediately": "boolean"
}
```

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Subscription cancelled successfully",
  "data": {
    "cancels_at": "datetime"
  }
}
```

---

#### ❌ GET `/payment-methods`
**Purpose**: Get user's payment methods  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Payment methods retrieved successfully",
  "data": [
    {
      "id": "integer",
      "type": "string",
      "brand": "string|null",
      "last4": "string|null",
      "expiry_month": "integer|null",
      "expiry_year": "integer|null",
      "provider": "string|null",
      "phone": "string|null",
      "is_default": "boolean",
      "nickname": "string"
    }
  ]
}
```

---

#### ❌ POST `/payment-methods`
**Purpose**: Add payment method  
**Method**: POST  
**Headers**: `Authorization: Bearer {token}`

**Request Body**:
```json
{
  "type": "string",
  "card_number": "string|null",
  "expiry_month": "integer|null",
  "expiry_year": "integer|null",
  "cvv": "string|null",
  "provider": "string|null",
  "phone": "string|null",
  "nickname": "string",
  "is_default": "boolean"
}
```

**Response**:
```json
{
  "code": 201,
  "error": false,
  "status": "success",
  "message": "Payment method added successfully",
  "data": {
    "payment_method": { ... }
  }
}
```

**Laravel Implementation Notes**:
- Use payment gateway tokenization (Stripe, PayPal, etc.)
- Store tokenized payment method
- Never store full card details
- Support card and mobile money

---

#### ❌ DELETE `/payment-methods/{id}`
**Purpose**: Delete payment method  
**Method**: DELETE  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Payment method deleted successfully"
}
```

---

#### ❌ GET `/billing/history`
**Purpose**: Get billing history  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Query Parameters**:
- `page`: `integer` (optional)
- `limit`: `integer` (optional)

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Billing history retrieved successfully",
  "data": [
    {
      "id": "string",
      "date": "date",
      "amount": "decimal",
      "currency": "string",
      "status": "string",
      "plan": "string",
      "period": "string",
      "invoice_url": "string",
      "pdf_url": "string"
    }
  ],
  "meta": {
    "current_page": "integer",
    "per_page": "integer",
    "total": "integer",
    "last_page": "integer",
    "from": "integer",
    "to": "integer",
    "path": "/api/billing/history",
    "first_page_url": "string",
    "last_page_url": "string",
    "next_page_url": "string|null",
    "prev_page_url": "string|null"
  }
}
```

---

### 8. Notifications (5 endpoints)

#### ❌ GET `/notifications`
**Purpose**: Get user notifications  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Query Parameters**:
- `read`: `boolean` (optional) - Filter by read status
- `type`: `string` (optional) - Filter by notification type
- `page`: `integer` (optional)
- `limit`: `integer` (optional)

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Notifications retrieved successfully",
  "data": [
    {
      "id": "integer",
      "type": "string",
      "title": "string",
      "message": "string",
      "read": "boolean",
      "created_at": "datetime",
      "data": {
        "url": "string",
        "action": "string"
      }
    }
  ],
  "meta": {
    "unread_count": "integer",
    "current_page": "integer",
    "per_page": "integer",
    "total": "integer",
    "last_page": "integer",
    "from": "integer",
    "to": "integer",
    "path": "/api/notifications",
    "first_page_url": "string",
    "last_page_url": "string",
    "next_page_url": "string|null",
    "prev_page_url": "string|null"
  }
}
```

**Notification Types**:
- `job_application`
- `project_invite`
- `course_update`
- `exam_reminder`
- `certificate_issued`
- `payment_received`
- `subscription_expiring`

---

#### ❌ PUT `/notifications/{id}/read`
**Purpose**: Mark notification as read  
**Method**: PUT  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Notification marked as read"
}
```

---

#### ❌ PUT `/notifications/read-all`
**Purpose**: Mark all notifications as read  
**Method**: PUT  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "All notifications marked as read",
  "data": {
    "marked_count": "integer"
  }
}
```

---

#### ❌ DELETE `/notifications/{id}`
**Purpose**: Delete notification  
**Method**: DELETE  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Notification marked as read"
}
```

---

#### ❌ GET `/notifications/unread-count`
**Purpose**: Get unread notification count  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Unread count retrieved successfully",
  "data": {
    "count": "integer"
  }
}
```

---

### 9. File Uploads (3 endpoints)

#### ❌ POST `/upload`
**Purpose**: Generic file upload endpoint  
**Method**: POST  
**Headers**: 
- `Authorization: Bearer {token}`
- `Content-Type: multipart/form-data`

**Request Body** (FormData):
```json
{
  "file": "file",
  "type": "string",
  "folder": "string|null"
}
```

**File Types**: `document`, `image`, `video`, `audio`, `avatar`, `resume`, `project_file`

**Response**:
```json
{
  "code": 201,
  "error": false,
  "status": "success",
  "message": "File uploaded successfully",
  "data": {
    "file": {
      "id": "integer",
      "url": "string",
      "filename": "string",
      "size": "integer",
      "mime_type": "string",
      "uploaded_at": "datetime"
    }
  }
}
```

**Laravel Implementation Notes**:
- Validate file type and size
- Store in appropriate directory based on type
- Generate unique filename
- Return public URL
- Support chunked uploads for large files

---

#### ❌ POST `/upload/chunk`
**Purpose**: Upload file chunk (for large files)  
**Method**: POST  
**Headers**: 
- `Authorization: Bearer {token}`
- `Content-Type: multipart/form-data`

**Request Body** (FormData):
```json
{
  "chunk": "file",
  "chunkIndex": "integer",
  "totalChunks": "integer",
  "fileName": "string",
  "fileSize": "integer",
  "uploadId": "string"
}
```

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Chunk received successfully",
  "data": {
    "chunk_received": "boolean",
    "upload_id": "string"
  }
}
```

**Laravel Implementation Notes**:
- Store chunks temporarily
- Validate chunk order
- Combine chunks when all received
- Clean up old incomplete uploads

---

#### ❌ POST `/upload/chunk/complete`
**Purpose**: Complete chunked upload  
**Method**: POST  
**Headers**: `Authorization: Bearer {token}`

**Request Body**:
```json
{
  "upload_id": "string",
  "file_type": "string"
}
```

**Response**:
```json
{
  "code": 201,
  "error": false,
  "status": "success",
  "message": "Chunked upload completed successfully",
  "data": {
    "file": {
      "id": "integer",
      "url": "string",
      "filename": "string",
      "size": "integer"
    }
  }
}
```

---

### 10. Profile Management (3 endpoints)

#### ❌ GET `/profile/eligibility`
**Purpose**: Check profile upgrade eligibility  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Profile eligibility checked successfully",
  "data": {
    "eligible": "boolean",
    "completion_percentage": "integer",
    "met_requirements": "integer",
    "total_requirements": "integer",
    "missing_requirements": ["string"],
    "requirements": {
      "has_bio": "boolean",
      "has_skills": "boolean",
      "has_courses": "boolean",
      "has_email": "boolean",
      "has_name": "boolean"
    }
  }
}
```

---

#### ❌ GET `/researchers/{id}/team`
**Purpose**: Get researcher team members (multi-purpose endpoint)  
**Method**: GET  
**Headers**: `Authorization: Bearer {token}`

**Route Parameters**:
- `id`: `integer` - Researcher profile ID. Can be current user's researcher ID (to get own team) or any other researcher's ID (to view their team, if permitted).

**Response**:
```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Team members retrieved successfully",
  "data": [
    {
      "id": "integer",
      "user": {
        "id": "integer",
        "name": "string",
        "email": "string",
        "profile_photo": "string"
      },
      "role": "string",
      "added_at": "datetime"
    }
  ]
}
```

---

#### ❌ POST `/researchers/{id}/team`
**Purpose**: Add team member to researcher's team  
**Method**: POST  
**Headers**: `Authorization: Bearer {token}`

**Route Parameters**:
- `id`: `integer` - Researcher profile ID (must be current user's researcher ID or user must have permission)

**Request Body**:
```json
{
  "user_id": "integer",
  "role": "string"
}
```

**Response**:
```json
{
  "code": 201,
  "error": false,
  "status": "success",
  "message": "Team member added successfully",
  "data": {
    "team_member": { ... }
  }
}
```

---

## Authentication & Authorization

### Token Format
- **Type**: Laravel Sanctum (Token-based authentication)
- **Storage**: Database (backend) / `localStorage` (frontend, key: `research_token`)
- **Header Format**: `Authorization: Bearer {token}`

### Token Expiration
- Access tokens can be configured to expire after a reasonable time (e.g., 24 hours)
- Implement refresh token mechanism if needed
- Return `401 Unauthorized` for expired or invalid tokens

### Role-Based Access Control
The following roles are used in the system:
- `student`
- `learner`
- `researcher`
- `recruiter`
- `admin`

Endpoints should verify user roles and permissions before processing requests.

---

## Response Format Standards

### Standard Success Response Format

All successful API responses follow this structure:

```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Operation successful",
  "data": {
    // Response data here
  }
}
```

### Pagination Response Format

Paginated responses wrap pagination metadata in a `meta` object:

```json
{
  "code": 200,
  "error": false,
  "status": "success",
  "message": "Data retrieved successfully",
  "data": [
    // Array of items
  ],
  "meta": {
    "current_page": 1,
    "per_page": 20,
    "total": 100,
    "last_page": 5,
    "from": 1,
    "to": 20,
    "path": "/api/resource",
    "first_page_url": "/api/resource?page=1",
    "last_page_url": "/api/resource?page=5",
    "next_page_url": "/api/resource?page=2",
    "prev_page_url": null
  }
}
```

---

## Error Handling Standards

### Standard Error Response Format

All error responses follow this structure:

```json
{
  "code": 422,
  "error": true,
  "status": "error",
  "message": "The given data was invalid.",
  "errors": {
    "email": ["The email field is required."],
    "password": ["The password must be at least 8 characters."]
  }
}
```

### HTTP Status Codes

- `200 OK` - Successful GET, PUT, DELETE
- `201 Created` - Successful POST (resource created)
- `400 Bad Request` - Validation errors, malformed request
- `401 Unauthorized` - Missing or invalid authentication
- `403 Forbidden` - Insufficient permissions
- `404 Not Found` - Resource not found
- `422 Unprocessable Entity` - Validation errors (Laravel standard)
- `500 Internal Server Error` - Server error

### Error Response Examples

**404 Not Found:**
```json
{
  "code": 404,
  "error": true,
  "status": "error",
  "message": "Resource Not Found"
}
```

**422 Validation Error:**
```json
{
  "code": 422,
  "error": true,
  "status": "error",
  "message": "The given data was invalid.",
  "errors": {
    "email": ["The email field is required."],
    "password": ["The password must be at least 8 characters."]
  }
}
```

**500 Server Error:**
```json
{
  "code": 500,
  "error": true,
  "status": "error",
  "message": "Internal server error occurred"
}
```

---

## Implementation Priority

### Phase 1: Critical (Week 1-2)
1. **OAuth Integration** (3 endpoints)
   - `/auth/{provider}/redirect`
   - `/auth/{provider}/callback`
   - `/auth/{provider}/unlink`

2. **File Uploads** (3 endpoints)
   - `/upload`
   - `/upload/chunk`
   - `/upload/chunk/complete`

3. **Notifications** (5 endpoints)
   - All notification endpoints

### Phase 2: High Priority (Week 3-4)
4. **Job Applications** (5 endpoints)
   - Application submission and management

5. **Course Enrollment & Progress** (8 endpoints)
   - Enrollment, progress tracking, offline sync

### Phase 3: Medium Priority (Week 5-6)
6. **Exams & Certifications** (12 endpoints)
   - Complete exam system

7. **Subscriptions & Payments** (8 endpoints)
   - Payment processing and subscription management

### Phase 4: Lower Priority (Week 7-8)
8. **Project Collaboration** (7 endpoints)
   - Versions, milestones, collaborators

9. **Profile Management** (3 endpoints)
   - Team management, eligibility checks

---

## Laravel Implementation Guidelines

### 1. Route Organization

Organize routes in `routes/api.php`:

```php
Route::middleware('auth:sanctum')->group(function () {
    // Protected routes
    Route::prefix('auth')->group(function () {
        Route::get('/{provider}/redirect', [OAuthController::class, 'redirect']);
        Route::post('/{provider}/callback', [OAuthController::class, 'callback']);
        Route::post('/{provider}/unlink', [OAuthController::class, 'unlink']);
    });
    
    Route::prefix('courses')->group(function () {
        Route::post('/{id}/enroll', [CourseController::class, 'enroll']);
        Route::get('/{id}/progress', [CourseController::class, 'getProgress']);
        // ... more routes
    });
    
    // ... other route groups
});
```

### 2. Controller Structure

Use resource controllers where appropriate:

```php
php artisan make:controller Api/ExamController --api
php artisan make:controller Api/NotificationController --api
```

### 3. Request Validation

Create Form Request classes for complex validation:

```php
php artisan make:request StoreJobApplicationRequest
php artisan make:request UpdateExamAttemptRequest
```

### 4. Response Formatting

Use Laravel's API Resources for consistent responses:

```php
php artisan make:resource ExamResource
php artisan make:resource NotificationResource
```

### 5. File Storage

Configure storage in `config/filesystems.php`:

```php
'avatars' => [
    'driver' => 'local',
    'root' => storage_path('app/public/avatars'),
    'url' => env('APP_URL').'/storage/avatars',
    'visibility' => 'public',
],
```

### 6. Database Migrations

Create migrations for new tables:

```php
php artisan make:migration create_exam_attempts_table
php artisan make:migration create_notifications_table
php artisan make:migration create_subscriptions_table
```

---

## Testing Requirements

### API Testing Checklist

For each endpoint, ensure:
- [ ] Authentication is required (where applicable)
- [ ] Authorization is enforced (role-based access)
- [ ] Input validation works correctly
- [ ] Error responses follow standard format
- [ ] Success responses include all required fields
- [ ] File uploads handle large files
- [ ] Pagination works correctly
- [ ] Filtering and sorting work as expected

### Recommended Testing Tools

- **Laravel**: PHPUnit for unit tests, Pest for feature tests
- **API Testing**: Postman collections, Insomnia
- **Load Testing**: Apache Bench, JMeter

---

## Additional Notes

### CORS Configuration

Ensure CORS is properly configured in Laravel to allow requests from the frontend domain.

### Rate Limiting

Implement rate limiting for:
- Authentication endpoints
- File upload endpoints
- API endpoints in general

### Caching

Consider caching for:
- Subscription plans
- Course catalog
- Exam lists
- Researcher search results

### Webhooks

Consider implementing webhooks for:
- Payment confirmations
- Subscription renewals
- Exam completions
- Certificate generation

---

## Contact & Support

For questions or clarifications regarding this API specification, please contact the frontend development team.

**Last Updated**: 2024-12-19  
**Document Maintainer**: Frontend Team

