# Resume Parse

Resume Parse is a dedicated API for resumes. It uses the same deterministic Parse PDF pipeline behind the scenes, applies resume-optimized fixed settings, and returns structured `result.resume` data for ATS, HR tech, recruiting, and talent operations.

Source: https://docs.docushell.com/resume-parse
Category: Reference
Read time: 7 min

## Related

- [Try Resume Playground](/playgrounds/resume): Open the ATS-focused playground with a sample resume and live API execution.
- [General Parse PDF](/parse-pdf.md): Use this when you need general document artifacts and parser controls instead of resume fields.
- [Getting started](/getting-started.md): Review auth, idempotency, status polling, and downloads.

## Summary

| Label | Value | Description |
| --- | --- | --- |
| Endpoint | /v1/resume/parse | Multipart upload route for ATS-ready resume extraction. |
| Credits | 1,000 | Lower-cost deterministic resume extraction for ATS and recruiting workflows. |
| AI / LLM | None | Parser output plus deterministic DocuShell mapping only. |

## Parse PDF Versus Resume Parse

Use Parse PDF when you want general-purpose document extraction, parser tuning controls, and artifact-first output for reports, invoices, papers, forms, or mixed business PDFs.

Use Resume Parse when the input is a resume and your application needs ATS-friendly fields such as candidate identity, contact channels, normalized skills, normalized experience, normalized education, projects, keywords, date ranges, confidence scores, and warnings.

Resume Parse is not an AI layer. It runs the deterministic Parse pipeline, fixes the parser settings that work best for resumes, then maps the extracted text into a resume-specific response shape.

- Parse PDF response focus: `result.document` and downloadable artifacts.
- Resume Parse response focus: `result.resume` plus `result.raw.document` for QA.
- Parse PDF exposes parser knobs; Resume Parse keeps them fixed to protect section detection quality.

## ATS Fields

These are the structured fields developers and businesses should integrate first.

| Field | Shape | Use |
| --- | --- | --- |
| candidate | name, headline, location | Candidate profile cards, CRM records, and dedupe flows. |
| contact | emails[], phones[], links[] | Recruiter outreach, enrichment, and candidate matching. |
| skills | string[] | Normalized skill indexing, filtering, and job matching. |
| experience | objects[] | Work history import with title, company, dates, current flag, description, and bullets. |
| education | objects[] | Education import with institution, degree, dates, graduation date, location, and description. |
| sections | summary, skills, experience, education, projects, and more | ATS import, review UI, search indexing, and compliance exports. |
| ats.keyword_text | normalized string | Keyword search, matching, and analytics pipelines. |
| ats.section_coverage | string[] | Quality checks for missing resume sections. |
| ats.date_ranges | string[] | Timeline extraction and review hints. |
| ats.confidence | name/contact/sections/overall | Best-effort confidence display and routing decisions. |
| ats.warnings | string[] | Missing-field and extraction-quality warnings. |

## Deterministic Settings

Resume Parse hardcodes the parser settings that the resume profile expects. Callers cannot toggle sanitization, reading order, table method, structure-tree usage, output mode, or line-break preservation on this route.

This keeps ATS output predictable. For example, `sanitize=false` preserves emails and phone numbers, `keep_line_breaks=true` improves heading and section detection, and `formats` always includes JSON, Markdown, and text even when callers request only an extra debug artifact.

> If you need full parser control, use `/v1/parse` instead of `/v1/resume/parse`.

## Endpoint Reference

- Method: `POST`
- Path: `/v1/resume/parse`
- Auth: Bearer token required on submit, status, and artifact download requests.
- Idempotency: Server-minted `job_id` values with optional `Idempotency-Key` replay support.
- Content type: `multipart/form-data`

Submit a resume PDF for queued deterministic parsing and receive ATS-focused structured candidate data under `result.resume`.

### Headers

| Name | Type | Required | Location | Description |
| --- | --- | --- | --- | --- |
| Authorization | Bearer <API_KEY> | Yes | header | User-owned API key created in the DocuShell dashboard. |
| Idempotency-Key | string | No | header | Recommended for safely retrying submit requests without creating duplicate jobs. |

### Request Fields

| Name | Type | Required | Location | Description |
| --- | --- | --- | --- | --- |
| file | file | Yes | multipart | Resume PDF upload. The gateway validates PDF magic bytes before forwarding the file. |
| file_name | string | No | multipart | Optional file name override used for storage metadata and downstream artifact names. |
| page_range | string | No | multipart | Optional comma-separated pages or ranges such as `1-2`. Resume Parse accepts at most 5 selected pages; use this when a resume PDF contains extra cover pages or attachments. |
| formats | `json` \| `markdown` \| `html` \| `text` \| `annotated_pdf` | No | multipart | Optional extra artifact list. Resume Parse always includes `json`, `markdown`, and `text` internally; requested extras such as `annotated_pdf` are unioned in. |

### Request Notes

- Resume Parse uses the same parse-pdf backend queue and worker as `/v1/parse`, but the public contract is distinct and returns `service: "resume-parse"`.
- Parser tuning is intentionally fixed for ATS extraction: `include_header_footer=false`, `use_struct_tree=true`, `sanitize=false`, `reading_order=xycut`, `table_method=cluster`, `keep_line_breaks=true`, and `output_mode=all`.
- Resume Parse accepts up to 5 pages per resume. For longer documents, submit a page range of 5 pages or fewer, or use `/v1/parse` for general PDF extraction.
- The mapper is deterministic only: parser output plus DocuShell regex, heading detection, date-range extraction, and section heuristics. No AI or LLM is used.
- Resume Parse costs 15 credits per queued job.
- Scanned or image-only resumes currently return `ocr_required` until OCR is enabled.

### Sample Requests

#### Multipart submit

```bash
curl -X POST "https://api.docushell.com/api/v1/resume/parse" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: resume-demo-001" \
  -F "file=@./sample-smart-and-secure-resume.pdf;type=application/pdf" \
  -F "file_name=sample-smart-and-secure-resume.pdf"
```

#### Request annotated debug output too

```bash
curl -X POST "https://api.docushell.com/api/v1/resume/parse" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: resume-debug-001" \
  -F "file=@./resume.pdf;type=application/pdf" \
  -F "formats=annotated_pdf"
```

The API still forces JSON, Markdown, and text for resume extraction, then adds requested extras.

### Queued Response

#### Queued response

```json
{
  "job_id": "job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT",
  "status": "queued",
  "cost": 1000,
  "service": "resume-parse",
  "request_id": "req_01JX8Y62XCDNZ2BM7TBM2M9Q8E",
  "links": {
    "status": "/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT"
  }
}
```

### Status Response

#### Resume parse status

```json
{
  "job_id": "job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT",
  "status": "done",
  "service": "resume-parse",
  "request_id": "req_01JX8Y62XCDNZ2BM7TBM2M9Q8E",
      "result": {
    "resume": {
      "candidate": {
        "name": "RAM KUMAR",
        "headline": "XXPosition/TitleXX",
        "location": "xCityx, xStatex"
      },
      "contact": {
        "emails": ["xxx@xxx.com"],
        "phones": ["00.00000000"],
        "links": []
      },
      "skills": [
        "Process Improvement",
        "Operations Management",
        "Project Management",
        "Strategic Planning"
      ],
      "experience": [
        {
          "title": "xxTitlexx",
          "company": "xxCompanyNamexx",
          "location": "xCityx, xStatex",
          "start_date": "April 2014",
          "end_date": "Current",
          "current": true,
          "date_range": "April 2014 - Current",
          "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
          "bullets": ["Lorem ipsum dolor sit amet, consectetur adipiscing elit."]
        },
        {
          "title": "xxTitlexx",
          "company": "xxCompanyNamexx",
          "location": null,
          "start_date": "October 2011",
          "end_date": "March 2014",
          "current": false,
          "date_range": "October 2011 - March 2014",
          "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
          "bullets": ["Lorem ipsum dolor sit amet, consectetur adipiscing elit."]
        }
      ],
      "education": [
        {
          "institution": "Symbiosis Institute of Management Studies",
          "degree": "Masters, Business Administration",
          "field": null,
          "start_date": null,
          "end_date": null,
          "graduation_date": "July 2010",
          "location": "West Pune, Maharashtra",
          "description": "Masters, Business Administration..."
        }
      ],
      "sections": {
        "summary": "Multi-page resume profile with business and operations experience...",
        "skills": "Process Improvement, Operations Management, Project Management, Strategic Planning",
        "experience": "WORK EXPERIENCE April 2014 - Current...",
        "education": "Masters, Business Administration...",
        "projects": "PROJECTS Project Name...",
        "certifications": "CERTIFICATIONS Certification Name...",
        "awards": null,
        "publications": null,
        "languages": "LANGUAGES Language...",
        "volunteering": null,
        "other": "REFERENCES Available on request."
      },
      "ats": {
        "keyword_text": "process improvement operations management project management strategic planning",
        "section_coverage": ["skills", "experience", "education", "projects", "certifications", "languages", "other"],
        "date_ranges": ["April 2014 - Current", "October 2011 - March 2014"],
        "confidence": {
          "name": 0.8,
          "contact": 1,
          "sections": 1,
          "overall": 0.93
        },
        "warnings": []
      }
    },
    "raw": {
      "document": {
        "fileName": "sample-smart-and-secure-resume.pdf",
        "numberOfPages": 5,
        "kids": []
      }
    },
    "artifacts": {
      "markdown_download": "/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT/download?format=markdown",
      "json_download": "/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT/download?format=json",
      "text_download": "/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT/download?format=text"
    },
    "metadata": {
      "engine": "docushell_parse",
      "output_mode": "all",
      "formats": ["json", "markdown", "text"],
      "use_struct_tree": true,
      "sanitize": false,
      "reading_order": "xycut",
      "table_method": "cluster",
      "keep_line_breaks": true
    }
  },
  "links": {
    "status": "/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT",
    "download": "/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT/download"
  }
}
```

Resume Parse returns structured ATS fields under `result.resume` while still exposing the raw Parse document and companion artifacts for QA.

### Download Samples

#### JSON artifact download

```bash
curl "https://api.docushell.com/api/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT/download?format=json" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Use `format=json` to stream the structured document artifact directly.

#### Resume Markdown artifact

```bash
curl "https://api.docushell.com/api/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT/download?format=markdown" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Markdown is always generated for Resume Parse so the profile mapper and your reviewers can inspect the reading-order text.

#### Resume plain text artifact

```bash
curl "https://api.docushell.com/api/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT/download?format=text" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Plain text is always generated for deterministic resume profile extraction and downstream search.

#### Annotated PDF debug artifact download

```bash
curl "https://api.docushell.com/api/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT/download?format=annotated_pdf" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  --output document.annotated.pdf
```

Annotated PDF downloads are visual debug artifacts for validating extracted structure against the source page.

### Artifacts

- `result.resume.candidate` contains name, headline, and location when detected.
- `result.resume.contact` contains deduplicated emails, phones, and classified links such as LinkedIn, GitHub, and portfolio URLs.
- `result.resume.skills` contains normalized, deduplicated skills from the skills section.
- `result.resume.experience` contains normalized experience entries with title, company, location, dates, current-job flag, description, and bullets when detected.
- `result.resume.education` contains normalized education entries with institution, degree, field, dates, graduation date, location, and description when detected.
- `result.resume.sections` is a fixed object of ATS-oriented sections such as summary, skills, experience, education, projects, certifications, awards, publications, languages, volunteering, and other.
- `result.resume.ats` includes normalized keyword text, detected section coverage, date ranges, confidence scores, and warnings for missing fields.
- `result.raw.document` exposes the underlying Parse document tree for QA and fallback extraction.
- JSON, Markdown, and text artifacts are always generated for Resume Parse; optional HTML or annotated PDF artifacts can be requested through `formats`.

### Poll And Download

- Poll `GET /v1/jobs/:jobId` until `status` becomes `done` or `failed`.
- When the job completes, read structured resume data from `result.resume`.
- Use `GET /v1/jobs/:jobId/download?format=json|markdown|text` for the underlying artifacts. Add `formats=annotated_pdf` at submit time when you need the visual debug artifact.

### Failure Notes

- `invalid_pdf`, `corrupt_pdf`, and `password_protected` mirror the Parse PDF failure behavior.
- `ocr_required` means the resume did not expose enough extractable text. Run OCR upstream before retrying.
- `invalid_page_range` is returned when the submitted selector is malformed or selects no valid pages.
- `page_limit_exceeded` is returned when the selected pages exceed the Resume Parse 5-page cap.
- `server_busy` or `backend_unavailable` indicate temporary capacity problems. Retry with the same Idempotency-Key when safe.
- Weak or missing fields do not fail the job; they appear as warnings and lower confidence values in `result.resume.ats`.

### Error Examples

#### OCR required

- Status: `400`
- Code: `ocr_required`

The uploaded resume appears to be scanned or image-only.

##### 400 error

```json
{
  "error": {
    "code": "ocr_required",
    "message": "This PDF appears to require OCR before it can be parsed.",
    "type": "invalid_request_error",
    "request_id": "req_01JX8Y62XCDNZ2BM7TBM2M9Q8E"
  }
}
```

#### Invalid PDF

- Status: `400`
- Code: `invalid_pdf`

The uploaded file failed PDF validation before it reached the parse queue.

##### 400 error

```json
{
  "error": {
    "code": "invalid_pdf",
    "message": "This file is not a valid PDF.",
    "type": "invalid_request_error",
    "request_id": "req_01JX8Y62XCDNZ2BM7TBM2M9Q8E"
  }
}
```

#### Authentication failure

- Status: `401`
- Code: `invalid_api_key`

Returned when the bearer token is missing, revoked, expired, or not allowed to use the API lane.

##### 401 error

```json
{
  "error": {
    "code": "invalid_api_key",
    "message": "Invalid API key.",
    "type": "auth_error",
    "request_id": "req_01JX8Y62XCDNZ2BM7TBM2M9Q8E"
  }
}
```

#### Idempotency conflict

- Status: `409`
- Code: `idempotency_key_reused`

Returned when the same Idempotency-Key is reused with a different payload than the original request.

##### 409 error

```json
{
  "error": {
    "code": "idempotency_key_reused",
    "message": "This Idempotency-Key was already used with a different request.",
    "type": "invalid_request_error",
    "request_id": "req_01JX8Y62XCDNZ2BM7TBM2M9Q8E"
  }
}
```

#### Webhook access disabled

- Status: `403`
- Code: `webhook_access_disabled`

Returned when a Starter API key submits webhook fields. Pro, Growth, and Scale include webhooks.

##### 403 error

```json
{
  "error": {
    "code": "webhook_access_disabled",
    "message": "Webhooks are available on Pro, Growth, and Scale. Starter includes API access without webhooks.",
    "type": "billing_error",
    "request_id": "req_01JX8Y62XCDNZ2BM7TBM2M9Q8E"
  }
}
```

#### Rate limit

- Status: `429`
- Code: `rate_limit_exceeded`

Returned when the API key or caller fingerprint exceeds the configured request rate.

##### 429 error

```json
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded.",
    "type": "rate_limit_error",
    "request_id": "req_01JX8Y62XCDNZ2BM7TBM2M9Q8E"
  }
}
```

## Artifact Downloads

Resume Parse always creates JSON, Markdown, and plain text artifacts for extraction and QA.

### JSON artifact download

```bash
curl "https://api.docushell.com/api/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT/download?format=json" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Use `format=json` to stream the structured document artifact directly.

### Resume Markdown artifact

```bash
curl "https://api.docushell.com/api/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT/download?format=markdown" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Markdown is always generated for Resume Parse so the profile mapper and your reviewers can inspect the reading-order text.

### Resume plain text artifact

```bash
curl "https://api.docushell.com/api/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT/download?format=text" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Plain text is always generated for deterministic resume profile extraction and downstream search.

## Known Limits

Resume Parse is best-effort deterministic extraction. It handles many common resume formats, but unusual visual layouts, very sparse text layers, scanned PDFs, or resumes with contact information only embedded in images can reduce confidence or return warnings.

The mapper never uses AI to infer missing facts. When it cannot find a field deterministically, it leaves the field empty and reports a warning instead of inventing candidate data.

- Resume Parse accepts up to 5 pages per resume; use Parse PDF for longer general documents.
- Scanned resumes currently return `ocr_required`.
- Highly designed resumes can produce partial sections; inspect `ats.warnings` and `ats.confidence`.
- Use the Markdown and text artifacts to debug what the parser actually extracted.
