Get started

Errors and retries

Error format, every status code and message, and when to retry a HireLayer API call.

Successful calls return 2xx. Every error returns a non-2xx status and a JSON body with an error string. Branch on the HTTP status first.

Gateway errors (authentication, credits, CV Extract)
{
  "error": "This document does not appear to be a CV or resume. Please upload a CV or resume and try again.",
  "code": "DOCUMENT_NOT_A_RESUME"
}
Service errors (Job Extract, Match, Rank, Skills)
{
  "success": false,
  "error": "job_text cannot be empty"
}
  • error is always present and human-readable. Every exact message is listed in the catalogue below.
  • code is present on CV Extract errors: INVALID_FILE, DOCUMENT_NOT_A_RESUME, DOCUMENT_TEXT_EMPTY, DOCUMENT_UNREADABLE, DOCUMENT_TOO_LARGE, PARSER_UNAVAILABLE.
  • CV Extract errors also carry an x-parser-request-id header. Log it.
StatusMeaningAction
400Invalid request: missing field, wrong type, limit exceeded.Fix the request. Do not retry.
401Missing or invalid API key.Fix the key. Do not retry.
403No credit left.Add credits or upgrade, then retry.
404Unknown path or wrong method.Check the endpoint.
413Upload too large (CV Extract).Send a smaller file.
415Wrong Content-Type (CV Extract).Send multipart/form-data.
422The document cannot be parsed as a resume (CV Extract).Do not retry the same file.
500Invalid JSON body, or an unexpected failure.Check the body, then retry with backoff.
502 503 504Temporary failure or timeout.Retry with backoff; honour Retry-After.
  • Retry 5xx responses and connection failures, at most 3 times, with exponential backoff and jitter (about 1 s, 2 s, 4 s).
  • When a Retry-After header is present, wait that many seconds.
  • Never retry 4xx unchanged. 403 can succeed once credits are added.
  • Failed calls consume no credit. There is no idempotency key: a call your client abandons can still complete and be charged, so keep client timeouts above the gateway timeouts (150 s for CV Extract, 65 s otherwise).
# hirelayer.py — minimal client with retries. Requires: pip install requests
import mimetypes
import os
import random
import time

import requests

API_BASE = "https://onlineresumeparser.com/api"


class HireLayerError(Exception):
    def __init__(self, status, message, code=None, request_id=None):
        super().__init__(f"HireLayer {status}: {message}")
        self.status = status
        self.code = code
        self.request_id = request_id


def _delay(attempt, retry_after):
    if retry_after and retry_after.isdigit():
        return int(retry_after)
    return min(30, 2**attempt) + random.random()


def call(method, path, *, json=None, files=None, data=None, timeout=65, max_retries=3):
    """Call HireLayer. Retries 5xx and connection failures, raises HireLayerError otherwise."""
    headers = {"X-API-Key": os.environ["HIRELAYER_API_KEY"]}
    for attempt in range(max_retries + 1):
        try:
            response = requests.request(
                method,
                API_BASE + path,
                headers=headers,
                json=json,
                files=files,
                data=data,
                timeout=timeout,
            )
        except requests.ConnectionError:
            if attempt == max_retries:
                raise
            time.sleep(_delay(attempt, None))
            continue

        if response.ok:
            return response.json()
        if response.status_code >= 500 and attempt < max_retries:
            time.sleep(_delay(attempt, response.headers.get("Retry-After")))
            continue

        try:
            body = response.json()
        except ValueError:
            body = {}
        raise HireLayerError(
            response.status_code,
            body.get("error", response.reason),
            body.get("code"),
            response.headers.get("x-parser-request-id"),
        )


def parse_resume(path, application_id=None):
    content_type = mimetypes.guess_type(path)[0] or "application/octet-stream"
    with open(path, "rb") as file:
        content = file.read()  # bytes can be re-sent on retry
    return call(
        "POST",
        "/v3/parser",
        files={"file": (os.path.basename(path), content, content_type)},
        data={"application_id": application_id} if application_id else None,
        timeout=150,
    )

Exact error messages, per endpoint.

POST/api/v3/parser17 errors›
  • 400
    Missing required file field

    Do not retry

  • 400
    application_id must be a string when provided

    Do not retry

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

    Do not retry

  • 401
    Missing API Key

    Do not retry

  • 401
    Invalid API Key

    Do not retry

  • 403
    Insufficient credits available

    Fix, then retry

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

    Do not retry

  • 415
    Content-Type must be 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.

    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.

    Do not retry

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

    Do not retry

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

    Do not retry

  • 500
    Internal Server Error

    Retry with backoff

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

    Retry with backoff

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

    Retry with backoff

  • 503
    Credit service temporarily unavailable

    Retry with backoff

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

    Retry with backoff

POST/api/v1/jobs/extract-criteria13 errors›
  • 400
    Request body must be a JSON object

    Do not retry

  • 400
    The request contains unsupported fields

    Do not retry

  • 400
    The 'job_text' field is required

    Do not retry

  • 400
    job_text cannot be empty

    Do not retry

  • 400
    job_text must be 50000 characters or less

    Do not retry

  • 401
    Missing API Key

    Do not retry

  • 401
    Invalid API Key

    Do not retry

  • 403
    Insufficient credits available

    Fix, then retry

  • 500
    Internal server error

    Retry with backoff

  • 500
    Internal server error. Please try again later.

    Retry with backoff

  • 502
    Upstream API unavailable

    Retry with backoff

  • 502
    The AI processing step failed. Please try again later.

    Retry with backoff

  • 503
    Credit service temporarily unavailable

    Retry with backoff

POST/api/v1/matching/job-candidate18 errors›
  • 400
    Request body must be a JSON object

    Do not retry

  • 400
    The request contains unsupported fields

    Do not retry

  • 400
    The 'job_text' field is required

    Do not retry

  • 400
    job_text cannot be empty

    Do not retry

  • 400
    job_text must be 50000 characters or less

    Do not retry

  • 400
    The 'candidate_text' field is required

    Do not retry

  • 400
    candidate_text cannot be empty

    Do not retry

  • 400
    candidate_text must be 50000 characters or less

    Do not retry

  • 400
    The 'matching_criteria' field must be an array

    Do not retry

  • 400
    matching_criteria contains an invalid criterion

    Do not retry

  • 401
    Missing API Key

    Do not retry

  • 401
    Invalid API Key

    Do not retry

  • 403
    Insufficient credits available

    Fix, then retry

  • 500
    Internal server error

    Retry with backoff

  • 500
    Internal server error. Please try again later.

    Retry with backoff

  • 502
    Upstream API unavailable

    Retry with backoff

  • 502
    The AI processing step failed. Please try again later.

    Retry with backoff

  • 503
    Credit service temporarily unavailable

    Retry with backoff

POST/api/v1/matching/job-candidates/rank19 errors›
  • 400
    Request body must be a JSON object

    Do not retry

  • 400
    The request contains unsupported fields

    Do not retry

  • 400
    The 'job_text' field is required

    Do not retry

  • 400
    job_text cannot be empty

    Do not retry

  • 400
    job_text must be 50000 characters or less

    Do not retry

  • 400
    The 'candidates' field must be an array

    Do not retry

  • 400
    candidates cannot be empty

    Do not retry

  • 400
    candidates must contain 10 candidates or fewer

    Do not retry

  • 400
    candidates contains an invalid candidate

    Do not retry

  • 400
    candidate_text must be 50000 characters or less

    Do not retry

  • 400
    candidates contains duplicate ids

    Do not retry

  • 401
    Missing API Key

    Do not retry

  • 401
    Invalid API Key

    Do not retry

  • 403
    Insufficient credits available

    Fix, then retry

  • 500
    Internal server error

    Retry with backoff

  • 500
    Internal server error. Please try again later.

    Retry with backoff

  • 502
    Upstream API unavailable

    Retry with backoff

  • 502
    The AI processing step failed. Please try again later.

    Retry with backoff

  • 503
    Credit service temporarily unavailable

    Retry with backoff

POST/api/v1/skills/match16 errors›
  • 400
    Provide either 'skill' or 'skills', not both

    Do not retry

  • 400
    The 'skill' or 'skills' field is required

    Do not retry

  • 400
    The 'skill' field is required

    Do not retry

  • 400
    Skill cannot be empty

    Do not retry

  • 400
    The 'skills' (list) field is required

    Do not retry

  • 400
    The 'skills' field must be a non-empty list

    Do not retry

  • 400
    Maximum 100 skills per batch request

    Do not retry

  • 400
    top_k must be an integer between 1 and 50

    Do not retry

  • 400
    Request body must be a JSON object

    Do not retry

  • 401
    Missing API Key

    Do not retry

  • 401
    Invalid API Key

    Do not retry

  • 403
    Insufficient credits available

    Fix, then retry

  • 500
    Internal server error

    Retry with backoff

  • 500
    Internal server error. Please try again later.

    Retry with backoff

  • 502
    Upstream API unavailable

    Retry with backoff

  • 503
    Credit service temporarily unavailable

    Retry with backoff

GET/api/v1/skills6 errors›
  • 401
    Missing API Key

    Do not retry

  • 401
    Invalid API Key

    Do not retry

  • 403
    Insufficient credits available

    Fix, then retry

  • 500
    Internal server error

    Retry with backoff

  • 502
    Upstream API unavailable

    Retry with backoff

  • 503
    Credit service temporarily unavailable

    Retry with backoff

GET/api/v1/health1 errors›
  • 502
    Upstream API unavailable

    Retry with backoff

POST/api/v2/parser6 errors›
  • 400
    An error occurred while processing the document or extracting its text. Please try again later.

    Do not retry

  • 401
    Missing API Key

    Do not retry

  • 401
    Invalid API Key

    Do not retry

  • 403
    Insufficient credits available

    Fix, then retry

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

    Do not retry

  • 503
    Credit service temporarily unavailable

    Retry with backoff