# Resume Parser - CV to JSON (`hirelayer/resume-parser`) Actor

Parse resumes and CVs (PDF, Word, images, 13 formats) into structured JSON: contact details, work experience, education, languages, normalized skills and the candidate photo. Bulk-friendly, pay per parsed resume.

- **URL**: https://apify.com/hirelayer/resume-parser.md
- **Developed by:** [HireLayer](https://apify.com/hirelayer) (community)
- **Stats:** 2 total users, 1 monthly users, 95.2% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $80.00 / 1,000 parsed resumes

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### What does Resume Parser do?

**Resume Parser** turns resumes and CVs into clean, structured JSON. Paste resume URLs and get back, for each candidate:

- **Contact details**: full name, email, phone number (E.164), LinkedIn, GitHub and other URLs
- **Work experience**: company, job title, description, contract type, dates, location and duration
- **Education**: degree, school, level (EQF), dates and location
- **Languages** with CEFR-based levels
- **Skills**, mapped to a taxonomy of 11,000+ skills with stable IDs
- **Candidate photo**: the face is detected and cropped from the resume (`face_url`)
- **Location** with geocoded coordinates, mobility, availability, driving licences
- The **full text** of the resume, OCR included, ready for search or for AI matching

It reads **13 formats**: PDF, DOC, DOCX, ODT, PPT, PPTX, ODP, XLS, RTF, TXT, JPG, PNG and BMP, including two-column layouts, infographic resumes and scanned documents. Resumes in English, French and other languages are supported.

Resume Parser is powered by the [HireLayer](https://hirelayer.co) resume parsing API, built for ATS, job boards and recruiting teams. Processing runs in the EU.

### Why use it?

- **Bulk processing**: parse hundreds of resumes in one run and export the results to JSON, CSV or Excel.
- **Fill your ATS or CRM automatically**: connect it to Make, Zapier, n8n or your own code with the Apify API.
- **Screen faster**: feed the parsed text to the [AI Candidate Matcher](https://apify.com/hirelayer/candidate-matcher) or the [AI Candidate Ranker](https://apify.com/hirelayer/candidate-ranker).
- **Pay only for results**: a resume that cannot be read is not charged.

### How to use it

1. Click **Try for free**.
2. Paste public resume URLs, one per line (direct download links from your ATS, S3, Google Drive or Dropbox work).
3. Click **Start**. Each resume takes about 35 seconds; several are processed in parallel.
4. Open the **Candidates** table or export the dataset.

### Input

| Field | Description |
| --- | --- |
| `resumeUrls` | Public URLs of resume files, under 4.5 MB each. |
| `storeFiles` | Off by default: nothing is kept after parsing and the photo link expires after 10 minutes. Turn it on to keep hosted links to the file and photo (`info_resume.url`, `info_resume.face_url`). |
| `maxConcurrency` | Resumes processed at the same time (default 3, up to 10). |

```json
{
  "resumeUrls": ["https://hirelayer.co/benchmark/resume-parser-2026-10/cv2-two-page-en.pdf"]
}
```

### Output

One dataset item per resume. Extract of a result:

```json
{
  "input_url": "https://hirelayer.co/benchmark/resume-parser-2026-10/cv2-two-page-en.pdf",
  "status": "success",
  "info_candidate": {
    "full_name": "DANIEL OKAFOR",
    "email": "daniel.okafor@example.com",
    "job_title": "Senior Backend Engineer",
    "experience_level": "More than 10 years",
    "location": { "city": "London", "country": "United Kingdom", "country_code": "GB" }
  },
  "info_resume": { "language": "EN", "face_url": null, "text": "DANIEL OKAFOR\nSenior Backend Engineer\nLondon…" },
  "work_experiences": [
    {
      "company_name": "Deliveroo",
      "job_title": "Senior Backend Engineer",
      "start_date": "2022-01-01",
      "end_date": null,
      "currently_active": true
    }
  ],
  "educations": [{ "degree_title": "MSc Advanced Computer Science", "school_name": "The University of Manchester" }],
  "languages": [{ "language": "English", "level": "Native or Bilingual (C2)" }],
  "skills": [{ "skill_title": "Python", "skill_type": "Software skill", "status": "normalized" }],
  "warnings": []
}
```

`warnings` lists the steps that were skipped for this resume (OCR, photo, geocoding, occupation codes) or flags a document that may not be a resume.

A resume that cannot be processed (unreachable URL, unsupported or empty file) gives an item with `"status": "error"` and an `error` message, and is not charged. The complete field list is in the [HireLayer Resume Parser documentation](https://hirelayer.co/api-docs/parse-resume).

### Pricing

You pay per successfully parsed resume (**$0.08 per resume**), plus nothing else. Set a maximum cost per run in the run options: the Actor stops before going over it.

### Use it from code

```bash
curl -X POST "https://api.apify.com/v2/acts/hirelayer~resume-parser/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"resumeUrls": ["https://example.com/resume.pdf"]}'
```

The Actor is also available to AI agents through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp).

### FAQ

**Is my data stored?** By default nothing is kept after parsing: not the file, not its text, not the result. Only the candidate photo stays reachable for 10 minutes behind `face_url`. Results stay in your Apify dataset, which you control. You are responsible for having a lawful basis to process candidate data.

**Can I call the API directly?** Yes. For high volumes or an ATS integration, [HireLayer](https://hirelayer.co) offers the same parser as a REST API with monthly plans.

**Need help or a feature?** Open an issue in the **Issues** tab or write to contact@hirelayer.co.

# Actor input Schema

## `resumeUrls` (type: `array`):

Public URLs of resume files, one per line: PDF, DOC, DOCX, ODT, PPT, PPTX, ODP, XLS, RTF, TXT, JPG, PNG or BMP, under 4.5 MB each. Links from Google Drive, Dropbox or S3 work when they download the file directly.

## `storeFiles` (type: `boolean`):

Off (default): the resume file is not kept after parsing, and the candidate photo link (info_resume.face_url) expires after 10 minutes. On: the file and photo stay available at their URLs (info_resume.url, info_resume.face_url); anyone with these links can open them.

## `maxConcurrency` (type: `integer`):

How many items are processed at the same time.

## Actor input object example

```json
{
  "resumeUrls": [
    "https://hirelayer.co/benchmark/resume-parser-2026-10/cv2-two-page-en.pdf",
    "https://hirelayer.co/benchmark/resume-parser-2026-10/cv5-infographic-en.pdf"
  ],
  "storeFiles": false,
  "maxConcurrency": 3
}
```

# Actor output Schema

## `results` (type: `string`):

One item per resume: candidate profile, experience, education, languages, skills, or an error.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "resumeUrls": [
        "https://hirelayer.co/benchmark/resume-parser-2026-10/cv2-two-page-en.pdf",
        "https://hirelayer.co/benchmark/resume-parser-2026-10/cv5-infographic-en.pdf"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("hirelayer/resume-parser").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "resumeUrls": [
        "https://hirelayer.co/benchmark/resume-parser-2026-10/cv2-two-page-en.pdf",
        "https://hirelayer.co/benchmark/resume-parser-2026-10/cv5-infographic-en.pdf",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("hirelayer/resume-parser").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "resumeUrls": [
    "https://hirelayer.co/benchmark/resume-parser-2026-10/cv2-two-page-en.pdf",
    "https://hirelayer.co/benchmark/resume-parser-2026-10/cv5-infographic-en.pdf"
  ]
}' |
apify call hirelayer/resume-parser --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,hirelayer/resume-parser"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/AJdYtu2i5Nin4EpCA/builds/dMRlXw8DtvEN1S9MF/openapi.json
