DEV Community

Fast Data
Fast Data

Posted on

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

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)