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

# Educator Applications

> Manage educator application submissions and approvals

## Get All Applications

<api method="GET" endpoint="/api/admin/educator-applications" />

Retrieve all educator applications with optional filtering by status.

### Authentication

<ParamField header="Authorization" type="string" required>
  Bearer token with admin role required
</ParamField>

### Query Parameters

<ParamField query="status" type="string" optional>
  Filter applications by status. Available values:

  * `pending` - Applications awaiting review
  * `approved` - Approved applications
  * `rejected` - Rejected applications

  If not specified, returns all applications regardless of status
</ParamField>

### Response

<ResponseField name="success" type="boolean">
  Indicates if the request was successful
</ResponseField>

<ResponseField name="applications" type="array">
  Array of applications sorted by submission date (newest first)

  <Expandable title="Application object">
    <ResponseField name="_id" type="string">
      Application unique identifier (MongoDB ObjectId)
    </ResponseField>

    <ResponseField name="userId" type="string">
      Clerk user ID of the applicant
    </ResponseField>

    <ResponseField name="professionalTitle" type="string">
      Applicant's professional title (e.g., "Senior Software Engineer")
    </ResponseField>

    <ResponseField name="bio" type="string">
      Applicant's biography and teaching background
    </ResponseField>

    <ResponseField name="expertise" type="array">
      Array of expertise areas/topics the applicant can teach
    </ResponseField>

    <ResponseField name="linkedinUrl" type="string">
      LinkedIn profile URL (optional, can be empty string)
    </ResponseField>

    <ResponseField name="status" type="string">
      Current status of the application:

      * `pending` - Under review
      * `approved` - Approved, educator role granted
      * `rejected` - Rejected with optional reason
    </ResponseField>

    <ResponseField name="rejectionReason" type="string">
      Reason for rejection (empty if not rejected)
    </ResponseField>

    <ResponseField name="createdAt" type="string">
      ISO 8601 timestamp when the application was submitted
    </ResponseField>

    <ResponseField name="updatedAt" type="string">
      ISO 8601 timestamp when the application was last updated
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseExample>
  ```json Response theme={null}
  {
    "success": true,
    "applications": [
      {
        "_id": "65a1b2c3d4e5f6789abcdef0",
        "userId": "user_2abc123def456",
        "professionalTitle": "Senior Full-Stack Developer",
        "bio": "I have 8 years of experience in web development and have been teaching programming for the past 3 years. I'm passionate about helping others learn to code and build amazing applications.",
        "expertise": [
          "JavaScript",
          "React",
          "Node.js",
          "MongoDB",
          "Web Development"
        ],
        "linkedinUrl": "https://linkedin.com/in/johnsmith",
        "status": "pending",
        "rejectionReason": "",
        "createdAt": "2024-01-15T10:30:00.000Z",
        "updatedAt": "2024-01-15T10:30:00.000Z"
      },
      {
        "_id": "65a1b2c3d4e5f6789abcdef1",
        "userId": "user_3xyz789ghi012",
        "professionalTitle": "Data Science Consultant",
        "bio": "PhD in Computer Science with specialization in Machine Learning. I've worked with Fortune 500 companies on AI solutions and love making complex topics accessible.",
        "expertise": [
          "Python",
          "Machine Learning",
          "Data Science",
          "TensorFlow",
          "Statistics"
        ],
        "linkedinUrl": "https://linkedin.com/in/sarahjohnson",
        "status": "approved",
        "rejectionReason": "",
        "createdAt": "2024-01-14T14:20:00.000Z",
        "updatedAt": "2024-01-14T16:45:00.000Z"
      },
      {
        "_id": "65a1b2c3d4e5f6789abcdef2",
        "userId": "user_4mno345pqr678",
        "professionalTitle": "Freelance Developer",
        "bio": "I build websites.",
        "expertise": [
          "HTML",
          "CSS"
        ],
        "linkedinUrl": "",
        "status": "rejected",
        "rejectionReason": "Application does not demonstrate sufficient teaching experience or depth of expertise. Please provide more details about your background and expand your expertise areas.",
        "createdAt": "2024-01-13T09:15:00.000Z",
        "updatedAt": "2024-01-13T11:30:00.000Z"
      }
    ]
  }
  ```
</ResponseExample>

***

## Approve Application

<api method="PATCH" endpoint="/api/admin/educator-applications/:id/approve" />

Approve an educator application and grant the user educator role in Clerk.

### Authentication

<ParamField header="Authorization" type="string" required>
  Bearer token with admin role required
</ParamField>

### Path Parameters

<ParamField path="id" type="string" required>
  Application ID (MongoDB ObjectId)
</ParamField>

### Response

<ResponseField name="success" type="boolean">
  Indicates if the approval was successful
</ResponseField>

<ResponseField name="message" type="string">
  Confirmation message
</ResponseField>

<ResponseExample>
  ```json Success Response theme={null}
  {
    "success": true,
    "message": "Application approved. Educator role granted."
  }
  ```

  ```json Error Response theme={null}
  {
    "success": false,
    "message": "Application not found."
  }
  ```
</ResponseExample>

### Side Effects

1. Updates application status to `approved`
2. Clears any existing `rejectionReason`
3. Updates user's Clerk public metadata with `role: 'educator'`
4. User can now create and publish courses

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH "https://api.skillrise.com/api/admin/educator-applications/65a1b2c3d4e5f6789abcdef0/approve" \
    -H "Authorization: Bearer YOUR_ADMIN_TOKEN"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://api.skillrise.com/api/admin/educator-applications/65a1b2c3d4e5f6789abcdef0/approve',
    {
      method: 'PATCH',
      headers: {
        'Authorization': 'Bearer YOUR_ADMIN_TOKEN'
      }
    }
  );

  const data = await response.json();
  ```
</CodeGroup>

***

## Reject Application

<api method="PATCH" endpoint="/api/admin/educator-applications/:id/reject" />

Reject an educator application with an optional reason.

### Authentication

<ParamField header="Authorization" type="string" required>
  Bearer token with admin role required
</ParamField>

### Path Parameters

<ParamField path="id" type="string" required>
  Application ID (MongoDB ObjectId)
</ParamField>

### Request Body

<ParamField body="reason" type="string" optional>
  Reason for rejection (will be visible to the applicant)
</ParamField>

### Response

<ResponseField name="success" type="boolean">
  Indicates if the rejection was successful
</ResponseField>

<ResponseField name="message" type="string">
  Confirmation message
</ResponseField>

<ResponseExample>
  ```json Success Response theme={null}
  {
    "success": true,
    "message": "Application rejected."
  }
  ```

  ```json Error Response theme={null}
  {
    "success": false,
    "message": "Application not found."
  }
  ```
</ResponseExample>

### Side Effects

1. Updates application status to `rejected`
2. Stores the rejection reason (if provided)
3. User can resubmit a new application later
4. Previous rejection reason will be cleared upon resubmission

### Example Requests

<CodeGroup>
  ```bash With Reason theme={null}
  curl -X PATCH "https://api.skillrise.com/api/admin/educator-applications/65a1b2c3d4e5f6789abcdef0/reject" \
    -H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "reason": "Application does not demonstrate sufficient teaching experience. Please provide more details about your background and reapply."
    }'
  ```

  ```bash Without Reason theme={null}
  curl -X PATCH "https://api.skillrise.com/api/admin/educator-applications/65a1b2c3d4e5f6789abcdef0/reject" \
    -H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{}'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://api.skillrise.com/api/admin/educator-applications/65a1b2c3d4e5f6789abcdef0/reject',
    {
      method: 'PATCH',
      headers: {
        'Authorization': 'Bearer YOUR_ADMIN_TOKEN',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        reason: 'Insufficient teaching experience demonstrated.'
      })
    }
  );

  const data = await response.json();
  ```
</CodeGroup>

### Notes

* Applications can only be approved or rejected once they are in `pending` status
* Rejected users can resubmit applications, which will overwrite their previous submission
* Approving an application automatically grants the `educator` role in Clerk
* The `reason` field is optional but recommended to provide feedback to applicants
* All admin endpoints require the `protectAdmin` middleware authentication
