Skip to content

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
Zoho Recruit + HireLayer
  1. 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.
  2. 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.
  3. 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.
  4. 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. 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. 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. 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. 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 fieldZoho Recruit API v2Note
score + summary + evaluated_criteriaPOST /recruit/v2/Notes (Note_Title, Note_Content, Parent_Id, se_module)What recruiters read
score ≥ your thresholdPOST /Candidates/{id}/actions/add_tags?tag_names=…
scoreCustom field by API name (PUT /Candidates/{id})Create the field first
skills[].skill_titleSkill_Set (comma-separated text)Merge with the current value
info_candidate.job_titleCurrent_Job_Title
educations[]Educational_Details (Institute_School, Degree, Duration.from/to)
work_experiences[]Experience_DetailsSubfield 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.

zoho-recruit-webhook.tstypescript
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.

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.