DEV Community

Fast Data
Fast Data

Posted on Edited on

Hiring signals: get a Slack alert when target companies post new jobs (n8n)

Written with AI assistance. Data, code and numbers were checked by me before publishing.

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
...
Enter fullscreen mode Exit fullscreen mode

"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
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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
];
Enter fullscreen mode Exit fullscreen mode

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 = Sales or title contains "Data".
  • Tech-stack research: includeDescription: true plus 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

Job ads can contain recruiter names and e-mail addresses. Store and use them in line with data protection rules.

Top comments (0)

⌂ 换网址