Products
HireLayer Talent Pool Search
Find the resumes closest to a job in your resume database, filtered by location and date added, in one call.
HireLayer Talent Pool Search finds, in the resume database of a workspace, the resumes closest to a job: every resume parsed or scored there is searchable. One POST /api/v4/resumes/search call with a stored job_id or a job text returns up to 500 application_ids sorted by closeness, with a similarity and whether each one is already scored for the job, for 1 credit per search. A job whose text replaces a stored job (same job_id) has its stored scores evaluated again, 1 credit each, and the search is refused (403) when the credits left do not cover them. A job text identical to the stored job returns the job as stored: a title sent with it is ignored; change it with PUT /jobs/{job_id}. Filter by location (a city and a radius) and by date added.
The search does not evaluate or explain: send the resumes you choose to the Resume Scorer by their application_id. Those already scored for the job, or being scored, cost nothing, unless their score is stale or its verdict was reset.
- Endpoint
POST /api/v4/resumes/search- Input
- A
job_idor a job text, alimit, optional filters - Output
- Resume ids, closest first
- Price
- 1 credit per search; 1 credit per stored score evaluated again when a new text replaces a stored job
/api/v4/resumes/searchFinds in the workspace's resume database the resumes closest to a job, to choose which ones to score. Proximity only: no evaluation, no explanation. Score the chosen ones with POST /resumes/score.
- Authentication
X-API-Keyheader- Billing
- 1 credit per search; 1 credit per stored score evaluated again when a new text replaces a stored job
- 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
Send exactly one of job_id or job.
job_idstringLetters, digits and
. _ : ~ -, up to 200 characters.jobobjectA job not stored yet; it is stored, as by
POST /jobs/extract-criteria.›Show 3 child fieldsHide child fields
textstringrequired1–50,000 characters
titlestring≤ 300 characters
job_idstringStore the job under your own id.
limitinteger1–500 · default
50filtersobject›Show 2 child fieldsHide child fields
locationobjectResumes whose location is unknown are left out when this filter is set.
›Show 3 child fieldsHide child fields
citystringrequiredcountry_codestringISO 3166-1 alpha-2, such as
FR. Helps when a city name exists in several countries.radius_kminteger1–500 · default
30
added_afterstring (date-time)
do_not_store_databooleanEnterprise plan only, else
403 enterprise_plan_required: process without storing anything. See Storage.default
false
Response
200The closest resumes, closest first.
request_idstringThe call's id, also in the
HireLayer-Request-Idheader. Quote it when contacting support.job_idstringresultsobject[]›Show 4 child fieldsHide child fields
rankinteger≥ 1
application_idstringsimilaritynumberProximity to the job. Compare it only within one search; it is not a score.
0–1
already_scoredbooleanAlready 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_requestjob_id or job is required.
param:job_id. Neitherjob_idnorjob, or both.Fix, then retry
- 400
- 400invalid_requestlimit must be an integer from 1 to 500.
param:limit.limitout of range.Fix, then retry
- 400invalid_requestNo city named Lyonn: check the spelling, or add country_code.
param:filters.location.city. A filter breaks a rule (here a city not found):paramnames it.Fix, then retry
- 400invalid_requestjob_id must contain letters, digits and . _ : ~ -, up to 200 characters.
param:job_id.job_idis not a valid id.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 needs 1 credit and none is left. Nothing was processed or billed.
No credit left for the search (and for the stored scores a new job text evaluates again).
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 job req-7 in workspace default.
param:job_id. No job underjob_idin the workspace.Do not retry
- 413payload_too_largejob.text must be 50,000 characters or less.
param:job.text. The job text is over 50,000 characters.Fix, then retry
- 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 location filter is briefly unavailable: search without it, or retry later.
param:filters.location. The location filter is briefly unavailable. 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. A
jobwhose text replaces a stored job (samejob_id) has its criteria extracted again, asPOST /jobs/extract-criteriadoes: its stored scores are evaluated again in the background, 1 credit each, and the call is refused (403) when the credits left do not cover them and the search. That check asks for the worst case, every stored score of the job evaluated again; only the evaluations that actually run are billed. - A stored job sent again
- a
jobwhose text is the stored job's is used as it is, and itstitleis then ignored: change it withPUT /jobs/{job_id}. - Without storage
- not available (
400 storage_required), since there is no resume database.
# 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/resumes/search \
-H "X-API-Key: $HIRELAYER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"job_id": "job_30cfa454c97663f3e1801e5a61b87d74",
"limit": 20,
"filters": {
"location": {
"city": "Paris",
"radius_km": 30
}
}
}'# Example ids: replace job_30cfa454c97663f3e1801e5a61b87d74 with a job_id returned by POST /api/v4/jobs/extract-criteria.
import os
import requests
response = requests.post(
"https://hirelayer.co/api/v4/resumes/search",
headers={"X-API-Key": os.environ["HIRELAYER_API_KEY"]},
json={
"job_id": "job_30cfa454c97663f3e1801e5a61b87d74",
"limit": 20,
"filters": {
"location": {
"city": "Paris",
"radius_km": 30,
},
},
},
timeout=60,
)
response.raise_for_status()
data = response.json()
print(data["results"])// Example ids: replace job_30cfa454c97663f3e1801e5a61b87d74 with a job_id returned by POST /api/v4/jobs/extract-criteria.
const response = await fetch('https://hirelayer.co/api/v4/resumes/search', {
method: 'POST',
headers: {
'X-API-Key': process.env.HIRELAYER_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({
job_id: 'job_30cfa454c97663f3e1801e5a61b87d74',
limit: 20,
filters: {
location: {
city: 'Paris',
radius_km: 30,
},
},
}),
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": "2b8e6d14-7a3c-4f91-8e25-6c0d9b3f1a47",
"job_id": "job_30cfa454c97663f3e1801e5a61b87d74",
"results": [
{
"rank": 1,
"application_id": "file_2c982f413a5e9e79563f8a1fcb5c7caa",
"similarity": 0.81,
"already_scored": true
},
{
"rank": 2,
"application_id": "cand-1042",
"similarity": 0.77,
"already_scored": false
}
],
"credits_used": 1
}{
"error": {
"code": "invalid_request",
"message": "job_id or job is required.",
"param": "job_id",
"doc_url": "https://hirelayer.co/api-docs/errors#invalid_request"
},
"request_id": "6f1c2a4e-1d2b-4c3a-9e8f-0a1b2c3d4e5f"
}