APIs

HireLayer CV Extract

Parse a resume file into structured candidate JSON with one multipart request: contact details, experience, education, languages and typed skills.

Endpoint
POST /api/v3/parser
Input
multipart/form-data · 13 file formats · about 4.5 MB max
Output
Synchronous JSON, usually in about 35 s (145 s max)
Billing
1 credit per successful parse
POST/api/v3/parser

Upload one resume file and receive the structured candidate profile in the same response.

Authentication
X-API-Key header
Billing
1 credit per successful parse (HTTP 200)
Client timeout
Client timeout ≥ 150 s

Request body

Content type multipart/form-data

  • filefilerequired

    The resume: PDF, DOC, DOCX, ODT, PPT, PPTX, ODP, XLS, RTF, TXT, JPG/JPEG, PNG or BMP. The type is detected from the content. Keep it under 4.5 MB.

  • application_idstring

    Your own reference, echoed in info_resume.application_id.

  • webhook_urlstring (URL)

    HTTP(S) URL that also receives the result. The response stays synchronous. See Webhook.

  • do_not_store_datastring

    true: the resume file is not stored. info_resume.url is then null, and the cropped photo is only reachable through a temporary link valid 10 minutes. Case-insensitive. Defaults to false (file stored).

    "true""false"

Response

200Parsed resume.

  • statusstring

    Always success on HTTP 200.

    "success"
  • upstream_statusstringmay be absent

    Present when an optional step was skipped (see warnings). The data is still usable.

    "partial"
  • request_idstring

    Unique request ID. Quote it when contacting support.

  • warningsstring[]

    Human-readable notes about skipped steps (OCR, photo, geocoding, occupation codes). Informational: do not parse.

  • errorsstring[]

    Always empty on HTTP 200. Failures use non-2xx statuses.

  • info_resumeResumeInfo

    The document.

    ›Show 7 child fields
    • application_idstring | null

      Your application_id, or null when not sent.

    • date_parsingstring

      Parsing time in UTC, YYYY-MM-DDTHH:mm:ss, without a zone suffix.

    • languagestring | null

      Main language of the resume, uppercase ISO 639-1 code such as EN or FR.

    • urlstring | null

      URL of the stored original file. Anyone with the link can open it. null with do_not_store_data=true, because the file is not stored.

    • face_urlstring | null

      Candidate photo cropped from the resume. null when no face is found and for .txt files.

    • face_url_expires_atstring | null

      With do_not_store_data=true: expiry of the temporary face_url, 10 minutes after parsing, UTC YYYY-MM-DDTHH:mm:ss. Otherwise null and face_url does not expire.

    • textstring

      Full extracted text, including OCR. May end with [EXTRACTED_HYPERLINKS] and [PDF_ANNOTATION_TEXTS] sections.

  • info_candidateCandidate

    The candidate profile.

    ›Show 19 child fields
    • full_namestring | null

      First and last name.

    • last_namestring | null

      Last name.

    • first_namestring | null

      First name.

    • emailstring | null

      Lower-cased email address.

    • phone_numberstring | null

      E.164 phone number, e.g. +33612345678. The country is inferred from the resume, France by default.

    • birth_datestring | null

      Date of birth, YYYY-MM-DD. A year alone becomes YYYY-01-01.

    • agenumber | null

      Age in years, as stated or inferred.

    • availability_nowboolean | null

      Whether the candidate is available now.

    • availability_datestring | null

      Date from which the candidate is available, YYYY-MM-DD.

    • driver_licensestring[]

      Driving licences as written, e.g. Permis B.

    • job_titlestring | null

      Target or current job title. Falls back to the most recent position.

    • education_namestring | null

      Highest qualification relevant to the job title.

    • education_levelstring | null

      Highest European Qualifications Framework (EQF) level.

      "Level 1""Level 2""Level 3""Level 4""Level 5""Level 6""Level 7""Level 8""Other"
    • experience_levelstring | null

      Total professional experience bracket.

      "0 to 1 year""1 to 3 years""3 to 5 years""5 to 10 years""More than 10 years"
    • linkedin_urlstring | null

      LinkedIn profile URL.

    • github_urlstring | null

      GitHub profile URL.

    • other_urlsstring[]

      Other URLs in the resume (portfolio, website…).

    • locationLocation

      Where the candidate lives.

      ›Show 9 child fields
      • countrystring | null

        Country name.

      • country_codestring | null

        ISO 3166-1 alpha-2 country code, e.g. FR.

      • regionstring | null

        Region.

      • departmentstring | null

        Department or county.

      • citystring | null

        City.

      • postal_codestring | null

        Postal code.

      • full_addressstring | null

        Address as a single line.

      • latitudenumber | null

        Latitude from geocoding.

      • longitudenumber | null

        Longitude from geocoding.

    • mobilityMobility

      Where else the candidate can work.

      ›Show 2 child fields
      • can_work_in_other_citiesboolean | null

        Whether the resume says the candidate can work elsewhere. null when not mentioned.

      • other_citiesMobilityCity[]

        Cities explicitly named as possible work locations.

        ›Show 5 child fields
        • citystring | null

          City named in the resume.

        • countrystring | null

          Country, when stated or reliably inferred.

        • postal_codestring | null

          Postal code, when present in the resume.

        • latitudenumber | null

          Latitude from geocoding.

        • longitudenumber | null

          Longitude from geocoding.

  • work_experiencesWorkExperience[]
    ›Show 12 child fields
    • company_namestring | null

      Employer name.

    • job_titlestring | null

      Job title for this position.

    • descriptionstring | null

      Tasks, responsibilities and achievements.

    • contract_typestring | null

      Canonical contract type. Unrecognized values become Other.

      "Permanent contract""Fixed-term contract""Temporary assignment""Internship""Apprenticeship""Freelance""Volunteering""Other"
    • start_datestring | null

      Start date, YYYY-MM-DD. A year alone becomes YYYY-01-01; a month alone, its first day.

    • end_datestring | null

      End date, YYYY-MM-DD. null for an ongoing role. A year alone becomes YYYY-12-31; a month alone, its last day.

    • currently_activeboolean | null

      Whether this is a current position.

    • work_experience_countrystring | null

      Country of the position.

    • work_experience_country_codestring | null

      ISO 3166-1 alpha-2 country code.

    • work_experience_citystring | null

      City of the position.

    • work_experience_postal_codestring | null

      Postal code of the position.

    • experience_durationnumber | null

      Duration of this position in months, as extracted.

  • educationsEducation[]
    ›Show 8 child fields
    • degree_titlestring | null

      Name of the degree or programme.

    • school_namestring | null

      School or institution.

    • descriptionstring | null

      Details of the programme.

    • degree_typestring | null

      EQF level of the degree, expected to be one of Level 1…Level 8 or Other. Not normalized: treat other strings as Other.

    • start_datestring | null

      Start date, YYYY-MM-DD.

    • end_datestring | null

      End date, YYYY-MM-DD.

    • currently_activeboolean | null

      Whether the programme is in progress.

    • locationEducationLocation

      Location of the school.

      ›Show 7 child fields
      • countrystring | null

        Country name.

      • country_codestring | null

        ISO 3166-1 alpha-2 country code, e.g. FR.

      • regionstring | null

        Region.

      • departmentstring | null

        Department or county.

      • citystring | null

        City.

      • postal_codestring | null

        Postal code.

      • full_addressstring | null

        Address as a single line.

  • rome_jobsRomeJob[]

    Occupations predicted from info_candidate.job_title with the French ROME taxonomy.

    ›Show 5 child fields
    • job_titlestring

      Occupation label, in French.

    • job_codestring

      Occupation (appellation) code.

    • rome_titlestring

      ROME job family label, in French.

    • rome_codestring

      ROME code, e.g. M1805.

    • prediction_scorenumber

      Confidence between 0.7 and 1.

  • languagesLanguage[]
    ›Show 2 child fields
    • languagestring

      Language name as written in the resume.

    • levelstring | null

      CEFR-based proficiency, or null when not stated.

      "Native or Bilingual (C2)""Full Professional Proficiency (C1)""Professional Working Proficiency (B2)""Limited Working Proficiency (B1)""Advanced Basic Proficiency (A2)""Introductory Proficiency (A1)"
  • skillsSkill[]
    ›Show 5 child fields
    • skill_titlestring

      Catalog label when status is normalized, otherwise the text from the resume.

    • skill_typestring
      "Hard skill""Soft skill""Software skill"
    • statusstring

      normalized: matched to the HireLayer Skills catalog. raw: no close catalog match.

      "normalized""raw"
    • domainstring | null

      Catalog domain. null when status is raw.

    • subcategorystring | null

      Catalog subcategory. null when status is raw.

  • certificationsstring[]
  • interestsstring[]

Errors

  • 400
    Missing required file field

    No multipart part named file.

    Do not retry

  • 400
    application_id must be a string when provided

    application_id was sent as a file part.

    Do not retry

  • 400
    INVALID_FILEThe uploaded file is empty or invalid. Please check the file and try again.

    Empty file, unsupported format, content that does not match its type, or a do_not_store_data value other than true/false.

    Do not retry

  • 401
    Missing API Key

    The X-API-Key header is absent. Authorization: Bearer is not accepted.

    Do not retry

  • 401
    Invalid API Key

    The key is malformed, unknown or revoked. Rotating a key revokes the previous one immediately.

    Do not retry

  • 403
    Insufficient credits available

    The account has no credit left.

    Fix, then retry

  • 413
    The uploaded file is too large to process. Please upload a smaller file.

    The encoded upload exceeds 6 MiB (a file of about 4.5 MB).

    Do not retry

  • 415
    Content-Type must be multipart/form-data

    The request is not multipart/form-data.

    Do not retry

  • 422
    DOCUMENT_NOT_A_RESUMEThis document does not appear to be a CV or resume. Please upload a CV or resume and try again.

    The document is clearly not a resume (cover letter, ID, invoice…).

    Do not retry

  • 422
    DOCUMENT_TEXT_EMPTYThe text could not be extracted from this document. Please verify that the file is readable and contains selectable text.

    No text was found, even with OCR.

    Do not retry

  • 422
    DOCUMENT_UNREADABLEThe document could not be read. Please upload a valid, readable file.

    The file is corrupted or cannot be opened.

    Do not retry

  • 422
    DOCUMENT_TOO_LARGEThis document contains too much text to process. Please try a shorter or simpler version.

    More than 100,000 characters of text were extracted.

    Do not retry

  • 500
    Internal Server Error

    Unexpected failure.

    Retry with backoff

  • 502
    PARSER_UNAVAILABLEAn error occurred while processing the document or extracting its text. Please try again later.

    The parser failed or returned an invalid result.

    Retry with backoff

  • 503
    PARSER_UNAVAILABLEAn error occurred while processing the document or extracting its text. Please try again later.

    A processing step (text extraction, OCR, model) is temporarily unavailable. Header Retry-After: 1.

    Retry with backoff

  • 503
    Credit service temporarily unavailable

    Credits could not be checked or deducted. No credit is consumed, including when the operation itself had completed. Header Retry-After: 1.

    Retry with backoff

  • 504
    PARSER_UNAVAILABLEAn error occurred while processing the document or extracting its text. Please try again later.

    Parsing did not finish within 145 seconds.

    Retry with backoff

Behavior

Latency
Synchronous. Parsing usually takes about 35 seconds; scans that need OCR take longer. The gateway waits up to 145 seconds, then returns 504. Use a client timeout of at least 150 seconds.
Retries
Retry 502, 503 and 504 with exponential backoff and honour Retry-After. Never retry 4xx unchanged. Failed requests are not charged.
Idempotency
There is no idempotency key. A request your client abandons can still complete and be charged: do not use a client timeout shorter than the gateway timeout.
Partial results
When an optional step is skipped (OCR of some pages, photo, geocoding, occupation codes), the response is still 200 with upstream_status: "partial" and a note in warnings.
Documents
13 formats (PDF, DOC, DOCX, ODT, PPT, PPTX, ODP, XLS, RTF, TXT, JPG/JPEG, PNG and BMP). All pages are read; scanned documents are OCR'd on their first 4 pages. Up to 100,000 extracted characters.
Languages
Free-text values stay in the language of the resume (no translation). Enumerated fields use the fixed English values of the response schema. rome_jobs labels are in French.
Request ID
Successful responses carry request_id; error responses carry the x-parser-request-id header. Quote them when contacting support.
curl -X POST https://onlineresumeparser.com/api/v3/parser \
  -H "X-API-Key: $HIRELAYER_API_KEY" \
  -F "[email protected];type=application/pdf" \
  -F "application_id=app_123"
{
  "status": "success",
  "request_id": "6f1c2a9e-4b7d-4c3e-9a51-2f8d7e6b1c04",
  "warnings": [],
  "errors": [],
  "info_resume": {
    "application_id": "app_123",
    "date_parsing": "2026-10-01T09:30:12",
    "language": "EN",
    "url": "https://files.example.com/original/1790847012000-alex-morgan.pdf",
    "face_url": "https://files.example.com/faces/1790847012000-alex-morgan.jpg",
    "face_url_expires_at": null,
    "text": "Alex Morgan\nSenior Software Engineer\nParis, France\[email protected]\n\nSenior software engineer with 8 years of experience building web platforms…"
  },
  "info_candidate": {
    "full_name": "Alex Morgan",
    "last_name": "Morgan",
    "first_name": "Alex",
    "email": "[email protected]",
    "phone_number": "+33612345678",
    "birth_date": "1992-04-18",
    "age": 34,
    "availability_now": false,
    "availability_date": "2026-11-01",
    "driver_license": [
      "Permis B"
    ],
    "job_title": "Senior Software Engineer",
    "education_name": "Master of Science in Computer Science",
    "education_level": "Level 7",
    "experience_level": "5 to 10 years",
    "linkedin_url": "https://www.linkedin.com/in/alex-morgan",
    "github_url": "https://github.com/alexmorgan",
    "other_urls": [
      "https://alexmorgan.dev"
    ],
    "location": {
      "country": "France",
      "country_code": "FR",
      "region": "Île-de-France",
      "department": "Paris",
      "city": "Paris",
      "postal_code": "75011",
      "full_address": "75011 Paris, France",
      "latitude": 48.8589,
      "longitude": 2.3801
    },
    "mobility": {
      "can_work_in_other_cities": true,
      "other_cities": [
        {
          "city": "Lyon",
          "country": "France",
          "postal_code": null,
          "latitude": 45.764,
          "longitude": 4.8357
        }
      ]
    }
  },
  "work_experiences": [
    {
      "company_name": "Northstar Labs",
      "job_title": "Senior Software Engineer",
      "description": "Lead a team of five engineers building a TypeScript and React SaaS platform.",
      "contract_type": "Permanent contract",
      "start_date": "2022-03-01",
      "end_date": null,
      "currently_active": true,
      "work_experience_country": "France",
      "work_experience_country_code": "FR",
      "work_experience_city": "Paris",
      "work_experience_postal_code": null,
      "experience_duration": 55
    },
    {
      "company_name": "Atelier Digital",
      "job_title": "Software Engineer",
      "description": "Built Node.js APIs and data pipelines for recruitment clients.",
      "contract_type": "Permanent contract",
      "start_date": "2018-09-01",
      "end_date": "2022-02-28",
      "currently_active": false,
      "work_experience_country": "France",
      "work_experience_country_code": "FR",
      "work_experience_city": "Paris",
      "work_experience_postal_code": null,
      "experience_duration": 42
    }
  ],
  "educations": [
    {
      "degree_title": "Master of Science in Computer Science",
      "school_name": "École Polytechnique",
      "description": "Distributed systems and software architecture.",
      "degree_type": "Level 7",
      "start_date": "2014-09-01",
      "end_date": "2016-06-30",
      "currently_active": false,
      "location": {
        "country": "France",
        "country_code": "FR",
        "region": "Île-de-France",
        "department": "Essonne",
        "city": "Palaiseau",
        "postal_code": "91120",
        "full_address": "Palaiseau, France"
      }
    }
  ],
  "rome_jobs": [
    {
      "job_title": "Ingénieur / Ingénieure logiciel",
      "job_code": "38971",
      "rome_title": "Études et développement informatique",
      "rome_code": "M1805",
      "prediction_score": 0.93
    }
  ],
  "languages": [
    {
      "language": "English",
      "level": "Native or Bilingual (C2)"
    },
    {
      "language": "French",
      "level": "Professional Working Proficiency (B2)"
    }
  ],
  "skills": [
    {
      "skill_title": "React",
      "skill_type": "Hard skill",
      "status": "normalized",
      "domain": "Technologie",
      "subcategory": "Languages & Frameworks"
    },
    {
      "skill_title": "Typescript",
      "skill_type": "Hard skill",
      "status": "normalized",
      "domain": "Technologie",
      "subcategory": "Languages & Frameworks"
    },
    {
      "skill_title": "Figma",
      "skill_type": "Software skill",
      "status": "normalized",
      "domain": "Design & Contenu",
      "subcategory": "Logiciel"
    },
    {
      "skill_title": "Technical leadership",
      "skill_type": "Soft skill",
      "status": "raw",
      "domain": null,
      "subcategory": null
    }
  ],
  "certifications": [
    "AWS Certified Developer – Associate"
  ],
  "interests": [
    "Open-source software",
    "Climbing"
  ]
}

When webhook_url is set, the result is also posted there as JSON, before the HTTP response is returned. Use it only as a convenience: the HTTP response remains the source of truth.

  • Sent only for successful parses, with Content-Type: application/json and no signature header. Add a secret token to the URL and check it on receipt.
  • Payload: the parsed resume. Unlike the HTTP response, status is "partial" when some steps were skipped, and upstream_status is absent.
  • 2-second timeout per attempt, up to 3 attempts on timeouts, network errors, 429 and 5xx. A webhook failure does not change the HTTP response.
  • The webhook can arrive even when the HTTP request ends with an error (for example 403 when credits run out during the call). Reconcile with your own application_id.

With do_not_store_data=true, HireLayer does not store the resume file. The parsed data is returned in the response as usual.

do_not_store_data=false (default)do_not_store_data=true
Original fileStored. info_resume.url links to it.Not stored. info_resume.url is null.
Candidate photoStored. face_url does not expire.Temporary link valid 10 minutes (face_url_expires_at).
Parsed dataReturned in the response.Returned in the response.

Existing integrations can keep using the asynchronous V2 contract. New integrations must use V3.