Job postings are one of the most honest signals a company sends. A startup that opens five account executive roles in a new country is about to sell there. A first "Head of Data" means a data stack is about to be bought. A burst of support roles often follows a launch.
Sales teams call these hiring signals, investors use them to track growth, and job seekers just want to be early. In all three cases the job is the same: watch a list of career pages and tell me what is new. This n8n workflow does exactly that, once a day, for about a dollar a month.
Disclosure: the job data comes from the Job Search API Actor on Apify, which I built. Pricing and limits are below.
The result
From a test run watching Stripe, Ramp and Palantir (postings from the last two days):
Hiring signals: 13 new role(s) at 3 company(ies)
Stripe: 9 new (Sales 3, Engineering 3, Leadership 1, Marketing 1, Customer 1)
- Account Executive, Velocity Platforms (Hunter) - Chicago, IL; New York, NY; ...
- Backend / API Engineer, Radar
- Country Manager, Israel - Israel
- Engineering Manager, Money as a Service (MaaS) - Singapore
...and 4 more (see the sheet)
Ramp: 2 new (Recruiting & People 2)
- Technical Sourcer - Engineering (Contract) - New York, NY (HQ)
- Lead Recruiter - Executive - New York, NY (HQ)
Palantir: 2 new (Engineering 2)
- Software Engineer, New Grad - Query Engines - London, United Kingdom
...
"Country Manager, Israel" is precisely the kind of line a sales or partnerships team wants to see on the day it appears. Every posting is also appended to a Google Sheet (company, team, title, location, remote, posted date, URL), so you can count over months.
The workflow
Schedule (daily 8:00)
→ HTTP Request: Job Search API (company career pages)
→ Remove Duplicates (previous executions, by job URL)
→ Code: tag team & pick columns
├→ Google Sheets (append)
└→ Code: build digest → Slack
Reading career pages without scraping HTML
Most tech companies host their careers page on an applicant tracking system: Greenhouse, Lever, Ashby or SmartRecruiters. All four have public JSON endpoints for open positions. The Actor reads those and returns one unified format, so you can mix them freely:
{
"companies": ["greenhouse:stripe", "ashby:ramp", "lever:palantir"],
"postedWithinDays": 2,
"maxJobsPerSource": 100,
"includeDescription": false
}
You can also pass careers URLs like https://jobs.lever.co/palantir. Since no keywords are set, only the company pages are read and every role is returned. (With keywords, the Actor also searches public job boards: Remote OK, Himalayas, Arbeitnow and the German Federal Employment Agency. That's handy for a job-seeker version.)
The HTTP Request node calls https://api.apify.com/v2/acts/fast_data_asap~job-search-api/run-sync-get-dataset-items with a Header Auth credential (Authorization: Bearer <token>). For three companies, the run took about six seconds.
"New since the last run"
This is the part people usually build with a database. n8n has it built in: Remove Duplicates with "Remove items processed in previous executions", keyed on {{ $json.url }}. It stores every URL it has seen and only passes on new ones. I tested it by running the workflow twice in a row: the first run let 13 postings through, the second discarded all 13.
postedWithinDays: 2 (not 1) is deliberate. If a run fails or n8n is down for a day, the next run still covers the gap, and deduplication takes care of the overlap.
Guessing the team
Job titles are messy, but a dozen regexes get you surprisingly far:
const TEAMS = [
['Leadership', /\b(head of|director|vp|vice president|chief|country manager|general manager)\b/i],
['Recruiting & People', /recruit|sourcer|talent|people partner|\bhr\b/i],
['Sales', /sales|account executive|account manager|business development|\b[bs]dr\b|partnership/i],
// ... Marketing, Customer, Data & AI, Engineering, Product & Design
];
Order matters. My first version put Engineering first, and "Account Executive, Velocity Platforms" was filed as Engineering because of platform. Now leadership and go-to-market patterns are checked first, and Engineering no longer matches on "platform".
Cost
The Actor charges $0.0025 per job returned. The test run above returned 13 jobs = $0.03; a daily run for three fast-growing companies comes to about $1 per month. Because of the one-day overlap, some postings are returned (and paid) twice; for very large companies, postedWithinDays: 1 halves the cost.
Apify's free plan includes $5 per month.
Ideas
-
Filter to what you sell into: add a Filter node, e.g.
team = Salesor title contains "Data". -
Tech-stack research:
includeDescription: trueplus an LLM step "Which tools does this posting mention?" - CRM task instead of Slack: create a HubSpot or Pipedrive task "Company X is hiring 5 AEs in DACH".
-
Job-seeker mode: add
"keywords": "python developer"and"remoteOnly": true. - Workday employers: the Job Search API doesn't read Workday career sites. For those I built a second Actor, the Career Site Jobs API: nine ATS including Workday, Workable, Teamtailor, Recruitee and Personio, plus an optional "only new jobs" mode that remembers what it has already returned. $2 per 1,000 jobs (down to $1.50 on higher Apify plans).
Get it
- Workflow JSON and setup guide: https://github.com/ichkifokkus/data-recipes/tree/main/4-hiring-signal-alert
- Actor: https://apify.com/fast_data_asap/job-search-api
Job ads can contain recruiter names and e-mail addresses. Store and use them in line with data protection rules.
Top comments (0)