跳到正文
DEV Community· Caspian Data·· 3 小時前AI 評分44

如何透過 Greenhouse 和 Lever 公開職位 API 追蹤各公司的招聘動向

Track hiring signals at any company with the Greenhouse and Lever public job APIs

AI 導讀

Company Jobs Tracker Actor 透過 Greenhouse 和 Lever 的公開唯讀 API,追蹤多家公司的招聘職位及招聘變化。它可整理公司摘要,並在後續執行時回報新增、關閉及變化職位;職位描述中的電郵地址和電話號碼會被移除。

正文

Caspian Data

Thousands of companies host their careers page on Greenhouse or Lever. Both platforms expose a public, documented, read-only API for those job boards, meant for building job sites. That makes them a clean data source for a useful question:

Which companies are hiring, for which teams, and how fast is that changing?

Sales teams use it as a buying signal, investors as a proxy for momentum, job seekers as an alert feed. This post shows how to get it in a few lines of Python, without scraping HTML and without collecting any personal data.

The two APIs

  • Greenhouse: https://boards-api.greenhouse.io/v1/boards/{company}/jobs?content=true
  • Lever: https://api.lever.co/v0/postings/{company}?mode=json

Both return JSON lists of open postings. Lever asks clients to stay at about one request per second.

Calling them directly is easy for one company. It gets tedious when you want a watchlist, "only new jobs since yesterday", normalized fields across both platforms, and a per-company summary. That is what the Company Jobs Tracker Actor does, so the rest of this post uses it.

Hiring signals for a list of companies

pip install apify-client
export APIFY_TOKEN=your_token
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("caspiandata/ats-jobs-hiring-signals").call(run_input={
    "companies": ["stripe", "airbnb", "lever:spotify", "lever:palantir"],
    "outputJobs": False,   # only the per-company summary rows
})
rows = [r for r in client.dataset(run["defaultDatasetId"]).iterate_items() if r["type"] == "company-signal"]
for r in sorted(rows, key=lambda r: r["postedLast30Days"], reverse=True):
    print(r["company"], r["openRoles"], r["postedLast30Days"], r["topDepartments"][0]["name"])

The full script formats it as a table. Output from a run on 31 October 2026:

Company        Open roles  Posted 30d  Remote %  Top department
Stripe                746         238       16%  Account Executives (EMEA)
Airbnb                202          94       10%  Software Engineering
Spotify                89          35       31%  Engineering
Palantir              299          17        0%  Dev

Run it again tomorrow and each row also has newSinceLastRun, closedSinceLastRun and changeSinceLastRun.

A daily "new jobs" alert

run = client.actor("caspiandata/ats-jobs-hiring-signals").call(run_input={
    "companies": ["https://boards.greenhouse.io/stripe", "lever:spotify"],
    "keywords": ["data", "analytics"],
    "onlyNew": True,
    "stateKey": "my-watchlist",
})

The first run returns everything; every later run returns only postings that appeared since the previous one. Put it on a cron job or an Apify schedule and pipe the result to Slack or email.

Finding a company's slug

Open the company's careers page and look for links to boards.greenhouse.io/<slug>, job-boards.greenhouse.io/<slug> or jobs.lever.co/<slug>. You can also just pass the slug and the Actor checks Greenhouse first, then Lever.

Notes

  • Only public postings are read, via the APIs the platforms document for that purpose. Email addresses and phone numbers in descriptions are removed.
  • Cost: $1 per 1,000 jobs and $5 per 1,000 company summary rows.

Runnable examples: github.com/caspiandata/caspiandata-examples


Disclosure: we (Caspian Data) built and maintain the Actor used here. This post was written with the help of AI tools and the numbers come from a real run.

來源:DEV Community · dev.to