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

# Confirm and Save Parsed CV

> Confirm and save the parsed CV data to your profile

## Endpoint

```
POST /api/v1/cv-parse/confirm
```

**Base URL**: `http://localhost:3000/api/v1`

<Note>This endpoint requires **authentication** and **Job Seeker role**.</Note>

## Authentication

Include the access token in the Authorization header:

```bash theme={null}
Authorization: Bearer YOUR_ACCESS_TOKEN
```

## Description

Review the parsed CV data and confirm to save it to your profile. This creates or updates your JobSeekerProfile, Education, WorkExperience, and JobSeekerSkill records.

The backend uses the stored parsed CV as the base version, then applies any fields you send in `data` before saving.

<Warning>
  Arrays are full replacements. If you send `education` or `workExperience`, the full array is
  deleted and recreated.

  To add or update one item, first get the current array from preview, then send the complete array
  with your change.

  For partial updates after confirmation, use the dedicated Education, Work Experience, etc... APIs.
</Warning>

## Request Body

<ParamField body="parseResultId" type="string" required>
  The parse result identifier returned by `POST /cv/confirm` or `GET /cv-parse/preview`.
</ParamField>

<ParamField body="data" type="object" required>
  CV data with optional overrides. All fields are optional except `workPreference` and
  `availabilityStatus`.
</ParamField>

<ParamField body="data.firstName" type="string" optional>
  First name override.
</ParamField>

<ParamField body="data.lastName" type="string" optional>
  Last name override.
</ParamField>

<ParamField body="data.cvEmail" type="string" optional>
  Email address override.
</ParamField>

<ParamField body="data.phone" type="string" optional>
  Phone number override.
</ParamField>

<ParamField body="data.location" type="string" optional>
  Location/address override.
</ParamField>

<ParamField body="data.linkedinUrl" type="string" optional>
  LinkedIn profile URL override.
</ParamField>

<ParamField body="data.githubUrl" type="string" optional>
  GitHub profile URL override.
</ParamField>

<ParamField body="data.portfolioUrl" type="string" optional>
  Portfolio website URL override.
</ParamField>

<ParamField body="data.title" type="string" optional>
  Job title override (e.g., "Software Engineer").
</ParamField>

<ParamField body="data.summary" type="string" optional>
  Professional summary override.
</ParamField>

<ParamField body="data.education" type="array" optional>
  Education array override. If sent, it replaces the stored education.
</ParamField>

<ParamField body="data.education[].institutionName" type="string" required>
  Institution name.
</ParamField>

<ParamField body="data.education[].degreeType" type="string" required>
  Degree type: ASSOCIATE, BACHELOR, MASTER, DOCTORATE.
</ParamField>

<ParamField body="data.education[].fieldOfStudy" type="string" required>
  Field of study.
</ParamField>

<ParamField body="data.education[].startDate" type="string" required>
  Start date (ISO 8601).
</ParamField>

<ParamField body="data.education[].endDate" type="string" optional>
  End date (ISO 8601).
</ParamField>

<ParamField body="data.education[].isCurrent" type="boolean" required>
  Currently studying here.
</ParamField>

<ParamField body="data.education[].gpa" type="number" optional>
  GPA score.
</ParamField>

<ParamField body="data.workExperience" type="array" optional>
  Work experience array override. If sent, it replaces the stored work experience.
</ParamField>

<ParamField body="data.workExperience[].companyName" type="string" required>
  Company name.
</ParamField>

<ParamField body="data.workExperience[].jobTitle" type="string" required>
  Job title.
</ParamField>

<ParamField body="data.workExperience[].location" type="string" optional>
  Job location.
</ParamField>

<ParamField body="data.workExperience[].startDate" type="string" required>
  Start date (ISO 8601).
</ParamField>

<ParamField body="data.workExperience[].endDate" type="string" optional>
  End date (ISO 8601).
</ParamField>

<ParamField body="data.workExperience[].isCurrent" type="boolean" required>
  Currently working here.
</ParamField>

<ParamField body="data.workExperience[].description" type="string" required>
  Job description.
</ParamField>

<ParamField body="data.skills" type="array" optional>
  Skills array. Skills from the parsed CV are kept (verified). User-added skills are appended
  (unverified).
</ParamField>

<ParamField body="data.skills[]" type="string" optional>
  Skill name. If skill already exists in parsed CV, it's marked as verified. New skills are
  unverified.
</ParamField>

<ParamField body="data.expectedSalary" type="number" optional>
  Expected salary.
</ParamField>

<ParamField body="data.workPreference" type="string" required>
  Work preference: ONSITE, REMOTE, HYBRID, ANY.
</ParamField>

<ParamField body="data.noticePeriod" type="number" optional>
  Notice period in days.
</ParamField>

<ParamField body="data.availabilityStatus" type="string" required>
  Availability status: OPEN\_TO\_WORK, NOT\_LOOKING, PASSIVELY\_LOOKING.
</ParamField>

## Request Example

```json theme={null}
{
  "parseResultId": "9968ae8c-e8f4-4d36-a17a-79215cca669c",
  "data": {
    "cvEmail": "amrrdev@gmail.com",
    "phone": "+20 120 456 2326",
    "summary": "Software Engineer with 1+ year of experience building scalable APIs with Node.js and NestJS.",
    "skills": ["TypeScript", "Node.js", "NestJS", "Docker"],
    "workPreference": "REMOTE",
    "availabilityStatus": "OPEN_TO_WORK"
  }
}
```

## Response

### Success Response (200 OK)

```json theme={null}
{
  "success": true,
  "data": {
    "message": "Profile updated successfully from CV"
  },
  "message": "Success",
  "meta": {
    "timestamp": "2026-04-23T20:00:00.000Z",
    "path": "/cv-parse/confirm",
    "method": "POST"
  }
}
```

## Error Responses

### 400 Bad Request - Validation Error (missing required fields)

```json theme={null}
{
  "success": false,
  "error": {
    "message": "data must be defined, workPreference must be a valid enum value, availabilityStatus must be a valid enum value",
    "statusCode": 400,
    "timestamp": "2026-04-23T20:00:00.000Z",
    "path": "/cv-parse/confirm",
    "method": "POST",
    "details": "Bad Request"
  }
}
```

### 400 Bad Request - No Completed Parse Result

```json theme={null}
{
  "success": false,
  "error": {
    "message": "No completed parse result to confirm",
    "statusCode": 400,
    "timestamp": "2026-04-23T20:00:00.000Z",
    "path": "/cv-parse/confirm",
    "method": "POST",
    "details": "Bad Request"
  }
}
```

### 401 Unauthorized

```json theme={null}
{
  "success": false,
  "error": {
    "message": "Unauthorized",
    "statusCode": 401,
    "timestamp": "2026-04-23T20:00:00.000Z",
    "path": "/cv-parse/confirm",
    "method": "POST",
    "details": "Unauthorized"
  }
}
```

### 403 Forbidden

```json theme={null}
{
  "success": false,
  "error": {
    "message": "Forbidden resource",
    "statusCode": 403,
    "timestamp": "2026-04-23T20:00:00.000Z",
    "path": "/cv-parse/confirm",
    "method": "POST",
    "details": "Forbidden"
  }
}
```

### 404 Not Found - Parse Result Not Found

```json theme={null}
{
  "success": false,
  "error": {
    "message": "Parse result not found",
    "statusCode": 404,
    "timestamp": "2026-04-23T20:00:00.000Z",
    "path": "/cv-parse/confirm",
    "method": "POST",
    "details": "Not Found"
  }
}
```

## Complete CV Flow

<Steps>
  <Step title="Upload CV">Call POST /cv/presigned-url to get an upload URL</Step>
  <Step title="Upload File">Upload the file using PUT with the upload URL</Step>
  <Step title="Confirm Upload">Call POST /cv/confirm to trigger NLP parsing</Step>
  <Step title="Preview Data">Call GET /cv-parse/preview to see parsed results</Step>
  <Step title="Confirm & Save">Call POST /cv-parse/confirm to save to your profile</Step>
</Steps>

<Info>
  What gets saved:
  JobSeekerProfile (title, summary, phone, cvEmail, location, links, preferences), Education,
  WorkExperience, and JobSeekerSkill.

  Skills from parsed CV are saved with `verified: true`; manually added skills are saved with
  `verified: false`.

  `yearsOfExperience` is always taken from the parsed CV and cannot be modified.

  **After confirmation, the CvParseResult record is deleted from the database.** Calling
  `GET /cv-parse/preview` will return a 404 after confirmation.
</Info>
