Skip to content

Reference

Legacy parsers

Legacy

`POST /api/v3/parser` and `POST /api/v2/parser` stay in service, with their JSON unchanged, for existing integrations. New integrations use the Resume Parser.

/api/v3/parser/api/v4/resumes/parse
Parsed resumeAt the top level of the responseUnder resume, next to application_id and credits_used
Same file sent againParsed again, 1 creditThe stored resume, already_stored: true, 0 credit
Errors{"error": "…", "code": "…"}{"error": {"code", "message", "param", "doc_url"}}
AsynchronousPrefer: respond-async and webhook_url, unsigned webhookwebhook_url, signed webhook
POST/api/v3/parser

Upload one resume file and receive the parsed resume at the top level of the response. Legacy: new integrations use POST /api/v4/resumes/parse, which returns the same JSON under resume.

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

Headers

  • Preferstring

    respond-async answers 202 right away and posts the outcome to webhook_url (HTTPS required). See Asynchronous mode.

    "respond-async"
  • HireLayer-Workspacestring

    The workspace the parse is stored in, when you serve several companies. Defaults to default. When sent, the response also includes workspace.

Request body

Content type multipart/form-data

  • filefilerequired

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

  • application_idstring

    Your id for this application (letters, digits and . _ : ~ -, up to 200 characters). The parse is stored in the resume database under it, replacing the resume stored under the same id before, and it comes back in info_resume.application_id. See Score a parsed resume.

  • webhook_urlstring (URL)

    HTTP(S) URL that also receives the result. The response stays synchronous unless you send Prefer: respond-async (an HTTPS URL on the standard port, without credentials, required). See Asynchronous mode.

  • do_not_store_datastring

    true: the resume file is not stored, nor the parsed resume. 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 is reserved for the Enterprise plan: on other plans the request is refused with 403 ENTERPRISE_PLAN_REQUIRED. See Data storage.

    "true""false"

Response

200Parsed resume.

  • statusstring

    Always success on HTTP 200.

    "success"
  • upstream_statusstringmay be absent

    Present when an optional step was skipped or the document is not a resume (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) or about a document that is not a resume (cover letter, diploma or certificate, recommendation letter). 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

      The id the parse is stored under in the resume database: your application_id, or, when you sent none, file_ followed by the first 32 hexadecimal characters of the SHA-256 of the file’s bytes. With do_not_store_data=true, or when storing failed, your application_id as sent, or null. See Score a parsed resume.

    • 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. A number written in the resume that is not valid for its country is still returned, in E.164 when its length fits, otherwise as written, with a warning.

    • 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

      Taxonomy skill name when status is normalized: in French for a resume in French, in English for a resume in any other language. Otherwise the text from the resume. One resume skill can give several normalized skills (Word/Excel).

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

      normalized: resolved to the HireLayer Skills taxonomy. raw: kept as written in the resume.

      "normalized""raw"
    • domainstring | null

      Primary domain of the taxonomy skill, in the language of skill_title. null when status is raw.

    • subcategorystring | null

      Primary family of the taxonomy skill, in the language of skill_title. null when status is raw.

  • certificationsstring[]
  • interestsstring[]
  • workspacestring | nullmay be absent

    Only when you send the HireLayer-Workspace header: the workspace the parse is stored in. null when it is not stored. See Score a parsed resume.

202Accepted in asynchronous mode: the outcome is posted to webhook_url.

  • statusstring
    "accepted"
  • application_idstring | null

    Your application_id, or null when not sent.

  • workspacestringmay be absent

    Only when you send the HireLayer-Workspace header: its value, the workspace the parse is stored in.

Errors

  • 400
    INVALID_MULTIPART_BODYThe request body is not valid multipart/form-data. Check the boundary and the Content-Disposition header of each part.

    The body cannot be read as multipart/form-data: the boundary is missing or does not match the body, the body is truncated, or a part has no Content-Disposition: form-data header with a name. Unquoted parameter values and filename* (as sent by .NET MultipartFormDataContent) are accepted.

    Do not retry

  • 400
    Missing required file field

    No multipart part named file.

    Do not retry

  • 400
    Prefer: respond-async requires a webhook_url field with an HTTPS URL

    The request asks for the asynchronous mode without a valid HTTPS webhook_url, or with one a failure cannot be posted to: with credentials (user:password@), on another port than the standard one, or to a private IP address, written as such or as a host name whose addresses are all private (such as localhost). A host name that does not resolve at that moment is accepted.

    Do not retry

  • 400
    application_id must be a string when provided

    application_id was sent as a file part.

    Do not retry

  • 400
    application_id must contain letters, digits and . _ : ~ -, up to 200 characters

    application_id has other characters, or more than 200. Nothing was parsed or billed.

    Do not retry

  • 400
    HireLayer-Workspace must contain letters, digits and . _ : ~ -, up to 200 characters

    The HireLayer-Workspace header has other characters, or more than 200. Nothing was parsed or billed.

    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

  • 403
    ENTERPRISE_PLAN_REQUIREDdo_not_store_data=true is reserved for the Enterprise plan. Send the request without it, or with do_not_store_data=false.

    do_not_store_data=true was sent by an account that is not on the Enterprise plan. Nothing was parsed or billed.

    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

  • 413
    The request body is larger than the 10 MB limit. Please upload a smaller file.

    The request body itself exceeds 10 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 not about a candidate (job offer, ID document, invoice, brochure…), is a fraudulent message (a fake recruiting-platform notice asking to click a link, even laid out as a CV), or nothing could be extracted from it. A cover letter, a diploma or a certificate is parsed instead (see Partial results).

    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, analysis) is temporarily unavailable, or the pages could not be read in time. A Retry-After header may give the wait in seconds.

    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.
Asynchronous mode
Send Prefer: respond-async with a webhook_url to get 202 Accepted right away, for automation platforms that stop waiting after about 30 seconds. See Asynchronous mode.
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. A cover letter, a diploma, a certificate or a recommendation letter is parsed the same way: only the information it contains is filled in, and warnings says the document is not a resume.
Documents
15 formats (PDF, DOC, DOCX, ODT, PPT, PPTX, ODP, XLS, RTF, TXT, HTML, Markdown, JPG/JPEG, PNG and BMP). An HTML page is read as its visible text; its email, phone and profile links count even when only the link shows, and a photo embedded in the page is returned in face_url. Markdown is read as written. Text files may be UTF-8, UTF-16 or Windows-1252. All pages are read. 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.
Stored resumes
Unless do_not_store_data=true, each parse is also stored, for free, in the resume database of the workspace, under your application_id (else an id drawn from the file), returned in info_resume.application_id. See Score a parsed resume.
curl -X POST https://hirelayer.co/api/v3/parser \
  -H "X-API-Key: $HIRELAYER_API_KEY" \
  -H "HireLayer-Workspace: acme-corp" \
  -F "file=@resume.pdf;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\nalex.morgan@example.com\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": "alex.morgan@example.com",
    "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": "Software skill",
      "status": "normalized",
      "domain": "Software Development",
      "subcategory": "Frontend development"
    },
    {
      "skill_title": "TypeScript",
      "skill_type": "Software skill",
      "status": "normalized",
      "domain": "Software Development",
      "subcategory": "Programming languages"
    },
    {
      "skill_title": "Figma",
      "skill_type": "Software skill",
      "status": "normalized",
      "domain": "Design, Creative & Media",
      "subcategory": "UX/UI design"
    },
    {
      "skill_title": "Technical leadership",
      "skill_type": "Soft skill",
      "status": "normalized",
      "domain": "Management, Projects & Strategy",
      "subcategory": "Team management"
    },
    {
      "skill_title": "Developer experience",
      "skill_type": "Hard 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, upstream_status is absent, workspace is the one you sent in HireLayer-Workspace (absent without the header), and info_resume.application_id is the one you sent (or null).
  • 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.

Add the header Prefer: respond-async and a webhook_url (HTTPS, on the standard port, without credentials) to receive 202 Accepted with Preference-Applied: respond-async, then the outcome on the webhook.

  • Success: the parsed resume, as described in Webhook. 1 credit is charged, as for a synchronous parse.
  • Failure: {"status": "error", "http_status": 422, "error": "…", "code": "…", "request_id": "…", "application_id": "…"}, with the status and message the synchronous call would have returned. Failures are not charged.
  • Errors found in the first 1.5 seconds (missing or invalid key, credits, missing file) are still returned synchronously with their usual status.
Asynchronous request
curl -X POST https://hirelayer.co/api/v3/parser \
  -H "X-API-Key: $HIRELAYER_API_KEY" \
  -H "Prefer: respond-async" \
  -F "file=@resume.pdf" \
  -F "application_id=app_123" \
  -F "webhook_url=https://example.com/hooks/hirelayer?token=YOUR_SECRET"

Unless you send do_not_store_data=true (Enterprise plan), each parse is also stored in the resume database of the workspace, under your application_id (letters, digits and . _ : ~ -, up to 200 characters), else file_ followed by the first 32 hexadecimal characters of the SHA-256 of the file’s bytes. info_resume.application_id is that id: send it to the Resume Scorer instead of the file, and the resume is not parsed or billed again.

Score a resume parsed by /api/v3/parser
curl -X POST https://hirelayer.co/api/v4/resumes/score \
  -H "X-API-Key: $HIRELAYER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"job": {"text": "Backend engineer, Node.js…"}, "resumes": [{"application_id": "app_123"}]}'
POST/api/v2/parser

Legacy asynchronous contract: the request is accepted with 202 and the result is posted to webhook_url.

Authentication
X-API-Key header
Billing
1 credit when the request is accepted (HTTP 202)
Client timeout
Client timeout ≥ 50 s

Request body

Content type multipart/form-data

  • filefilerequired

    The resume: PDF, DOCX, ODT, PPTX, ODP, TXT, JPG or PNG.

  • webhook_urlstring (URL)required

    URL that receives the result when processing ends.

  • application_idstring

    Your own reference, echoed in the webhook payload.

Response

202Accepted. The result is sent to webhook_url later.

  • messagestring
    "CV processing initiated."
  • bodynull
  • errorboolean
    false

Errors

  • 400
    INVALID_MULTIPART_BODYThe request body is not valid multipart/form-data. Check the boundary and the Content-Disposition header of each part.

    The body cannot be read as multipart/form-data: the boundary is missing or does not match the body, the body is truncated, or a part has no Content-Disposition: form-data header with a name. Unquoted parameter values and filename* (as sent by .NET MultipartFormDataContent) are accepted.

    Do not retry

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

    Any error from the legacy parser is returned with its status code (400 for a missing file or webhook_url, unsupported type…) and this generic message.

    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 request body is larger than the 10 MB limit. Please upload a smaller file.

    The request body itself exceeds 10 MB.

    Do not retry

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

    The request is not multipart/form-data.

    Do not retry

  • 500
    Internal Server Error

    The legacy parser did not accept the request within 45 seconds, or an unexpected failure.

    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

Behavior

Asynchronous
The gateway waits up to 45 seconds for the request to be accepted. The webhook then receives {"status": "success", …} with the parsed resume, or {"status": "failure", "error_code": …, "error_message": …}.
Billing
The credit is consumed when the request is accepted, even if processing fails later.
curl -X POST https://hirelayer.co/api/v2/parser \
  -H "X-API-Key: $HIRELAYER_API_KEY" \
  -F "file=@resume.pdf;type=application/pdf" \
  -F "webhook_url=https://example.com/hirelayer/webhook" \
  -F "application_id=app_123"
{
  "message": "CV processing initiated.",
  "body": null,
  "error": false
}

Resumes sent to /api/v2/parser are not stored in the resume database.