Products
HireLayer Job Recommendations
Find the open jobs closest to a resume, sent as a stored id, a text or a file, in one call.
HireLayer Job Recommendations finds the open jobs of a workspace closest to a resume. One POST /api/v4/jobs/search call with a stored application_id, a resume text or a resume file returns up to 100 job_ids sorted by closeness, with a similarity each, for 1 credit per search (+1 when the resume comes as a file, parsed and stored).
Only jobs stored with status: "open" are searched. To explain a recommendation, score the resume against that job with the Resume Scorer, one call per job.
- Endpoint
POST /api/v4/jobs/search- Input
- An
application_id, a resume text or a resume file - Output
- Job ids, closest first
- Price
- 1 credit per search, +1 for a resume file
/api/v4/jobs/searchFinds the open stored jobs of the workspace closest to a resume. Proximity only: no evaluation, no explanation. Score the chosen ones with POST /resumes/score, one call per job.
- Authentication
X-API-Keyheader- Billing
- 1 credit per search, +1 for a resume file
- Client timeout
- Client timeout ≥ 60 s
Headers
HireLayer-WorkspacestringYour customer's workspace id. Case-insensitive, created on first use. Absent, calls use
default.
Request body
Content type application/json, or multipart/form-data with files
Send exactly one of application_id or resume.
application_idstringLetters, digits and
. _ : ~ -, up to 200 characters.resumeobjectA resume not stored yet; it is stored under your id, or a
text_id.›Show 2 child fieldsHide child fields
textstringrequired1–50,000 characters
application_idstringStore the resume under your own id.
limitinteger1–100 · default
10do_not_store_databooleanEnterprise plan only, else
403 enterprise_plan_required: process without storing anything. See Storage.default
false
Response
200The closest open jobs, closest first.
request_idstringThe call's id, also in the
HireLayer-Request-Idheader. Quote it when contacting support.application_idstringresultsobject[]›Show 5 child fieldsHide child fields
rankinteger≥ 1
job_idstringtitlestring | nullsimilaritynumber0–1
already_scoredbooleanThe resume is already scored for this job, or being scored (
pending); scoring it again costs 0 unless the score isstaleor itsverdictwas reset.
credits_usedintegerCredits this call cost.
≥ 0
Errors
- 400invalid_requestapplication_id or resume is required.
param:application_id. Neitherapplication_idnorresume, or both.Fix, then retry
- 400
- 400invalid_requestfile is required: send the resume in the multipart part file.
param:file. In multipart, no partfile.Fix, then retry
- 400invalid_requestlimit must be an integer from 1 to 100.
param:limit.limitout of range.Fix, then retry
- 400invalid_requestapplication_id must contain letters, digits and . _ : ~ -, up to 200 characters.
param:application_id.application_idis not a valid id, or is a name the paths reserve.Fix, then retry
- 400
- 400invalid_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
- 400invalid_requestHireLayer-Workspace must contain letters, digits and . _ : ~ -, up to 200 characters.
param:HireLayer-Workspace.HireLayer-Workspaceis not a valid id.Fix, then retry
- 400storage_requiredA search reads the stored resumes and jobs: it is not available without storage.
param:do_not_store_data.do_not_store_data: true(Enterprise plan): a search needs storage.Do not retry
- 400storage_requiredThis workspace runs without storage (do_not_store_data): a search reads the stored resumes and jobs, so it is not available in it.
param:HireLayer-Workspace. The workspace runs without storage.Do not retry
- 401
- 401missing_api_keyAuthorization: Bearer is not accepted: send the key in the X-API-Key header.
The key sent as
Authorization: Bearer: it goes inX-API-Key.Fix, then retry
- 401missing_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
- 401invalid_api_keyInvalid API key: it is unknown, malformed or revoked.
The key is unknown, malformed or revoked.
Fix, then retry
- 403insufficient_creditsThis search parses 1 file and searches, 1 credit each: 2 credits, and 1 is left. Nothing was processed or billed.
The credits left do not cover the search (and the parse of a file).
Fix, then retry
- 403enterprise_plan_requireddo_not_store_data is available on the Enterprise plan only. Nothing was processed or billed.
param:do_not_store_data.do_not_store_data: truebelow the Enterprise plan.Do not retry
- 404not_foundNo resume cand-42 in workspace default.
param:application_id. No resume underapplication_idin the workspace.Do not retry
- 413
- 413payload_too_largeresume.text must be 50,000 characters or less.
param:resume.text. The resume text is over 50,000 characters.Fix, then retry
- 422resume_unreadablefile cannot be read as a resume: it is empty, damaged or in an unsupported format. Nothing was billed.
param:file. The file cannot be read as a resume.Do not retry
- 429rate_limitedToo many files are being parsed at once for this account: retry after the Retry-After delay.
Too many parses at once. Header
Retry-After: <seconds>.Retry with backoff
- 500internal_errorInternal error: retry later. If it persists, contact support with the request_id.
An unexpected error.
Retry with backoff
- 502model_unavailableThe analysis did not complete after several attempts. Nothing was stored or billed: retry with backoff.
The analysis did not complete.
Retry with backoff
- 502internal_errorThe service could not be reached: retry later.
The service could not be reached.
Retry with backoff
- 503internal_errorThe credit service is briefly unavailable: retry in a second.
The credit service is briefly unavailable. Header
Retry-After: <seconds>.Retry with backoff
- 503internal_errorThe resume was parsed but could not be stored, so there is nothing to search with: retry in a few seconds.
param:file. The resume file was parsed but could not be stored yet. HeaderRetry-After: <seconds>.Retry with backoff
- 504internal_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
- Credits
- 1 per search, +1 when the resume comes as a file (parsed and stored).
- Without storage
- not available (
400 storage_required), since there are no stored jobs.
# Example ids: replace file_2c982f413a5e9e79563f8a1fcb5c7caa with an application_id returned by POST /api/v4/resumes/parse.
curl -X POST https://hirelayer.co/api/v4/jobs/search \
-H "X-API-Key: $HIRELAYER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"application_id": "file_2c982f413a5e9e79563f8a1fcb5c7caa",
"limit": 10
}'# Example ids: replace file_2c982f413a5e9e79563f8a1fcb5c7caa with an application_id returned by POST /api/v4/resumes/parse.
import os
import requests
response = requests.post(
"https://hirelayer.co/api/v4/jobs/search",
headers={"X-API-Key": os.environ["HIRELAYER_API_KEY"]},
json={
"application_id": "file_2c982f413a5e9e79563f8a1fcb5c7caa",
"limit": 10,
},
timeout=60,
)
response.raise_for_status()
data = response.json()
print(data["results"])// Example ids: replace file_2c982f413a5e9e79563f8a1fcb5c7caa with an application_id returned by POST /api/v4/resumes/parse.
const response = await fetch('https://hirelayer.co/api/v4/jobs/search', {
method: 'POST',
headers: {
'X-API-Key': process.env.HIRELAYER_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({
application_id: 'file_2c982f413a5e9e79563f8a1fcb5c7caa',
limit: 10,
}),
signal: AbortSignal.timeout(60_000),
})
if (!response.ok) {
throw new Error(`HireLayer ${response.status}: ${await response.text()}`)
}
const data = await response.json()
console.log(data.results){
"request_id": "9d3f5a20-1c6e-4b78-a2f4-3e8b7c1d0f69",
"application_id": "file_2c982f413a5e9e79563f8a1fcb5c7caa",
"results": [
{
"rank": 1,
"job_id": "job_30cfa454c97663f3e1801e5a61b87d74",
"title": "Ingénieur IA / Développeur backend Node.js (H/F)",
"similarity": 0.78,
"already_scored": true
},
{
"rank": 2,
"job_id": "senior-ds-nlp",
"title": "Senior Data Scientist – NLP (m/f)",
"similarity": 0.74,
"already_scored": false
}
],
"credits_used": 1
}{
"error": {
"code": "invalid_request",
"message": "application_id or resume is required.",
"param": "application_id",
"doc_url": "https://hirelayer.co/api-docs/errors#invalid_request"
},
"request_id": "6f1c2a4e-1d2b-4c3a-9e8f-0a1b2c3d4e5f"
}From a resume file. Send the resume as a file in the multipart field file: it is parsed and stored first, +1 credit.
curl -X POST https://hirelayer.co/api/v4/jobs/search \
-H "X-API-Key: $HIRELAYER_API_KEY" \
-F "file=@resume.pdf;type=application/pdf"import os
import requests
with open("resume.pdf", "rb") as file:
response = requests.post(
"https://hirelayer.co/api/v4/jobs/search",
headers={"X-API-Key": os.environ["HIRELAYER_API_KEY"]},
files={"file": ("resume.pdf", file, "application/pdf")},
timeout=150,
)
response.raise_for_status()
data = response.json()
print(data["results"])import { readFile } from 'node:fs/promises'
const form = new FormData()
form.append(
'file',
new Blob([await readFile('resume.pdf')], { type: 'application/pdf' }),
'resume.pdf'
)
const response = await fetch('https://hirelayer.co/api/v4/jobs/search', {
method: 'POST',
headers: {
'X-API-Key': process.env.HIRELAYER_API_KEY!,
},
body: form,
signal: AbortSignal.timeout(150_000),
})
if (!response.ok) {
throw new Error(`HireLayer ${response.status}: ${await response.text()}`)
}
const data = await response.json()
console.log(data.results){
"request_id": "9d3f5a20-1c6e-4b78-a2f4-3e8b7c1d0f69",
"application_id": "file_2c982f413a5e9e79563f8a1fcb5c7caa",
"results": [
{
"rank": 1,
"job_id": "job_30cfa454c97663f3e1801e5a61b87d74",
"title": "Ingénieur IA / Développeur backend Node.js (H/F)",
"similarity": 0.78,
"already_scored": true
},
{
"rank": 2,
"job_id": "senior-ds-nlp",
"title": "Senior Data Scientist – NLP (m/f)",
"similarity": 0.74,
"already_scored": false
}
],
"credits_used": 1
}