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

# Submit

This endpoint allows a student to upload their completed PDF answer sheet for a quiz. You must submit the file within the allowed quiz duration — the server calculates the deadline from the `start_at` timestamp and the `duration` value you provide.

## Endpoint

```text theme={null}
POST /api/v3/quiz/submit-pdf
```

## Required Role

**Authenticated student** — you must authenticate with a student-scoped Bearer token and be enrolled in the course.

## Required Headers

| Header          | Value                    |
| --------------- | ------------------------ |
| `Authorization` | `Bearer <student-token>` |
| `Accept`        | `application/json`       |
| `Content-Type`  | `multipart/form-data`    |

## Request Parameters

<ParamField body="file" type="file/PDF" required>
  The student's completed answer sheet as a PDF file. The server rejects any file that is not a valid PDF.
</ParamField>

<ParamField body="course_id" type="integer" required>
  The ID of the course this quiz belongs to.
</ParamField>

<ParamField body="quiz_id" type="integer" required>
  The ID of the quiz the student is submitting answers for.
</ParamField>

<ParamField body="class_id" type="integer">
  The ID of the class, if this course is divided into classes. Omit if not applicable.
</ParamField>

<ParamField body="duration" type="numeric" required>
  The maximum allowed duration for this quiz, in minutes. The server uses this value together with `start_at` to verify the submission is on time.
</ParamField>

<ParamField body="start_at" type="datetime" required>
  The timestamp recording when the student began the quiz (e.g. `2026-06-30T09:00:00`). Combined with `duration`, this defines the submission deadline.
</ParamField>

## Example Request

```bash theme={null}
curl -X POST https://app.example.com/api/v3/quiz/submit-pdf \
  -H "Authorization: Bearer your-student-token" \
  -H "Accept: application/json" \
  -F "file=@/path/to/answers.pdf" \
  -F "course_id=5" \
  -F "quiz_id=1" \
  -F "duration=60" \
  -F "start_at=2026-06-30T09:00:00"
```

## Response

### 200 OK

```json theme={null}
{
  "status": true,
  "message": "Submitted successfully"
}
```

## Error Responses

| Status | Message                        | Cause                                                            |
| ------ | ------------------------------ | ---------------------------------------------------------------- |
| `422`  | Invalid Data                   | The uploaded file is not a PDF, or a required field is missing.  |
| `404`  | Not Found / Course Not Found   | The specified `quiz_id` or `course_id` does not exist.           |
| `403`  | Quiz duration expired          | The submission arrived after the allowed duration window closed. |
| `403`  | Pay first to access the course | The student is not enrolled in or has not paid for the course.   |

### 422 Validation Error Example

```json theme={null}
{
  "message": "Invalid Data",
  "errors": {
    "file": ["The file must be a file of type: pdf."]
  }
}
```

<Warning>
  The server verifies that your submission arrives within the allowed time window. It adds `duration` minutes to the `start_at` timestamp to calculate the deadline — if that deadline has passed at the moment the request is received, the submission is rejected with a `403 Quiz duration expired` error. Ensure the `start_at` value you send accurately reflects when the student opened the quiz.
</Warning>
