Client-hunting sheet for Indian recruitment agencies: which companies on Zoho Recruit and Keka are hiring in your desk, and which roles are open 30+ days
What you get: a client-hunting sheet in one Google Sheet with one row per Indian company you want as a client: how many roles are open, how many were published in the last 7 days, how many have been open for 30+ days (the hard-to-fill roles an agency can help with), the city hiring most, how many roles fall in your desk (for example sales, accounts or IT), how many ask for your experience band, the change since last week and a Pitch now / Growing / Warm / Watch / Quiet status. It is built for Indian recruitment and staffing agencies, freelance recruiters and HR service firms. The jobs come from public company career pages on Zoho Recruit and Keka (plus Freshteam while it lasts). The example rows and numbers are made up.
The finished sheet
pipeline tab (example rows are made up)
| Company | Open roles | New in 7 days | Open 30+ days | Top city | Roles in your desk | Your experience band | Change vs last week | Status |
|---|---|---|---|---|---|---|---|---|
| Example Foods Pvt Ltd | 14 | 2 | 5 | Pune | 4 | 3 | +1 | Pitch now: hard-to-fill roles in your desk |
| Example Fintech | 22 | 6 | 1 | Bengaluru | 0 | 0 | +6 | Growing: call this week |
| Example Clinics | 5 | 0 | 0 | Hyderabad | 2 | 1 | 0 | Warm: your desk is hiring |
| Example Textiles | 0 | 0 | 0 | 0 | 0 | -2 | Quiet |
"Roles in your desk" counts jobs whose title contains the word you set (for example Sales, Accountant or Java). "Your experience band" counts Keka jobs whose stated minimum experience is at least the number of years you set, because most agencies place mid-level and senior people, not freshers.
Who this is for
- Recruitment and staffing agencies in India: a company that has had five sales roles open for over a month is a better first call than one that just posted a single role and will fill it from referrals.
- Freelance and boutique recruiters: keep a shortlist of 20 to 200 target companies and see each Monday which ones are hiring in your desk.
- HR service firms (payroll, background checks, onboarding, training): a company adding many people this month is a good time to offer help.
Many Indian SMBs and startups publish their openings on a Zoho Recruit or Keka career page rather than (or before) a job portal. Those pages are public and need no login, so you can read them like a candidate would.
Step 1: the prospects tab
Add a tab named prospects with A Company, B Career page, C Why they matter and D Owner in row 1, then one row per target company. In B Career page put the company's career page address. You find it by opening the company's website, clicking Careers and then any job:
- Zoho Recruit pages look like
https://examplefoods.zohorecruit.in/jobs/Careers(or.com/.eu). - Keka pages look like
https://examplefintech.keka.com/careers. - Freshteam pages look like
https://exampleclinics.freshteam.com/jobs.
The actor also accepts short forms such as zoho:examplefoods, keka:examplefintech or freshteam:exampleclinics. If the careers page shows Darwinbox, Naukri or a plain list on the company's own site, this sheet will not read it: leave that company out or track it by hand.
Step 2: run the jobs pull for every company at once
Open India ATS Jobs: Zoho Recruit, Keka, Freshteam on the Apify Store. It reads each public career page and returns one row per open job in the same columns, whichever of the three systems the company uses. To build its input from your sheet, add a tab named settings and put this in any empty cell (for example D1), then copy the result into the input's JSON view:
="{""boards"": [" & TEXTJOIN(",", TRUE, ARRAYFORMULA(IF(prospects!B2:B="", "", """" & TRIM(prospects!B2:B) & """"))) & "], ""postedWithinDays"": 0, ""includeDescription"": false}"
postedWithinDays: 0returns every open job, which you need for the open-roles and 30+ days counts. The 7-day count is worked out in the sheet.includeDescription: falseleaves out the long job text, so the export is small and easy to import.- Leave
keywordsempty. Your desk word is applied in the sheet, so you still see each company's total hiring.
When the run succeeds, download the dataset as CSV and import it into a new tab named jobs (File → Import → Upload → Replace current sheet). Each row is one job with fields such as company, title, city, experience (Keka, for example 1-3), department, publishedAt, ats and jobUrl. Also open the run's key-value store and check the BOARDS_SUMMARY record: it shows a status for every career page, so a wrong address shows up there instead of silently giving zero.
Step 3: find the columns by name
CSV column order can change between runs, so the sheet looks up each column by its header. In the settings tab, put these in A2:B8:
| A | B (formula) |
|---|---|
| company | =MATCH(A2, jobs!$1:$1, 0) |
| title | =MATCH(A3, jobs!$1:$1, 0) |
| city | =MATCH(A4, jobs!$1:$1, 0) |
| experience | =MATCH(A5, jobs!$1:$1, 0) |
| publishedAt | =MATCH(A6, jobs!$1:$1, 0) |
| ats | =MATCH(A7, jobs!$1:$1, 0) |
| jobUrl | =MATCH(A8, jobs!$1:$1, 0) |
Then put your desk word in settings!B10 (for example Sales) and your minimum years of experience in settings!B11 (for example 3). If a MATCH shows #N/A, open the jobs tab and copy the exact header text into column A.
Step 4: the pipeline tab, one row per company
After the first run, copy each company name exactly as it appears in the company column of jobs into pipeline!A2 downwards (the career page sometimes uses a longer legal name than you typed). Row 1 headers: A Company, B Open roles, C New in 7 days, D Open 30+ days, E Top city, F Roles in your desk, G Your experience band, H Last week, I Change, J Status. Formulas for row 2 (copy down):
B2 =COUNTIF(INDEX(jobs!$A:$ZZ, 0, settings!$B$2), A2)
C2 =SUMPRODUCT((INDEX(jobs!$A$2:$ZZ, 0, settings!$B$2)=A2) *
(IFERROR(DATEVALUE(LEFT(INDEX(jobs!$A$2:$ZZ, 0, settings!$B$6), 10)), 0) >= TODAY()-7))
D2 =SUMPRODUCT((INDEX(jobs!$A$2:$ZZ, 0, settings!$B$2)=A2) *
(IFERROR(DATEVALUE(LEFT(INDEX(jobs!$A$2:$ZZ, 0, settings!$B$6), 10)), 0) > 0) *
(IFERROR(DATEVALUE(LEFT(INDEX(jobs!$A$2:$ZZ, 0, settings!$B$6), 10)), 0) <= TODAY()-30))
E2 =IFERROR(INDEX(QUERY({INDEX(jobs!$A$2:$ZZ, 0, settings!$B$2), INDEX(jobs!$A$2:$ZZ, 0, settings!$B$4)},
"select Col2, count(Col1) where Col1 = '" & SUBSTITUTE(A2, "'", "''") & "' and Col2 <> ''
group by Col2 order by count(Col1) desc limit 1 label count(Col1) ''", 0), 1, 1), "")
F2 =SUMPRODUCT((INDEX(jobs!$A$2:$ZZ, 0, settings!$B$2)=A2) *
ISNUMBER(SEARCH(settings!$B$10, INDEX(jobs!$A$2:$ZZ, 0, settings!$B$3))))
G2 =SUMPRODUCT((INDEX(jobs!$A$2:$ZZ, 0, settings!$B$2)=A2) *
(IFERROR(VALUE(REGEXEXTRACT(TO_TEXT(INDEX(jobs!$A$2:$ZZ, 0, settings!$B$5)), "\d+")), -1) >= settings!$B$11))
I2 =IF(H2="", "", B2-H2)
J2 =IF(B2=0, "Quiet",
IF(AND(F2>=1, D2>=1), "Pitch now: hard-to-fill roles in your desk",
IF(C2>=3, "Growing: call this week",
IF(F2>=1, "Warm: your desk is hiring", "Watch"))))
The thresholds in J2 (30 days, 3 new roles in a week) are our working rule, not an industry standard. Change them to fit your desk: IT roles often stay open longer than sales roles.
Optional: add a tab named aged with =FILTER(jobs!A:ZZ, ISNUMBER(SEARCH(settings!B10, INDEX(jobs!A:ZZ, 0, settings!B3))), IFERROR(DATEVALUE(LEFT(INDEX(jobs!A:ZZ, 0, settings!B6), 10)), TODAY()) <= TODAY()-30). It lists every role in your desk that has been open 30+ days, with its job link, so you can quote the exact role in your first message.
Step 5: the weekly routine (about 20 minutes)
- Monday morning: before importing, copy column
B Open rolesand paste it as values intoH Last week. - Run the actor again with the same input and import the new CSV into
jobs(replace the tab). - Sort
pipelineby Status. Open two or three job links for each "Pitch now" company and check the roles are still open (see the Zoho note below). - Write to the company's HR or careers inbox, or call the number on its website. Log the date in
prospects!Dso two people don't call the same company. - Add new target companies to
prospectsand drop the ones that said no.
First message template
Subject: [Role title] in [city]: shortlisted candidates in 7 days Hello [Company] team, I saw the [Role title] role on your careers page has been open for a few weeks. We place [desk, e.g. sales and business development] people in [city/region] and have placed similar roles at [type of company, no client names without permission]. If useful, I can send 3 screened profiles within 7 days. Our fee is [your terms], payable only on joining. Regards, [Your name], [Agency], [phone]
Keep it short, name the exact role, and never claim a placement you didn't make.
Honest limits
- Only Zoho Recruit, Keka and Freshteam career pages. Darwinbox and Naukri are not supported, and neither are jobs listed only on a company's own website or on job portals.
- Zoho Recruit companies can choose to keep filled or closed jobs visible on their career site (Zoho documents a "Show filled/closed/unpublished jobs" option). Such a job can look "open 30+ days" when it is already filled. Open the job link before you pitch.
- Freshteam is closing down. Freshworks' own sunset FAQ says renewals stopped from 7 June 2026 and accounts stay reachable for 90 days after the subscription ends. Freshteam pages also give no published date, so their jobs count in "Open roles" but never in "New in 7 days" or "Open 30+ days". Expect those companies to move to another system.
- Published date is the date the company shows. Some companies re-post an old role, which resets the date, so a hard-to-fill role can look new.
- Experience is only stated on Keka (for example
1-3), so "Your experience band" is 0 for Zoho and Freshteam jobs. Read the title instead. - Keka rarely states full-time or contract, so this sheet does not filter by employment type.
- This lists jobs, not people. When you contact someone, use the company's published HR or careers contact, honour opt-outs, and follow India's Digital Personal Data Protection Act, 2023 and its rules for any personal data you keep. This is not legal advice.
Sources checked today (25 Oct 2026): Zoho Recruit help pages on setting up a career site and retaining closed jobs on the career site; the Freshteam sunset support FAQ; the robots.txt of a Keka careers host (it allows /careers); and the actor's README and input schema on Apify.
Related
- How to run the India ATS jobs actor (Zoho Recruit, Keka, Freshteam)
- Hiring signal sheet for Greenhouse, Lever and Ashby companies
- Speculative job application sheet (find the HR inbox)
- Turn a website contact export into a call sheet
- GSTIN, PAN and IFSC check sheet
Questions
How do I know if a company uses Zoho Recruit or Keka?
Open any job on its careers page. If the address contains zohorecruit, keka.com/careers or freshteam.com, the sheet works for that company.
Why is "Open 30+ days" a good signal for an agency?
A role that stays open for a month usually means the company's own posting and referrals have not found the right person. That is when an outside recruiter is most useful. Check the job is still open first.
Why does a company show 0 open roles?
Either it has no open jobs, the company name in pipeline does not match the export exactly, or the career page address was wrong. Check BOARDS_SUMMARY in the run's key-value store.
Partner programme opening soon: join the free waitlist. Planned terms are 50% of each referred sale (75% once you have 5+ paying customers), single level, paid through Gumroad only from revenue received. Join the partner waitlist
Unadhi Guides are free, independent explainers. We correct errors as soon as we find them: write to mininglife7@gmail.com.