Skip to content

Data and account

Jobs and scores

List, store under your own ids and delete the jobs of a workspace, edit their criteria, and read their ranking again with the recruiter’s priorities.

A job is stored with its criteria under its job_id by the Job Criteria Extractor, the Resume Scorer or PUT /jobs/{job_id}, and every score the Resume Scorer computes is stored with it. Only jobs with status: "open" are searched by Job Recommendations: close one with {"status": "closed"}.

  • Listing, reading, storing and deleting jobs and scores is free, and so are removing a criterion and changing its weight, requirement or type: the stored scores are re-ranked at once.
  • Adding a criterion, rewording one (label or threshold), or sending new criteria or recompute_criteria: true to PUT /jobs/{job_id} evaluates the job’s stored scores again, 1 credit each.
  • Reading the ranking with precise_ranking=true adds the ranking reasons, 1 credit per read.
GET/api/v4/jobs

The jobs of the workspace, most recently updated first. Free.

Authentication
X-API-Key header
Billing
Free
Client timeout
Client timeout ≥ 30 s

Headers

  • HireLayer-Workspacestring

    Your customer's workspace id. Case-insensitive, created on first use. Absent, calls use default.

Query parameters

  • limitinteger

    Page size.

    1–100 · default 20

  • cursorstring

    The next_cursor of the previous page.

  • statusstring

    Only open jobs are found by POST /jobs/search.

    "open""closed"

Response

200A page of jobs.

  • dataobject[]
    ›Show 11 child fields
    • job_idstring
    • workspacestring
    • titlestring | null
    • textstring

      The job description.

    • locationstring | null
    • languagestring

      Language of the job's criteria labels and thresholds, score summaries and explanations, and ranking reasons. Sent, it is kept; left out, it is the language of the job's text when the job is created, and en when that text is in another language or its language cannot be told.

      "en""fr""de""es""pt"
    • statusstring

      Only open jobs are found by POST /jobs/search.

      "open""closed"
    • criteriaobject[]
      ›Show 7 child fields
      • criterion_idstring

        Stable id in the job, such as crit_2. Never reused.

      • labelstring
      • typestring
        "skill""experience""education""language""certification""location""soft_skill""other"
      • requirementstring

        required: a resume that clearly lacks it loses 25 % of its score, never eliminated outright. preferred and bonus count only through their weight.

        "required""preferred""bonus"
      • weightinteger

        Importance. 3 essential, 2 important, 1 nice to have, 0 off: kept on the job, left out of every score, of the required-criterion penalty, of required_missing and of to_verify. Texts already written (summary, explanation) stay as they are.

        0–3

      • thresholdstring | null
      • sourcestring

        extracted by HireLayer, or custom: sent or edited by you.

        "extracted""custom"
    • scores_countinteger

      ≥ 0

    • created_atstring (date-time)
    • updated_atstring (date-time)
  • next_cursorstring | null

Errors

  • 400
    invalid_requeststatus must be open or closed.

    param: status. status is not open or closed.

    Fix, then retry

  • 400
    invalid_requestlimit must be an integer from 1 to 100.

    param: limit. limit out of range.

    Fix, then retry

  • 400
    invalid_requestcursor is not a next_cursor returned by this API.

    param: cursor. cursor is not a next_cursor of this list.

    Fix, then retry

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

    param: HireLayer-Workspace. HireLayer-Workspace is not a valid id.

    Fix, then retry

  • 401
    missing_api_keyThe X-API-Key header is missing.

    No X-API-Key header.

    Fix, then retry

  • 401
    missing_api_keyAuthorization: Bearer is not accepted: send the key in the X-API-Key header.

    The key sent as Authorization: Bearer: it goes in X-API-Key.

    Fix, then retry

  • 401
    missing_api_keyThe key goes in the X-API-Key header, not in the URL.

    The key sent in the URL: it goes in X-API-Key.

    Fix, then retry

  • 401
    invalid_api_keyInvalid API key: it is unknown, malformed or revoked.

    The key is unknown, malformed or revoked.

    Fix, then retry

  • 500
    internal_errorInternal error: retry later. If it persists, contact support with the request_id.

    An unexpected error.

    Retry with backoff

  • 502
    internal_errorThe service could not be reached: retry later.

    The service could not be reached.

    Retry with backoff

  • 503
    internal_errorThe credit service is briefly unavailable: retry in a second.

    The credit service is briefly unavailable. Header Retry-After: <seconds>.

    Retry with backoff

  • 504
    internal_errorThe service did not answer in time. The change may still be applied: read it before sending it again.

    No answer in time.

    Retry with backoff

curl -g "https://hirelayer.co/api/v4/jobs?status=open" \
  -H "X-API-Key: $HIRELAYER_API_KEY"
{
  "error": {
    "code": "invalid_request",
    "message": "status must be open or closed.",
    "param": "status",
    "doc_url": "https://hirelayer.co/api-docs/errors#invalid_request"
  },
  "request_id": "6f1c2a4e-1d2b-4c3a-9e8f-0a1b2c3d4e5f"
}
GET/api/v4/jobs/{job_id}

Get a stored job.

Authentication
X-API-Key header
Billing
Free
Client timeout
Client timeout ≥ 30 s

Path parameters

  • job_idstringrequired

    Letters, digits and . _ : ~ -, up to 200 characters.

Headers

  • HireLayer-Workspacestring

    Your customer's workspace id. Case-insensitive, created on first use. Absent, calls use default.

Response

200The job and its criteria.

  • job_idstring
  • workspacestring
  • titlestring | null
  • textstring

    The job description.

  • locationstring | null
  • languagestring

    Language of the job's criteria labels and thresholds, score summaries and explanations, and ranking reasons. Sent, it is kept; left out, it is the language of the job's text when the job is created, and en when that text is in another language or its language cannot be told.

    "en""fr""de""es""pt"
  • statusstring

    Only open jobs are found by POST /jobs/search.

    "open""closed"
  • criteriaobject[]
    ›Show 7 child fields
    • criterion_idstring

      Stable id in the job, such as crit_2. Never reused.

    • labelstring
    • typestring
      "skill""experience""education""language""certification""location""soft_skill""other"
    • requirementstring

      required: a resume that clearly lacks it loses 25 % of its score, never eliminated outright. preferred and bonus count only through their weight.

      "required""preferred""bonus"
    • weightinteger

      Importance. 3 essential, 2 important, 1 nice to have, 0 off: kept on the job, left out of every score, of the required-criterion penalty, of required_missing and of to_verify. Texts already written (summary, explanation) stay as they are.

      0–3

    • thresholdstring | null
    • sourcestring

      extracted by HireLayer, or custom: sent or edited by you.

      "extracted""custom"
  • scores_countinteger

    ≥ 0

  • created_atstring (date-time)
  • updated_atstring (date-time)

Errors

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

    param: job_id. job_id in the path is not a valid id.

    Fix, then retry

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

    param: HireLayer-Workspace. HireLayer-Workspace is not a valid id.

    Fix, then retry

  • 401
    missing_api_keyThe X-API-Key header is missing.

    No X-API-Key header.

    Fix, then retry

  • 401
    missing_api_keyAuthorization: Bearer is not accepted: send the key in the X-API-Key header.

    The key sent as Authorization: Bearer: it goes in X-API-Key.

    Fix, then retry

  • 401
    missing_api_keyThe key goes in the X-API-Key header, not in the URL.

    The key sent in the URL: it goes in X-API-Key.

    Fix, then retry

  • 401
    invalid_api_keyInvalid API key: it is unknown, malformed or revoked.

    The key is unknown, malformed or revoked.

    Fix, then retry

  • 404
    not_foundNo job req-7 in workspace default.

    param: job_id. No job under this id in the workspace.

    Do not retry

  • 500
    internal_errorInternal error: retry later. If it persists, contact support with the request_id.

    An unexpected error.

    Retry with backoff

  • 502
    internal_errorThe service could not be reached: retry later.

    The service could not be reached.

    Retry with backoff

  • 503
    internal_errorThe credit service is briefly unavailable: retry in a second.

    The credit service is briefly unavailable. Header Retry-After: <seconds>.

    Retry with backoff

  • 504
    internal_errorThe service did not answer in time. The change may still be applied: read it before sending it again.

    No answer in time.

    Retry with backoff

# Example ids: replace job_30cfa454c97663f3e1801e5a61b87d74 with a job_id returned by POST /api/v4/jobs/extract-criteria.
curl https://hirelayer.co/api/v4/jobs/job_30cfa454c97663f3e1801e5a61b87d74 \
  -H "X-API-Key: $HIRELAYER_API_KEY"
{
  "job_id": "job_30cfa454c97663f3e1801e5a61b87d74",
  "workspace": "acme",
  "title": "Ingénieur IA / Développeur backend Node.js (H/F)",
  "text": "Ingénieur IA / Développeur backend Node.js (H/F)\nLumio · Paris 9e · CDI · Hybride (2 jours de télétravail par semaine)\n\nLumio édite une plateforme SaaS qui automatise le traitement de documents administratifs pour les cabinets comptables (300 clients, 2 millions de documents par mois). Notre équipe produit compte 14 personnes.\n\nVos missions\n- Concevoir et faire évoluer les API backend (Node.js, TypeScript) de la plateforme\n- Intégrer des modèles de langage en production : RAG, extraction structurée, évaluation de la qualité des réponses\n- Déployer et superviser l'infrastructure sur AWS (Lambda, S3, DynamoDB) avec Terraform\n- Participer aux revues de code et accompagner deux développeurs juniors\n\nVotre profil\n- Diplôme d'ingénieur ou Bac+5 en informatique\n- 3 ans minimum d'expérience en développement backend Node.js / TypeScript\n- Expérience indispensable de l'intégration de LLM en production\n- Vous maîtrisez AWS (Lambda, S3, DynamoDB) ; une certification AWS est un plus\n- Anglais courant (B2 minimum) obligatoire : une partie de nos clients est à l'étranger\n- Idéalement, une première expérience d'encadrement technique\n- Vous acceptez une astreinte d'une semaine sur six\n\nCe que nous offrons\n- Salaire de 55 à 65 k€ selon expérience, BSPCE\n- Tickets restaurant, mutuelle prise en charge à 100 %\n- Démarrage dès que possible",
  "location": null,
  "language": "fr",
  "status": "open",
  "criteria": [
    {
      "criterion_id": "crit_1",
      "label": "Développement backend Node.js / TypeScript",
      "type": "skill",
      "requirement": "preferred",
      "weight": 3,
      "threshold": "3 ans minimum",
      "source": "extracted"
    },
    {
      "criterion_id": "crit_2",
      "label": "Intégration de LLM en production",
      "type": "skill",
      "requirement": "required",
      "weight": 3,
      "threshold": null,
      "source": "extracted"
    },
    {
      "criterion_id": "crit_3",
      "label": "AWS (Lambda, S3, DynamoDB)",
      "type": "skill",
      "requirement": "preferred",
      "weight": 2,
      "threshold": null,
      "source": "extracted"
    },
    {
      "criterion_id": "crit_4",
      "label": "Diplôme d'ingénieur ou Bac+5 en informatique",
      "type": "education",
      "requirement": "preferred",
      "weight": 2,
      "threshold": "Bac+5",
      "source": "extracted"
    },
    {
      "criterion_id": "crit_5",
      "label": "Anglais",
      "type": "language",
      "requirement": "required",
      "weight": 2,
      "threshold": "B2 minimum",
      "source": "extracted"
    },
    {
      "criterion_id": "crit_6",
      "label": "Encadrement technique",
      "type": "experience",
      "requirement": "bonus",
      "weight": 1,
      "threshold": null,
      "source": "extracted"
    },
    {
      "criterion_id": "crit_7",
      "label": "Certification AWS",
      "type": "certification",
      "requirement": "bonus",
      "weight": 1,
      "threshold": null,
      "source": "extracted"
    },
    {
      "criterion_id": "crit_8",
      "label": "Astreinte",
      "type": "other",
      "requirement": "required",
      "weight": 1,
      "threshold": "1 semaine sur 6",
      "source": "extracted"
    }
  ],
  "scores_count": 2,
  "created_at": "2026-10-26T22:38:23Z",
  "updated_at": "2026-10-26T22:38:23Z"
}
PUT/api/v4/jobs/{job_id}

Creates or updates a job under your job_id, for an ATS that keeps its own ids. Without criteria on creation, they are extracted from its text, as by POST /jobs/extract-criteria. On update, criteria are kept unless you send criteria or recompute_criteria: true; a criterion with the same label and threshold as a current one keeps its id and its per-criterion results.

Authentication
X-API-Key header
Billing
Free; 1 credit per stored score evaluated again
Client timeout
Client timeout ≥ 150 s

Path parameters

  • job_idstringrequired

    Letters, digits and . _ : ~ -, up to 200 characters.

Headers

  • HireLayer-Workspacestring

    Your customer's workspace id. Case-insensitive, created on first use. Absent, calls use default.

Request body

Content type application/json

  • textstring

    The job description. Required to create the job.

    30–50,000 characters

  • titlestring | null

    null erases it.

    ≤ 300 characters

  • locationstring | null

    null erases it.

    ≤ 300 characters

  • statusstring

    Only open jobs are found by POST /jobs/search.

    "open""closed"
  • languagestring

    Language of the job's criteria labels and thresholds, score summaries and explanations, and ranking reasons. Sent, it is kept; left out, it is the language of the job's text when the job is created, and en when that text is in another language or its language cannot be told.

    "en""fr""de""es""pt"
  • criteriaobject[]

    1–20 items

    ›Show 7 child fields
    • labelstringrequired

      1–300 characters

    • typestring
      "skill""experience""education""language""certification""location""soft_skill""other"
    • requirementstring

      required: a resume that clearly lacks it loses 25 % of its score, never eliminated outright. preferred and bonus count only through their weight.

      "required""preferred""bonus"
    • weightinteger

      Importance. 3 essential, 2 important, 1 nice to have, 0 off: kept on the job, left out of every score, of the required-criterion penalty, of required_missing and of to_verify. Texts already written (summary, explanation) stay as they are.

      0–3

    • thresholdstring | null

      Minimum level in short text, such as 3 ans minimum, Bac+2 or B2.

      ≤ 100 characters

    • criterion_idstring
    • sourcestring
  • recompute_criteriaboolean

    Extract the criteria again from text. Not with criteria.

    default false

Response

200Updated.

  • job_idstring
  • workspacestring
  • titlestring | null
  • textstring

    The job description.

  • locationstring | null
  • languagestring

    Language of the job's criteria labels and thresholds, score summaries and explanations, and ranking reasons. Sent, it is kept; left out, it is the language of the job's text when the job is created, and en when that text is in another language or its language cannot be told.

    "en""fr""de""es""pt"
  • statusstring

    Only open jobs are found by POST /jobs/search.

    "open""closed"
  • criteriaobject[]
    ›Show 7 child fields
    • criterion_idstring

      Stable id in the job, such as crit_2. Never reused.

    • labelstring
    • typestring
      "skill""experience""education""language""certification""location""soft_skill""other"
    • requirementstring

      required: a resume that clearly lacks it loses 25 % of its score, never eliminated outright. preferred and bonus count only through their weight.

      "required""preferred""bonus"
    • weightinteger

      Importance. 3 essential, 2 important, 1 nice to have, 0 off: kept on the job, left out of every score, of the required-criterion penalty, of required_missing and of to_verify. Texts already written (summary, explanation) stay as they are.

      0–3

    • thresholdstring | null
    • sourcestring

      extracted by HireLayer, or custom: sent or edited by you.

      "extracted""custom"
  • scores_countinteger

    ≥ 0

  • created_atstring (date-time)
  • updated_atstring (date-time)

201Created.

  • job_idstring
  • workspacestring
  • titlestring | null
  • textstring

    The job description.

  • locationstring | null
  • languagestring

    Language of the job's criteria labels and thresholds, score summaries and explanations, and ranking reasons. Sent, it is kept; left out, it is the language of the job's text when the job is created, and en when that text is in another language or its language cannot be told.

    "en""fr""de""es""pt"
  • statusstring

    Only open jobs are found by POST /jobs/search.

    "open""closed"
  • criteriaobject[]
    ›Show 7 child fields
    • criterion_idstring

      Stable id in the job, such as crit_2. Never reused.

    • labelstring
    • typestring
      "skill""experience""education""language""certification""location""soft_skill""other"
    • requirementstring

      required: a resume that clearly lacks it loses 25 % of its score, never eliminated outright. preferred and bonus count only through their weight.

      "required""preferred""bonus"
    • weightinteger

      Importance. 3 essential, 2 important, 1 nice to have, 0 off: kept on the job, left out of every score, of the required-criterion penalty, of required_missing and of to_verify. Texts already written (summary, explanation) stay as they are.

      0–3

    • thresholdstring | null
    • sourcestring

      extracted by HireLayer, or custom: sent or edited by you.

      "extracted""custom"
  • scores_countinteger

    ≥ 0

  • created_atstring (date-time)
  • updated_atstring (date-time)

Errors

  • 400
    invalid_requesttext must be 30 characters or more: send the job's full text.

    param: text. text is under 30 characters.

    Fix, then retry

  • 400
    invalid_requesttext is required to create a job.

    param: text. A new job without its text.

    Fix, then retry

  • 400
    invalid_requeststatus must be open or closed.

    param: status. status is not open or closed.

    Fix, then retry

  • 400
    invalid_requestcriteria[0].weight must be 0, 1, 2 or 3.

    param: criteria[0].weight. A criterion breaks a rule (here its weight): param names the field.

    Fix, then retry

  • 400
    invalid_requestcriteria must hold 1 to 20 criteria.

    param: criteria. No criterion, or more than 20.

    Fix, then retry

  • 400
    invalid_requestcriteria[1] repeats criteria[0] (same label and threshold).

    param: criteria[1].label. Two criteria with the same label and threshold.

    Fix, then retry

  • 400
    invalid_requesttitle must be 300 characters or less.

    param: title. title or location over 300 characters.

    Fix, then retry

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

    param: job_id. job_id in the path is not a valid id.

    Fix, then retry

  • 400
    invalid_requestUnknown field description.

    param: description. A field the call does not take.

    Fix, then retry

  • 400
    invalid_requestThe request body is not valid JSON.

    The body is not valid JSON, not an object, or not sent as application/json.

    Fix, then retry

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

    param: HireLayer-Workspace. HireLayer-Workspace is not a valid id.

    Fix, then retry

  • 400
    storage_requiredThis workspace runs without storage (do_not_store_data): nothing can be stored in it.

    param: HireLayer-Workspace. The workspace runs without storage, and the call would store something in it.

    Do not retry

  • 401
    missing_api_keyThe X-API-Key header is missing.

    No X-API-Key header.

    Fix, then retry

  • 401
    missing_api_keyAuthorization: Bearer is not accepted: send the key in the X-API-Key header.

    The key sent as Authorization: Bearer: it goes in X-API-Key.

    Fix, then retry

  • 401
    missing_api_keyThe key goes in the X-API-Key header, not in the URL.

    The key sent in the URL: it goes in X-API-Key.

    Fix, then retry

  • 401
    invalid_api_keyInvalid API key: it is unknown, malformed or revoked.

    The key is unknown, malformed or revoked.

    Fix, then retry

  • 403
    insufficient_creditsThis call evaluates 12 scores, 1 credit each: 12 credits, and 3 are left. Nothing was processed or billed.

    The change evaluates the job's stored scores again, and the credits left do not cover them.

    Fix, then retry

  • 413
    payload_too_largetext must be 50,000 characters or less.

    param: text. The text is over 50,000 characters.

    Fix, then retry

  • 413
    payload_too_largeThe request body must be 10 MB or less.

    The body is over 10 MB.

    Fix, then retry

  • 500
    internal_errorInternal error: retry later. If it persists, contact support with the request_id.

    An unexpected error.

    Retry with backoff

  • 502
    model_unavailableThe analysis did not complete after several attempts. Nothing was stored or billed: retry with backoff.

    The analysis did not complete.

    Retry with backoff

  • 502
    internal_errorThe service could not be reached: retry later.

    The service could not be reached.

    Retry with backoff

  • 503
    internal_errorThe credit service is briefly unavailable: retry in a second.

    The credit service is briefly unavailable. Header Retry-After: <seconds>.

    Retry with backoff

  • 504
    internal_errorThe service did not answer in time. The change may still be applied: read it before sending it again.

    No answer in time.

    Retry with backoff

Behavior

Partial update
a field left out keeps its stored value (text, title, location, status, language, and the criteria as above); null erases title or location. To close a job, send {"status": "closed"}. text is required only to create a job: an unknown job_id without text is refused (400, param: text). A text holds at least 30 characters.
Language
en, fr, de, es or pt, for the criteria extracted and the scores' summaries and explanations. Left out on creation, it is the language of text (en for a text in any other language); on update, the stored one stays. Criteria already extracted keep their wording: send recompute_criteria: true to extract them again in a new language.
Without storage
refused in a workspace without storage (400 storage_required).
Credits
0, plus 1 per stored score evaluated again because criteria were added, reworded or extracted again.
Verdicts
a criterion added, removed or reworded sets the verdict of the job's scores to null. Each comes back when its resume is sent again to POST /resumes/score for this job (1 credit, a full evaluation).
curl -X PUT https://hirelayer.co/api/v4/jobs/req-2026-114 \
  -H "X-API-Key: $HIRELAYER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Ingénieur IA / Développeur backend Node.js (H/F)",
    "text": "Ingénieur IA / Développeur backend Node.js (H/F)\nLumio · Paris 9e · CDI · Hybride (2 jours de télétravail par semaine)\n- 3 ans minimum d'\''expérience en développement backend Node.js / TypeScript\n- Expérience indispensable de l'\''intégration de LLM en production\n- Vous maîtrisez AWS (Lambda, S3, DynamoDB) ; une certification AWS est un plus\n- Anglais courant (B2 minimum) obligatoire",
    "location": "Paris",
    "status": "open"
  }'
{
  "error": {
    "code": "invalid_request",
    "message": "text must be 30 characters or more: send the job's full text.",
    "param": "text",
    "doc_url": "https://hirelayer.co/api-docs/errors#invalid_request"
  },
  "request_id": "6f1c2a4e-1d2b-4c3a-9e8f-0a1b2c3d4e5f"
}
DELETE/api/v4/jobs/{job_id}

Deletes the job, its criteria and its scores. The resumes stay. Deleting a job that does not exist is not an error. Free.

Authentication
X-API-Key header
Billing
Free
Client timeout
Client timeout ≥ 30 s

Path parameters

  • job_idstringrequired

    Letters, digits and . _ : ~ -, up to 200 characters.

Headers

  • HireLayer-Workspacestring

    Your customer's workspace id. Case-insensitive, created on first use. Absent, calls use default.

Response

204Deleted.

Errors

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

    param: job_id. job_id in the path is not a valid id.

    Fix, then retry

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

    param: HireLayer-Workspace. HireLayer-Workspace is not a valid id.

    Fix, then retry

  • 401
    missing_api_keyThe X-API-Key header is missing.

    No X-API-Key header.

    Fix, then retry

  • 401
    missing_api_keyAuthorization: Bearer is not accepted: send the key in the X-API-Key header.

    The key sent as Authorization: Bearer: it goes in X-API-Key.

    Fix, then retry

  • 401
    missing_api_keyThe key goes in the X-API-Key header, not in the URL.

    The key sent in the URL: it goes in X-API-Key.

    Fix, then retry

  • 401
    invalid_api_keyInvalid API key: it is unknown, malformed or revoked.

    The key is unknown, malformed or revoked.

    Fix, then retry

  • 500
    internal_errorInternal error: retry later. If it persists, contact support with the request_id.

    An unexpected error.

    Retry with backoff

  • 502
    internal_errorThe service could not be reached: retry later.

    The service could not be reached.

    Retry with backoff

  • 503
    internal_errorThe credit service is briefly unavailable: retry in a second.

    The credit service is briefly unavailable. Header Retry-After: <seconds>.

    Retry with backoff

  • 504
    internal_errorThe service did not answer in time. The change may still be applied: read it before sending it again.

    No answer in time.

    Retry with backoff

curl -X DELETE https://hirelayer.co/api/v4/jobs/req-2026-114 \
  -H "X-API-Key: $HIRELAYER_API_KEY"
{
  "error": {
    "code": "invalid_request",
    "message": "job_id must contain letters, digits and . _ : ~ -, up to 200 characters.",
    "param": "job_id",
    "doc_url": "https://hirelayer.co/api-docs/errors#invalid_request"
  },
  "request_id": "6f1c2a4e-1d2b-4c3a-9e8f-0a1b2c3d4e5f"
}
POST/api/v4/jobs/{job_id}/criteria

Adds a criterion. The job's stored scores are evaluated on it in the background, 1 credit each (their evaluation_status is pending meanwhile), and their verdict is null until their next full evaluation (see Verdict).

Authentication
X-API-Key header
Billing
1 credit per stored score of the job
Client timeout
Client timeout ≥ 150 s

Path parameters

  • job_idstringrequired

    Letters, digits and . _ : ~ -, up to 200 characters.

Headers

  • HireLayer-Workspacestring

    Your customer's workspace id. Case-insensitive, created on first use. Absent, calls use default.

Request body

Content type application/json

  • labelstringrequired

    1–300 characters

  • typestring
    "skill""experience""education""language""certification""location""soft_skill""other"
  • requirementstring

    required: a resume that clearly lacks it loses 25 % of its score, never eliminated outright. preferred and bonus count only through their weight.

    "required""preferred""bonus"
  • weightinteger

    Importance. 3 essential, 2 important, 1 nice to have, 0 off: kept on the job, left out of every score, of the required-criterion penalty, of required_missing and of to_verify. Texts already written (summary, explanation) stay as they are.

    0–3

  • thresholdstring | null

    Minimum level in short text, such as 3 ans minimum, Bac+2 or B2.

    ≤ 100 characters

  • criterion_idstring
  • sourcestring

Response

201Added.

  • criterion_idstring

    Stable id in the job, such as crit_2. Never reused.

  • labelstring
  • typestring
    "skill""experience""education""language""certification""location""soft_skill""other"
  • requirementstring

    required: a resume that clearly lacks it loses 25 % of its score, never eliminated outright. preferred and bonus count only through their weight.

    "required""preferred""bonus"
  • weightinteger

    Importance. 3 essential, 2 important, 1 nice to have, 0 off: kept on the job, left out of every score, of the required-criterion penalty, of required_missing and of to_verify. Texts already written (summary, explanation) stay as they are.

    0–3

  • thresholdstring | null
  • sourcestring

    extracted by HireLayer, or custom: sent or edited by you.

    "extracted""custom"

Errors

  • 400
    invalid_requestlabel is required.

    param: label. No label.

    Fix, then retry

  • 400
    invalid_requesttype must be one of skill, experience, education, language, certification, location, soft_skill, other.

    param: type. A field out of its values (here type): param names it.

    Fix, then retry

  • 400
    invalid_requestweight must be 0, 1, 2 or 3.

    param: weight. A criterion breaks a rule (here its weight): param names the field.

    Fix, then retry

  • 400
    invalid_requestA job has at most 20 criteria.

    The job has 20 criteria already.

    Fix, then retry

  • 400
    invalid_requestCriterion crit_3 already has this label and threshold.

    param: label. Another criterion of the job has the same label and threshold.

    Fix, then retry

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

    param: job_id. job_id in the path is not a valid id.

    Fix, then retry

  • 400
    invalid_requestUnknown field name.

    param: name. A field the call does not take.

    Fix, then retry

  • 400
    invalid_requestThe request body is not valid JSON.

    The body is not valid JSON, not an object, or not sent as application/json.

    Fix, then retry

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

    param: HireLayer-Workspace. HireLayer-Workspace is not a valid id.

    Fix, then retry

  • 400
    storage_requiredThis workspace runs without storage (do_not_store_data): nothing can be stored in it.

    param: HireLayer-Workspace. The workspace runs without storage, and the call would store something in it.

    Do not retry

  • 401
    missing_api_keyThe X-API-Key header is missing.

    No X-API-Key header.

    Fix, then retry

  • 401
    missing_api_keyAuthorization: Bearer is not accepted: send the key in the X-API-Key header.

    The key sent as Authorization: Bearer: it goes in X-API-Key.

    Fix, then retry

  • 401
    missing_api_keyThe key goes in the X-API-Key header, not in the URL.

    The key sent in the URL: it goes in X-API-Key.

    Fix, then retry

  • 401
    invalid_api_keyInvalid API key: it is unknown, malformed or revoked.

    The key is unknown, malformed or revoked.

    Fix, then retry

  • 403
    insufficient_creditsThis call evaluates 12 scores, 1 credit each: 12 credits, and 3 are left. Nothing was processed or billed.

    The change evaluates the job's stored scores again, and the credits left do not cover them.

    Fix, then retry

  • 404
    not_foundNo job req-7 in workspace default.

    param: job_id. No job under this id in the workspace.

    Do not retry

  • 413
    payload_too_largeThe request body must be 10 MB or less.

    The body is over 10 MB.

    Fix, then retry

  • 500
    internal_errorInternal error: retry later. If it persists, contact support with the request_id.

    An unexpected error.

    Retry with backoff

  • 502
    internal_errorThe service could not be reached: retry later.

    The service could not be reached.

    Retry with backoff

  • 503
    internal_errorThe credit service is briefly unavailable: retry in a second.

    The credit service is briefly unavailable. Header Retry-After: <seconds>.

    Retry with backoff

  • 504
    internal_errorThe service did not answer in time. The change may still be applied: read it before sending it again.

    No answer in time.

    Retry with backoff

# Example ids: replace job_30cfa454c97663f3e1801e5a61b87d74 with a job_id returned by POST /api/v4/jobs/extract-criteria.
curl -X POST https://hirelayer.co/api/v4/jobs/job_30cfa454c97663f3e1801e5a61b87d74/criteria \
  -H "X-API-Key: $HIRELAYER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "Terraform",
    "type": "skill",
    "requirement": "preferred",
    "weight": 2
  }'
{
  "error": {
    "code": "invalid_request",
    "message": "label is required.",
    "param": "label",
    "doc_url": "https://hirelayer.co/api-docs/errors#invalid_request"
  },
  "request_id": "6f1c2a4e-1d2b-4c3a-9e8f-0a1b2c3d4e5f"
}
PATCH/api/v4/jobs/{job_id}/criteria/{criterion_id}

A new weight, requirement or type re-ranks at once, for free; weight 0 turns the criterion off. A new label or threshold evaluates the criterion again on the job's stored scores, 1 credit each, and sets their verdict to null until their next full evaluation.

In a workspace without storage, refused (400 storage_required), as POST /jobs/{job_id}/criteria is; removing a criterion stays allowed.

Authentication
X-API-Key header
Billing
Free for weight, requirement and type; 1 credit per stored score for label or threshold
Client timeout
Client timeout ≥ 150 s

Path parameters

  • job_idstringrequired

    Letters, digits and . _ : ~ -, up to 200 characters.

  • criterion_idstringrequired

Headers

  • HireLayer-Workspacestring

    Your customer's workspace id. Case-insensitive, created on first use. Absent, calls use default.

Request body

Content type application/json

  • labelstring

    1–300 characters

  • typestring
    "skill""experience""education""language""certification""location""soft_skill""other"
  • requirementstring

    required: a resume that clearly lacks it loses 25 % of its score, never eliminated outright. preferred and bonus count only through their weight.

    "required""preferred""bonus"
  • weightinteger

    Importance. 3 essential, 2 important, 1 nice to have, 0 off: kept on the job, left out of every score, of the required-criterion penalty, of required_missing and of to_verify. Texts already written (summary, explanation) stay as they are.

    0–3

  • thresholdstring | null

    ≤ 100 characters

Response

200Changed.

  • criterion_idstring

    Stable id in the job, such as crit_2. Never reused.

  • labelstring
  • typestring
    "skill""experience""education""language""certification""location""soft_skill""other"
  • requirementstring

    required: a resume that clearly lacks it loses 25 % of its score, never eliminated outright. preferred and bonus count only through their weight.

    "required""preferred""bonus"
  • weightinteger

    Importance. 3 essential, 2 important, 1 nice to have, 0 off: kept on the job, left out of every score, of the required-criterion penalty, of required_missing and of to_verify. Texts already written (summary, explanation) stay as they are.

    0–3

  • thresholdstring | null
  • sourcestring

    extracted by HireLayer, or custom: sent or edited by you.

    "extracted""custom"

Errors

  • 400
    invalid_requestSend at least one field to change.

    An empty body.

    Fix, then retry

  • 400
    invalid_requestweight must be 0, 1, 2 or 3.

    param: weight. A criterion breaks a rule (here its weight): param names the field.

    Fix, then retry

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

    param: criterion_id. criterion_id in the path is not a valid id.

    Fix, then retry

  • 400
    invalid_requestUnknown field name.

    param: name. A field the call does not take.

    Fix, then retry

  • 400
    invalid_requestThe request body is not valid JSON.

    The body is not valid JSON, not an object, or not sent as application/json.

    Fix, then retry

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

    param: HireLayer-Workspace. HireLayer-Workspace is not a valid id.

    Fix, then retry

  • 400
    storage_requiredThis workspace runs without storage (do_not_store_data): nothing can be stored in it.

    param: HireLayer-Workspace. The workspace runs without storage, and the call would store something in it.

    Do not retry

  • 401
    missing_api_keyThe X-API-Key header is missing.

    No X-API-Key header.

    Fix, then retry

  • 401
    missing_api_keyAuthorization: Bearer is not accepted: send the key in the X-API-Key header.

    The key sent as Authorization: Bearer: it goes in X-API-Key.

    Fix, then retry

  • 401
    missing_api_keyThe key goes in the X-API-Key header, not in the URL.

    The key sent in the URL: it goes in X-API-Key.

    Fix, then retry

  • 401
    invalid_api_keyInvalid API key: it is unknown, malformed or revoked.

    The key is unknown, malformed or revoked.

    Fix, then retry

  • 403
    insufficient_creditsThis call evaluates 12 scores, 1 credit each: 12 credits, and 3 are left. Nothing was processed or billed.

    The change evaluates the job's stored scores again, and the credits left do not cover them.

    Fix, then retry

  • 404
    not_foundNo job req-7 in workspace default.

    param: job_id. No job under this id in the workspace.

    Do not retry

  • 404
    not_foundNo criterion crit_9 in job req-7.

    param: criterion_id. No such criterion in the job.

    Do not retry

  • 413
    payload_too_largeThe request body must be 10 MB or less.

    The body is over 10 MB.

    Fix, then retry

  • 500
    internal_errorInternal error: retry later. If it persists, contact support with the request_id.

    An unexpected error.

    Retry with backoff

  • 502
    internal_errorThe service could not be reached: retry later.

    The service could not be reached.

    Retry with backoff

  • 503
    internal_errorThe credit service is briefly unavailable: retry in a second.

    The credit service is briefly unavailable. Header Retry-After: <seconds>.

    Retry with backoff

  • 504
    internal_errorThe service did not answer in time. The change may still be applied: read it before sending it again.

    No answer in time.

    Retry with backoff

# Example ids: replace job_30cfa454c97663f3e1801e5a61b87d74 with a job_id returned by POST /api/v4/jobs/extract-criteria.
curl -X PATCH https://hirelayer.co/api/v4/jobs/job_30cfa454c97663f3e1801e5a61b87d74/criteria/crit_7 \
  -H "X-API-Key: $HIRELAYER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "weight": 0
  }'
{
  "error": {
    "code": "invalid_request",
    "message": "Send at least one field to change.",
    "doc_url": "https://hirelayer.co/api-docs/errors#invalid_request"
  },
  "request_id": "6f1c2a4e-1d2b-4c3a-9e8f-0a1b2c3d4e5f"
}
DELETE/api/v4/jobs/{job_id}/criteria/{criterion_id}

The criterion leaves the scores at once, with no new evaluation, and the verdict of the job's scores is null until their next full evaluation. A job keeps at least one criterion. Free.

Authentication
X-API-Key header
Billing
Free
Client timeout
Client timeout ≥ 30 s

Path parameters

  • job_idstringrequired

    Letters, digits and . _ : ~ -, up to 200 characters.

  • criterion_idstringrequired

Headers

  • HireLayer-Workspacestring

    Your customer's workspace id. Case-insensitive, created on first use. Absent, calls use default.

Response

204Removed.

Errors

  • 400
    invalid_requestA job keeps at least one criterion: add the new one before deleting this one.

    The job's last criterion.

    Fix, then retry

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

    param: criterion_id. criterion_id in the path is not a valid id.

    Fix, then retry

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

    param: HireLayer-Workspace. HireLayer-Workspace is not a valid id.

    Fix, then retry

  • 401
    missing_api_keyThe X-API-Key header is missing.

    No X-API-Key header.

    Fix, then retry

  • 401
    missing_api_keyAuthorization: Bearer is not accepted: send the key in the X-API-Key header.

    The key sent as Authorization: Bearer: it goes in X-API-Key.

    Fix, then retry

  • 401
    missing_api_keyThe key goes in the X-API-Key header, not in the URL.

    The key sent in the URL: it goes in X-API-Key.

    Fix, then retry

  • 401
    invalid_api_keyInvalid API key: it is unknown, malformed or revoked.

    The key is unknown, malformed or revoked.

    Fix, then retry

  • 404
    not_foundNo job req-7 in workspace default.

    param: job_id. No job under this id in the workspace.

    Do not retry

  • 404
    not_foundNo criterion crit_9 in job req-7.

    param: criterion_id. No such criterion in the job.

    Do not retry

  • 500
    internal_errorInternal error: retry later. If it persists, contact support with the request_id.

    An unexpected error.

    Retry with backoff

  • 502
    internal_errorThe service could not be reached: retry later.

    The service could not be reached.

    Retry with backoff

  • 503
    internal_errorThe credit service is briefly unavailable: retry in a second.

    The credit service is briefly unavailable. Header Retry-After: <seconds>.

    Retry with backoff

  • 504
    internal_errorThe service did not answer in time. The change may still be applied: read it before sending it again.

    No answer in time.

    Retry with backoff

# Example ids: replace job_30cfa454c97663f3e1801e5a61b87d74 with a job_id returned by POST /api/v4/jobs/extract-criteria.
curl -X DELETE https://hirelayer.co/api/v4/jobs/job_30cfa454c97663f3e1801e5a61b87d74/criteria/crit_7 \
  -H "X-API-Key: $HIRELAYER_API_KEY"
{
  "error": {
    "code": "invalid_request",
    "message": "A job keeps at least one criterion: add the new one before deleting this one.",
    "doc_url": "https://hirelayer.co/api-docs/errors#invalid_request"
  },
  "request_id": "6f1c2a4e-1d2b-4c3a-9e8f-0a1b2c3d4e5f"
}

Read a job’s ranking again as often as needed, with other weights for one view (?weights[crit_3]=0), without evaluating anything again. Detaching a resume deletes its score and keeps the resume.

GET/api/v4/jobs/{job_id}/scores

The stored scores of a job, best first, scored at read time with the priorities of this read. Free. precise_ranking=true costs 1 credit per read: it compares the 10 best of all the job's resumes and adds ranking_reason, and is billed when it ranks at least 2 completed scores (credits_used). It is made again only when those 10, the job's description or the priorities of the read (weights and requirements) change. In a workspace without storage (set after its jobs were stored), it is made again at every read and never kept.

Authentication
X-API-Key header
Billing
Free; 1 with precise_ranking=true
Client timeout
Client timeout ≥ 60 s

Path parameters

  • job_idstringrequired

    Letters, digits and . _ : ~ -, up to 200 characters.

Headers

  • HireLayer-Workspacestring

    Your customer's workspace id. Case-insensitive, created on first use. Absent, calls use default.

Query parameters

  • limitinteger

    Page size.

    1–100 · default 20

  • cursorstring

    The next_cursor of the previous page.

  • weightsobject

    Weights for this read only, by criterion id, such as weights[crit_3]=0. 0 turns a criterion off.

  • requirementsobject

    Requirements for this read only, by criterion id, such as requirements[crit_1]=required.

  • min_scorenumber

    Only scores at least this high.

    0–1

  • includestring

    criteria adds the per-criterion detail to each score.

    "criteria"
  • precise_rankingboolean

    Re-rank the 10 best of all the job's resumes and add ranking_reason. 1 credit.

    default false

  • request_idstring

    Only the resumes of one scoring call, as results_url gives it: all of them from the start, each with its id (yours, or derived from its file or text on receipt), pending until evaluated; the call is done when none is. Ranks then cover that call only, with the precise ranking the call asked for. Only include goes with it: any other parameter of this read (weights, requirements, min_score, precise_ranking, limit, cursor) is refused (400 invalid_request, param naming the first one).

Response

200A page of the ranking.

  • job_idstring
  • weights_usedobject

    The weight of each criterion in this ranking, overrides included.

  • precise_rankingboolean
  • credits_usedinteger

    Credits this call cost.

    ≥ 0

  • dataobject[]
    ›Show 15 child fields
    • rankinteger

      Place in the whole ranking, across pages: by score, except among the 10 best when precise_ranking is on. Pending and failed resumes come last.

      ≥ 1

    • application_idstring | null

      null without storage, and for a resume file that could not be read.

    • referencestring | null

      The reference the resume was sent with. Given back in the answer of POST /resumes/score, its webhook and its results_url; null in a job's stored ranking and in one stored score, which outlive the call.

    • file_namestring | null

      The name of the resume file sent to POST /resumes/score, given back as reference is.

    • evaluation_statusstring
      "completed""pending""failed"
    • staleboolean

      The resume was replaced after this evaluation. The result stays readable, and is evaluated again the next time the resume is sent to POST /resumes/score for this job.

    • scorenumber | null

      Rounded to 2 decimals; null until evaluated.

      0–1

    • verdictstring | nullmay be absent

      The overall judgment of the resume for the job: highly_relevant (shortlist), relevant (worth a call), marginally_relevant (weak), not_relevant (off-topic). Present once the evaluation is completed, absent while pending or failed. It does not follow the weights of a read, so it can disagree with score after a weight change. null when a criterion of the job was added, removed or reworded (label or threshold) since the last full evaluation of the resume, or when no overall judgment could be given. A change of weight, requirement or type leaves it as is. After a reset, it comes back when the resume is sent again to POST /resumes/score for this job: a full evaluation, 1 credit, on top of the credit the new criterion's own evaluation cost.

      "highly_relevant""relevant""marginally_relevant""not_relevant"null
    • summarystring | nullmay be absent

      Overall assessment, in the job's language. Present once the evaluation is completed. It follows verdict, written with it: null when verdict is null (a criterion of the job added, removed or reworded since the last full evaluation of the resume), back with the next full evaluation.

    • ranking_reasonstringmay be absent

      One sentence that places the resume against the others. Only with precise_ranking, for ranks 1 to 10, when at least 2 resumes are compared; absent otherwise.

    • required_missingobject[]

      Required criteria marked missing with medium or high confidence; each multiplies the score by 0.75.

      ›Show 2 child fields
      • criterion_idstring
      • labelstring
    • to_verifyobject[]

      Required criteria not clearly met, to check with the candidate; those of required_missing included.

      ›Show 2 child fields
      • criterion_idstring
      • labelstring
    • criteriaobject[]may be absent

      Per-criterion detail, in the job's criteria order, once the evaluation is completed. Always in POST /resumes/score answers; in GET /jobs/{job_id}/scores, only with include=criteria.

      ›Show 10 child fields
      • criterion_idstring
      • labelstring
      • requirementstring

        required: a resume that clearly lacks it loses 25 % of its score, never eliminated outright. preferred and bonus count only through their weight.

        "required""preferred""bonus"
      • weightinteger

        Importance. 3 essential, 2 important, 1 nice to have, 0 off: kept on the job, left out of every score, of the required-criterion penalty, of required_missing and of to_verify. Texts already written (summary, explanation) stay as they are.

        0–3

      • statusstring

        The reading of the criterion. met; partial; missing, which can still carry a weak hint (score 0.33); unknown: the resume says nothing about something resumes often leave out, such as availability, and the criterion is left out of the score.

        "met""partial""missing""unknown"
      • scorenumber | null

        1 met or exceeded, 0.67 partly met, 0.33 a weak hint, 0 absent, null unknown. The resume's score uses the exact values 2/3 and 1/3, then rounds to 2 decimals.

        00.330.671null
      • gapstring | null

        Why the evidence is partial (scores 0.67 and 0.33): the same thing, less of it; a neighbouring skill of the same trade; plausible but not shown.

        "below_threshold""related""indirect"null
      • confidencestring

        A required criterion missing with low confidence does not lower the score.

        "high""medium""low"
      • evidencestring

        Where the resume shows it: the section, then the passages quoted between quotation marks, in the resume's language. Empty when there is none. Free text, so search the quoted passages rather than the whole string.

      • explanationstring

        One sentence, in the job's language.

    • errorobject | null

      Why this resume failed, when evaluation_status is failed. It was not billed.

      ›Show 4 child fields
      • codestring

        Stable codes: branch on them, never on message. method_not_allowed answers a method a path does not take (405, with an Allow header), outside any operation.

        "invalid_request""storage_required""missing_api_key""invalid_api_key""insufficient_credits""enterprise_plan_required""not_found""payload_too_large""resume_unreadable""job_unreadable""rate_limited""model_unavailable""internal_error""method_not_allowed"
      • messagestring

        Readable explanation, for logs.

      • paramstringmay be absent

        The field or parameter at fault, when there is one, such as job.criteria or resumes[2].file.

      • doc_urlstring (URL)
    • evaluated_atstring (date-time) | null
  • next_cursorstring | null

Errors

  • 400
    invalid_requestweights[crit_3] must be 0, 1, 2 or 3.

    param: weights[crit_3]. A query parameter out of its values (here a weight): param names it.

    Fix, then retry

  • 400
    invalid_requestlimit does not apply with request_id: a Scorer call is read whole, with include only.

    param: limit. A parameter other than include with request_id.

    Fix, then retry

  • 400
    invalid_requestlimit must be an integer from 1 to 100.

    param: limit. limit out of range.

    Fix, then retry

  • 400
    invalid_requestcursor is not a next_cursor returned by this API.

    param: cursor. cursor is not a next_cursor of this list.

    Fix, then retry

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

    param: job_id. job_id in the path is not a valid id.

    Fix, then retry

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

    param: HireLayer-Workspace. HireLayer-Workspace is not a valid id.

    Fix, then retry

  • 401
    missing_api_keyThe X-API-Key header is missing.

    No X-API-Key header.

    Fix, then retry

  • 401
    missing_api_keyAuthorization: Bearer is not accepted: send the key in the X-API-Key header.

    The key sent as Authorization: Bearer: it goes in X-API-Key.

    Fix, then retry

  • 401
    missing_api_keyThe key goes in the X-API-Key header, not in the URL.

    The key sent in the URL: it goes in X-API-Key.

    Fix, then retry

  • 401
    invalid_api_keyInvalid API key: it is unknown, malformed or revoked.

    The key is unknown, malformed or revoked.

    Fix, then retry

  • 403
    insufficient_creditsThis call needs 1 credit and none is left. Nothing was processed or billed.

    No credit left for the precise ranking.

    Fix, then retry

  • 404
    not_foundNo job req-7 in workspace default.

    param: job_id. No job under this id in the workspace.

    Do not retry

  • 404
    not_foundNo Scorer call 5d0a3c1e-2f4b-4c8e-9a61-0b7e2d9f4c13 for job req-7.

    param: request_id. No Scorer call under request_id for this job (kept 30 days).

    Do not retry

  • 500
    internal_errorInternal error: retry later. If it persists, contact support with the request_id.

    An unexpected error.

    Retry with backoff

  • 502
    internal_errorThe service could not be reached: retry later.

    The service could not be reached.

    Retry with backoff

  • 503
    internal_errorThe credit service is briefly unavailable: retry in a second.

    The credit service is briefly unavailable. Header Retry-After: <seconds>.

    Retry with backoff

  • 504
    internal_errorThe service did not answer in time. The change may still be applied: read it before sending it again.

    No answer in time.

    Retry with backoff

# Example ids: replace job_30cfa454c97663f3e1801e5a61b87d74 with a job_id returned by POST /api/v4/jobs/extract-criteria.
curl -g "https://hirelayer.co/api/v4/jobs/job_30cfa454c97663f3e1801e5a61b87d74/scores?weights[crit_3]=0" \
  -H "X-API-Key: $HIRELAYER_API_KEY"
{
  "job_id": "job_30cfa454c97663f3e1801e5a61b87d74",
  "weights_used": {
    "crit_1": 3,
    "crit_2": 3,
    "crit_3": 2,
    "crit_4": 2,
    "crit_5": 2,
    "crit_6": 1,
    "crit_7": 1,
    "crit_8": 1
  },
  "precise_ranking": false,
  "credits_used": 0,
  "data": [
    {
      "rank": 1,
      "application_id": "file_2c982f413a5e9e79563f8a1fcb5c7caa",
      "reference": null,
      "file_name": null,
      "evaluation_status": "completed",
      "stale": false,
      "score": 0.9,
      "verdict": "highly_relevant",
      "summary": "Candidat très pertinent avec une expertise forte en LLM et AWS, un excellent niveau d'anglais, à présélectionner malgré une expérience en Node.js légèrement sous le seuil.",
      "required_missing": [],
      "to_verify": [
        {
          "criterion_id": "crit_8",
          "label": "Astreinte"
        }
      ],
      "error": null,
      "evaluated_at": "2026-10-26T22:39:25Z"
    },
    {
      "rank": 2,
      "application_id": "file_addd6bc79e818deebe289d009058d6b1",
      "reference": null,
      "file_name": null,
      "evaluation_status": "completed",
      "stale": false,
      "score": 0.25,
      "verdict": "marginally_relevant",
      "summary": "Candidat exclusivement frontend (React/TypeScript) sans expérience backend Node.js ni intégration de LLM, deux critères essentiels non satisfaits.",
      "required_missing": [
        {
          "criterion_id": "crit_2",
          "label": "Intégration de LLM en production"
        }
      ],
      "to_verify": [
        {
          "criterion_id": "crit_2",
          "label": "Intégration de LLM en production"
        },
        {
          "criterion_id": "crit_8",
          "label": "Astreinte"
        }
      ],
      "error": null,
      "evaluated_at": "2026-10-26T22:40:51Z"
    }
  ],
  "next_cursor": null
}
GET/api/v4/jobs/{job_id}/scores/{application_id}

One resume's score for a job, criterion by criterion, with the priorities of this read. Free.

Authentication
X-API-Key header
Billing
Free
Client timeout
Client timeout ≥ 30 s

Path parameters

  • job_idstringrequired

    Letters, digits and . _ : ~ -, up to 200 characters.

  • application_idstringrequired

    The resume's id, including one returned by the legacy /api/v3/parser in info_resume.application_id.

Headers

  • HireLayer-Workspacestring

    Your customer's workspace id. Case-insensitive, created on first use. Absent, calls use default.

Query parameters

  • weightsobject

    Weights for this read only, by criterion id, such as weights[crit_3]=0. 0 turns a criterion off.

  • requirementsobject

    Requirements for this read only, by criterion id, such as requirements[crit_1]=required.

Response

200The score.

  • rankinteger

    Place in the whole ranking, across pages: by score, except among the 10 best when precise_ranking is on. Pending and failed resumes come last.

    ≥ 1

  • application_idstring | null

    null without storage, and for a resume file that could not be read.

  • referencestring | null

    The reference the resume was sent with. Given back in the answer of POST /resumes/score, its webhook and its results_url; null in a job's stored ranking and in one stored score, which outlive the call.

  • file_namestring | null

    The name of the resume file sent to POST /resumes/score, given back as reference is.

  • evaluation_statusstring
    "completed""pending""failed"
  • staleboolean

    The resume was replaced after this evaluation. The result stays readable, and is evaluated again the next time the resume is sent to POST /resumes/score for this job.

  • scorenumber | null

    Rounded to 2 decimals; null until evaluated.

    0–1

  • verdictstring | nullmay be absent

    The overall judgment of the resume for the job: highly_relevant (shortlist), relevant (worth a call), marginally_relevant (weak), not_relevant (off-topic). Present once the evaluation is completed, absent while pending or failed. It does not follow the weights of a read, so it can disagree with score after a weight change. null when a criterion of the job was added, removed or reworded (label or threshold) since the last full evaluation of the resume, or when no overall judgment could be given. A change of weight, requirement or type leaves it as is. After a reset, it comes back when the resume is sent again to POST /resumes/score for this job: a full evaluation, 1 credit, on top of the credit the new criterion's own evaluation cost.

    "highly_relevant""relevant""marginally_relevant""not_relevant"null
  • summarystring | nullmay be absent

    Overall assessment, in the job's language. Present once the evaluation is completed. It follows verdict, written with it: null when verdict is null (a criterion of the job added, removed or reworded since the last full evaluation of the resume), back with the next full evaluation.

  • ranking_reasonstringmay be absent

    One sentence that places the resume against the others. Only with precise_ranking, for ranks 1 to 10, when at least 2 resumes are compared; absent otherwise.

  • required_missingobject[]

    Required criteria marked missing with medium or high confidence; each multiplies the score by 0.75.

    ›Show 2 child fields
    • criterion_idstring
    • labelstring
  • to_verifyobject[]

    Required criteria not clearly met, to check with the candidate; those of required_missing included.

    ›Show 2 child fields
    • criterion_idstring
    • labelstring
  • criteriaobject[]may be absent

    Per-criterion detail, in the job's criteria order, once the evaluation is completed. Always in POST /resumes/score answers; in GET /jobs/{job_id}/scores, only with include=criteria.

    ›Show 10 child fields
    • criterion_idstring
    • labelstring
    • requirementstring

      required: a resume that clearly lacks it loses 25 % of its score, never eliminated outright. preferred and bonus count only through their weight.

      "required""preferred""bonus"
    • weightinteger

      Importance. 3 essential, 2 important, 1 nice to have, 0 off: kept on the job, left out of every score, of the required-criterion penalty, of required_missing and of to_verify. Texts already written (summary, explanation) stay as they are.

      0–3

    • statusstring

      The reading of the criterion. met; partial; missing, which can still carry a weak hint (score 0.33); unknown: the resume says nothing about something resumes often leave out, such as availability, and the criterion is left out of the score.

      "met""partial""missing""unknown"
    • scorenumber | null

      1 met or exceeded, 0.67 partly met, 0.33 a weak hint, 0 absent, null unknown. The resume's score uses the exact values 2/3 and 1/3, then rounds to 2 decimals.

      00.330.671null
    • gapstring | null

      Why the evidence is partial (scores 0.67 and 0.33): the same thing, less of it; a neighbouring skill of the same trade; plausible but not shown.

      "below_threshold""related""indirect"null
    • confidencestring

      A required criterion missing with low confidence does not lower the score.

      "high""medium""low"
    • evidencestring

      Where the resume shows it: the section, then the passages quoted between quotation marks, in the resume's language. Empty when there is none. Free text, so search the quoted passages rather than the whole string.

    • explanationstring

      One sentence, in the job's language.

  • errorobject | null

    Why this resume failed, when evaluation_status is failed. It was not billed.

    ›Show 4 child fields
    • codestring

      Stable codes: branch on them, never on message. method_not_allowed answers a method a path does not take (405, with an Allow header), outside any operation.

      "invalid_request""storage_required""missing_api_key""invalid_api_key""insufficient_credits""enterprise_plan_required""not_found""payload_too_large""resume_unreadable""job_unreadable""rate_limited""model_unavailable""internal_error""method_not_allowed"
    • messagestring

      Readable explanation, for logs.

    • paramstringmay be absent

      The field or parameter at fault, when there is one, such as job.criteria or resumes[2].file.

    • doc_urlstring (URL)
  • evaluated_atstring (date-time) | null

Errors

  • 400
    invalid_requestweights[crit_3] must be 0, 1, 2 or 3.

    param: weights[crit_3]. A query parameter out of its values (here a weight): param names it.

    Fix, then retry

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

    param: application_id. application_id in the path is not a valid id.

    Fix, then retry

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

    param: HireLayer-Workspace. HireLayer-Workspace is not a valid id.

    Fix, then retry

  • 401
    missing_api_keyThe X-API-Key header is missing.

    No X-API-Key header.

    Fix, then retry

  • 401
    missing_api_keyAuthorization: Bearer is not accepted: send the key in the X-API-Key header.

    The key sent as Authorization: Bearer: it goes in X-API-Key.

    Fix, then retry

  • 401
    missing_api_keyThe key goes in the X-API-Key header, not in the URL.

    The key sent in the URL: it goes in X-API-Key.

    Fix, then retry

  • 401
    invalid_api_keyInvalid API key: it is unknown, malformed or revoked.

    The key is unknown, malformed or revoked.

    Fix, then retry

  • 404
    not_foundNo job req-7 in workspace default.

    param: job_id. No job under this id in the workspace.

    Do not retry

  • 404
    not_foundNo score of resume cand-42 for job req-7 in workspace default.

    param: application_id. The resume has no score for this job.

    Do not retry

  • 500
    internal_errorInternal error: retry later. If it persists, contact support with the request_id.

    An unexpected error.

    Retry with backoff

  • 502
    internal_errorThe service could not be reached: retry later.

    The service could not be reached.

    Retry with backoff

  • 503
    internal_errorThe credit service is briefly unavailable: retry in a second.

    The credit service is briefly unavailable. Header Retry-After: <seconds>.

    Retry with backoff

  • 504
    internal_errorThe service did not answer in time. The change may still be applied: read it before sending it again.

    No answer in time.

    Retry with backoff

# Example ids: replace job_30cfa454c97663f3e1801e5a61b87d74 with a job_id returned by POST /api/v4/jobs/extract-criteria, and file_2c982f413a5e9e79563f8a1fcb5c7caa with an application_id returned by POST /api/v4/resumes/parse.
curl https://hirelayer.co/api/v4/jobs/job_30cfa454c97663f3e1801e5a61b87d74/scores/file_2c982f413a5e9e79563f8a1fcb5c7caa \
  -H "X-API-Key: $HIRELAYER_API_KEY"
{
  "error": {
    "code": "invalid_request",
    "message": "weights[crit_3] must be 0, 1, 2 or 3.",
    "param": "weights[crit_3]",
    "doc_url": "https://hirelayer.co/api-docs/errors#invalid_request"
  },
  "request_id": "6f1c2a4e-1d2b-4c3a-9e8f-0a1b2c3d4e5f"
}
DELETE/api/v4/jobs/{job_id}/scores/{application_id}

Deletes the score. The resume stays in the workspace. Free.

Authentication
X-API-Key header
Billing
Free
Client timeout
Client timeout ≥ 30 s

Path parameters

  • job_idstringrequired

    Letters, digits and . _ : ~ -, up to 200 characters.

  • application_idstringrequired

    The resume's id, including one returned by the legacy /api/v3/parser in info_resume.application_id.

Headers

  • HireLayer-Workspacestring

    Your customer's workspace id. Case-insensitive, created on first use. Absent, calls use default.

Response

204Deleted.

Errors

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

    param: application_id. application_id in the path is not a valid id.

    Fix, then retry

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

    param: HireLayer-Workspace. HireLayer-Workspace is not a valid id.

    Fix, then retry

  • 401
    missing_api_keyThe X-API-Key header is missing.

    No X-API-Key header.

    Fix, then retry

  • 401
    missing_api_keyAuthorization: Bearer is not accepted: send the key in the X-API-Key header.

    The key sent as Authorization: Bearer: it goes in X-API-Key.

    Fix, then retry

  • 401
    missing_api_keyThe key goes in the X-API-Key header, not in the URL.

    The key sent in the URL: it goes in X-API-Key.

    Fix, then retry

  • 401
    invalid_api_keyInvalid API key: it is unknown, malformed or revoked.

    The key is unknown, malformed or revoked.

    Fix, then retry

  • 500
    internal_errorInternal error: retry later. If it persists, contact support with the request_id.

    An unexpected error.

    Retry with backoff

  • 502
    internal_errorThe service could not be reached: retry later.

    The service could not be reached.

    Retry with backoff

  • 503
    internal_errorThe credit service is briefly unavailable: retry in a second.

    The credit service is briefly unavailable. Header Retry-After: <seconds>.

    Retry with backoff

  • 504
    internal_errorThe service did not answer in time. The change may still be applied: read it before sending it again.

    No answer in time.

    Retry with backoff

# Example ids: replace job_30cfa454c97663f3e1801e5a61b87d74 with a job_id returned by POST /api/v4/jobs/extract-criteria, and file_2c982f413a5e9e79563f8a1fcb5c7caa with an application_id returned by POST /api/v4/resumes/parse.
curl -X DELETE https://hirelayer.co/api/v4/jobs/job_30cfa454c97663f3e1801e5a61b87d74/scores/file_2c982f413a5e9e79563f8a1fcb5c7caa \
  -H "X-API-Key: $HIRELAYER_API_KEY"
{
  "error": {
    "code": "invalid_request",
    "message": "application_id must contain letters, digits and . _ : ~ -, up to 200 characters.",
    "param": "application_id",
    "doc_url": "https://hirelayer.co/api-docs/errors#invalid_request"
  },
  "request_id": "6f1c2a4e-1d2b-4c3a-9e8f-0a1b2c3d4e5f"
}