Zoho Recruit integration · Workflow webhook + API v2
Screen Zoho Recruit candidates with HireLayer
Zoho Recruit parses resumes and can call any URL from a workflow rule, so a new candidate can start your own screening service without a marketplace extension. HireLayer scores each candidate against the job opening with an explanation per criterion, and your service writes the score, a note, tags and normalized skills back through the Recruit API.
- Trigger
- Workflow rule with a webhook action
- Zoho Recruit API
- REST API v2, OAuth 2.0 Self Client
- Write-back
- Notes, tags, Skill_Set, Educational_Details
- Cost
- 2 credits per candidate, plus 1 per job opening
- 1A candidate is addedZoho RecruitA workflow rule on the Candidates module calls your webhook with the candidate’s record ID and a secret you chose.
- 2Parse the resumeHireLayerYour service lists the candidate’s attachments, downloads the latest with /Candidates/{id}/Attachments/{attachment_id} and sends it to HireLayer CV Extract.
- 3Score against the job openingHireLayerThe service finds the associated opening with /Candidates/{id}/associate, and HireLayer Match scores the resume against that opening’s criteria.
- 4Write back to Zoho RecruitZoho RecruitA note with the score and the gaps, a tag for strong matches, and normalized skills in Skill_Set.
Use cases
What teams do with HireLayer and Zoho Recruit
Screen new applicants
Every candidate associated with an opening gets a score and the list of mandatory criteria met, in a note your recruiters read on the recrod.
Rank an opening’s pipeline
List the candidates of a job opening with GET /Job_Openings/{id}/associate, send up to 10 resume texts per call to HireLayer Rank, and note each candidate’s rank and rationale.
Normalized skills
Write HireLayer’s normalized skills to Skill_Set, so a search in Recruit finds the same skill under one nane across candidates.
Complete manual records
Candidates added by hand or through Insert Records may have empty education and experiance tables. Fill Educational_Details and Experience_Details from HireLayer’s parse.
Setup
Connect Zoho Recruit to HireLayer
This is a small service you run, for example a serverless function or an n8n workflow. Webhooks and workflow rules are configured in Zoho Recruit Setup; no marketplace extension is needed.
- 1
Register an API client
In the Zoho API Console (api-console.zoho.com), create a Self Client with scopes such as ZohoRecruit.modules.ALL and ZohoRecruit.modules.attachments.all, plus ZohoRECRUIT.settings.tags.ALL for tags. Use the accounts server and API domain of your data center, for example zohoapis.eu for an EU account. Access tokens last one hour.
- 2
Create the webhook
In Setup → Automation → Actions → Webhooks, add your URL with the POST method, the candidate’s record ID as a parameter, and a secret as a custom parameter that your service checks.
- 3
Add a workflow rule
In Setup → Automation → Workflow rules, create a rule on Candidates that runs when a record is created, and add the webhook as an instant action. A Blueprint transition can call the same webhook.
- 4
Extract criteria, parse, score and write back
Send each job opening’s description to HireLayer Job Extract once. For each call, download the latest attachment, parse it, score it against the associated opening, then post a note and add a tag.
Field mapping
Where HireLayer results go in Zoho Recruit
Fields are written by API name. Check yours in Setup → Developer Space → APIs → API Names, especially for custom fields and the Experience_Details subfields.
| HireLayer field | Zoho Recruit API v2 | Note |
|---|---|---|
| score + summary + evaluated_criteria | POST /recruit/v2/Notes (Note_Title, Note_Content, Parent_Id, se_module) | What recruiters read |
| score ≥ your threshold | POST /Candidates/{id}/actions/add_tags?tag_names=… | |
| score | Custom field by API name (PUT /Candidates/{id}) | Create the field first |
| skills[].skill_title | Skill_Set (comma-separated text) | Merge with the current value |
| info_candidate.job_title | Current_Job_Title | |
| educations[] | Educational_Details (Institute_School, Degree, Duration.from/to) | |
| work_experiences[] | Experience_Details | Subfield API names from the fields metadata |
Example
A webhook handler in TypeScript
A minimal Node.js handler: it checks the secret, finds the associated job opening, downloads the latest attachment, parses and scores it, then adds a note and a tag. Add your own token refresh, storage for criteria and retries.
const HIRELAYER = 'https://hirelayer.co'
const headers = { 'X-API-Key': process.env.HIRELAYER_API_KEY! }
// API domain of your data center, e.g. https://www.zohoapis.eu for EU accounts
const RECRUIT = `${process.env.ZOHO_API_DOMAIN}/recruit/v2`
type Attachment = { id: string; File_Name: string; Created_Time: string }
const json = { 'Content-Type': 'application/json' }
const zoho = async (path: string, init: RequestInit = {}) => fetch(`${RECRUIT}/${path}`, {
...init, headers: { ...json, Authorization: `Zoho-oauthtoken ${await zohoAccessToken()}` },
})
// Zoho answers 204 with no body when a list is empty
const list = (path: string) =>
zoho(path).then((r) => (r.status === 204 ? [] : r.json().then((body) => body.data)))
// params: the parameters configured on the Zoho Recruit webhook
export async function handle(params: { candidate_id: string; secret: string }) {
if (params.secret !== process.env.ZOHO_WEBHOOK_SECRET) return 401
const id = params.candidate_id
// 1. The job opening and the latest attachment of the candidate
const [opening] = await list(`Candidates/${id}/associate`)
const [latest] = (await list(`Candidates/${id}/Attachments`)).sort(
(a: Attachment, b: Attachment) => b.Created_Time.localeCompare(a.Created_Time))
if (!opening || !latest) return 200
// 2. Download and parse (about 35 s)
const form = new FormData()
form.append('file', await zoho(`Candidates/${id}/Attachments/${latest.id}`)
.then((r) => r.blob()), latest.File_Name)
form.append('application_id', id)
const parsed = await fetch(`${HIRELAYER}/api/v3/parser`, {
method: 'POST', headers, body: form, signal: AbortSignal.timeout(150_000),
}).then((r) => r.json())
// 3. Score with the criteria stored for this job opening
const criteria = await loadCriteria(opening.id)
const match = await fetch(`${HIRELAYER}/api/v1/matching/job-candidate`, {
method: 'POST',
headers: { ...headers, ...json },
body: JSON.stringify({
job_text: criteria.jobText,
candidate_text: parsed.info_resume.text,
matching_criteria: criteria.items,
}),
}).then((r) => r.json())
// 4. Note and tag on the candidate
await zoho('Notes', { method: 'POST', body: JSON.stringify({ data: [{
Note_Title: 'HireLayer screening',
Note_Content: `Score: ${Math.round(match.score * 100)}/100\n${match.summary}`,
Parent_Id: id,
se_module: 'Candidates',
}] }) })
if (match.score >= 0.7) {
await zoho(`Candidates/${id}/actions/add_tags?tag_names=HireLayer%20strong%20match`, { method: 'POST' })
}
return 200
}Limits
Good to know
Webhook limits
Zoho documents daily webhook limits per edition: 10,000 calls or 100 per user license on Professional, 20,000 or 200 per license on Enterprise, whichever is lower. POST payloads are capped at 10,000 characters, and Notes cannot trigger webhooks.
API credits
Each API call uses credits from a rolling 24-hour pool, for example 10,000 plus 500 per license on Professional, up to 500,000. The handler above makes up to five Zoho calls per candidate, plus token refreshes.
Zoho Recruit already parses resumes
Its parser fills names, contact details, skills, education and experience, with a configurable Parser Mapping. Use HireLayer for job-specific scores and normalized skills, and only fill tables Recruit left empty.
Not a Marketplace extension
HireLayer is not listed on Zoho Marketplace. You connect it with your own API client and workflow webhook; Zoho documents webhook limits for the Professional and Enterprise editions, so check that your edition includes webhooks.
HireLayer APIs used on this page
FAQ
HireLayer and Zoho Recruit: questions
Does HireLayer integrate with Zoho Recruit?
Yes, through a workflow-rule webhook and the Zoho Recruit API v2: your service receives each new candidate, sends the resume to HireLayer, and writes the score back as a note and tags. HireLayer has no extension on Zoho Marketplace.
Can I screen Zoho Recruit candidates with AI?
Yes. HireLayer turns the job opening into weighted criteria, then scores each candidate from 0 to 1 with an explanation per criterion, written in French. The score supports your recruiters’ review; it does not change candidate statuses.
Can I use Zapier or Make instead of code?
Yes. Zoho Recruit has an official Zapier app with New Record and Update Record, and a Make app maintained by Make that adds Make an API Call, which can reach the attachments endpoint. Call HireLayer with Make’s HTTP module or a Zapier HTTP step.
Which Zoho data center should I use?
The one your Recruit account lives in: API calls go to zohoapis.com, zohoapis.eu, zohoapis.in, zohoapis.com.au, zohoapis.com.cn or zohoapis.jp, with the matching accounts server. Use the API domain returned during authorization. HireLayer itself processes data in the EU.
Does Zoho Recruit already parse resumes?
Yes, with a built-in parser and a configurable Parser Mapping, including for files sent to POST /Candidates/actions/import_document. HireLayer adds what the parse does not: a score against each job opening, with the criteria met and missing.
Connect Zoho Recruit to HireLayer today
The Free plan includes 50 credits a month, no card required. One successful call is one credit, on every API.
