Company Job Boards Scraper & Hiring Signals (ATS) avatar

Company Job Boards Scraper & Hiring Signals (ATS)

Pricing

from $1.00 / 1,000 job scrapeds

Go to Apify Store
Company Job Boards Scraper & Hiring Signals (ATS)

Company Job Boards Scraper & Hiring Signals (ATS)

Scrape job postings from company career pages on Greenhouse, Lever, Ashby, SmartRecruiters and Workable via their public job-board APIs. Normalized jobs (title, department, location, remote, salary, apply URL) plus hiring signals: new, removed and changed roles per company. Pay per job and signal.

Pricing

from $1.00 / 1,000 job scrapeds

Rating

0.0

(0)

Developer

Owlabee

Owlabee

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Categories

Share

What it does

This Actor scrapes job postings straight from the public job-board APIs that company career pages are built on: Greenhouse, Lever, Ashby, SmartRecruiters and Workable. Give it a list of boards (greenhouse:stripe, https://jobs.lever.co/spotify, ashby:openai, …) and it returns one normalized record per open job: title, department, team, location (raw plus best-effort city/country), a remote flag, employment type, posted/updated dates, apply URL, optional plain-text description and salary data where the provider exposes it (Ashby and Lever).

Switch to signals mode and it becomes a hiring monitor. Each board is compared with the snapshot from the previous run and you get change events — new-role, removed-role, title-changed, location-changed — plus one board-summary per company with open-role count, net change, top departments, top locations, remote share and a 0–100 hiring velocity score. That is the data sales teams, recruiters, investors and researchers use to spot companies that are expanding, freezing or shifting focus, without touching LinkedIn.

Because it reads official job-board APIs over plain HTTP, it needs no browser, no proxies and no login, which keeps it fast and cheap: 1,000 jobs cost about $1.00. Results are available as JSON, CSV, Excel, through the Apify API, webhooks and the Apify MCP server.

How to use

  1. Enter your Job boards, one per line, either as provider:boardId or by pasting the career-page URL. The provider is detected from the hostname (boards.greenhouse.io, job-boards.greenhouse.io, jobs.lever.co, jobs.ashbyhq.com, careers.smartrecruiters.com, apply.workable.com, <company>.workable.com).
  2. Pick a Mode: jobs for a full export, signals to detect changes since the last run. Optionally enable Include job description, lower Max jobs per board, set a Webhook URL.
  3. Click Start. For signals, schedule the same task (daily or weekly); the first run writes a baseline, every later run writes only what changed plus a summary per board.

Input

FieldTypeRequiredDescription
boardsstring[]yesprovider:boardId (greenhouse, lever, ashby, smartrecruiters, workable) or a public board URL. Duplicates are merged.
modejobs | signalsnojobs (default) lists every open job; signals diffs against the previous snapshot.
includeDescriptionbooleannoAdd descriptionText (HTML → text, max 3,000 chars). Default false. SmartRecruiters and Workable need one extra request per job for this.
maxJobsPerBoardintegernoCap per board (default 2000). Boards over the cap are marked truncated; removed-role signals are suppressed for them.
stateStoreNamestringnoNamed key-value store holding snapshots for signals mode (default ats-hiring-signals-state).
webhookUrlstringnoPOST target for the end-of-run summary (per-board summaries, counts, charges).
maxConcurrencyintegernoBoards fetched in parallel (default 5). Same-host requests are additionally limited to ~2/s.

Output example

A job record (mode: jobs, or baseline run in signals mode):

{
"type": "job",
"provider": "greenhouse",
"boardId": "stripe",
"companyName": "Stripe",
"jobId": "4012345007",
"title": "Senior Backend Engineer, Payments",
"department": "Engineering",
"team": "Payments Platform",
"location": "San Francisco, CA",
"city": "San Francisco",
"country": "United States",
"remote": false,
"employmentType": "full-time",
"postedAt": "2026-09-01T16:00:00.000Z",
"updatedAt": "2026-10-10T22:02:11.000Z",
"applyUrl": "https://boards.greenhouse.io/stripe/jobs/4012345007",
"jobUrl": "https://boards.greenhouse.io/stripe/jobs/4012345007",
"descriptionText": null,
"compensation": null,
"fetchedAt": "2026-10-16T12:00:00.000Z"
}

Ashby and Lever jobs carry compensation as { "min": 295000, "max": 440000, "currency": "USD", "interval": "1 YEAR", "summary": "$295K - $440K" } when the company publishes it.

A new-role signal (the other signal types share the shape; title-changed adds previousTitle, location-changed adds previousLocation):

{
"type": "new-role",
"provider": "lever",
"boardId": "spotify",
"jobId": "a1b2c3d4-0000-4000-8000-000000000001",
"title": "Staff Software Engineer, Platform",
"department": "Engineering",
"location": "New York, NY",
"remote": false,
"applyUrl": "https://jobs.lever.co/spotify/a1b2c3d4-0000-4000-8000-000000000001/apply",
"postedAt": "2026-10-14T10:26:40.000Z",
"job": { "jobId": "a1b2c3d4-…", "title": "Staff Software Engineer, Platform", "team": "Platform", "city": "New York", "country": "United States" },
"detectedAt": "2026-10-16T12:00:00.000Z"
}

A board-summary record (one per board per signals run):

{
"type": "board-summary",
"provider": "lever",
"boardId": "spotify",
"companyName": null,
"baseline": false,
"openRoles": 312,
"previousOpenRoles": 298,
"newSinceLastRun": 21,
"removedSinceLastRun": 7,
"changedSinceLastRun": 3,
"netChange": 14,
"topDepartments": [{ "name": "Engineering", "count": 140 }, { "name": "Sales", "count": 45 }],
"topLocations": [{ "name": "Stockholm, Sweden", "count": 120 }, { "name": "New York, NY", "count": 80 }],
"remoteShare": 0.18,
"hiringVelocityScore": 58,
"truncated": false,
"previousSnapshotAt": "2026-10-09T12:00:00.000Z",
"detectedAt": "2026-10-16T12:00:00.000Z"
}

Error items look like { "type": "error", "provider": "lever", "boardId": "nonexistent", "error": "BOARD_NOT_FOUND", "errorMessage": "HTTP 404 ..." }. Error codes: BOARD_NOT_FOUND, UNKNOWN_PROVIDER, UNRECOGNIZED_URL, BLOCKED, WORKABLE_BLOCKED, RATE_LIMITED, TIMEOUT, FETCH_FAILED. They are charged like a job record because the work to discover the problem was done.

The run's key-value store also gets a SUMMARY record with counts, charges and all board summaries; the same payload is POSTed to webhookUrl when set.

Pricing

Pay per event. You only pay for what the Actor produces; set a maximum cost per run in the run options to cap spend.

EventPriceNotes
Job scraped (job-scraped)$0.001Per job record, including baseline job records on the first signals run and error items
Hiring signal (hiring-signal)$0.005Per new-role, removed-role, title-changed, location-changed and per board-summary record
Actor start$0.00005Apify platform event

Examples: 1,000 jobs ≈ $1.00. A weekly check of 50 companies ≈ 50 summaries = $0.25 + $0.005 per detected change, after a one-off baseline charged at the per-job price (50 companies × ~100 jobs ≈ $5.00). A quiet week with 50 companies and 60 changes costs ≈ $0.55.

Limits and fair use

  • Only the providers' public, unauthenticated job-board APIs are used: boards-api.greenhouse.io, api.lever.co (and api.eu.lever.co), api.ashbyhq.com/posting-api, api.smartrecruiters.com/v1/companies, apply.workable.com/api. Private or password-protected boards are not supported.
  • Requests to each provider host are rate-limited to about 2 per second with exponential backoff on 429/5xx; very large boards or includeDescription on SmartRecruiters/Workable (one extra request per job) take proportionally longer.
  • Workable's career-page API sits behind a WAF. The Actor first tries the v3 search endpoint, then falls back to the v1 widget endpoint; if both are blocked you get a WORKABLE_BLOCKED error item for that board and the run continues. No residential proxies are used.
  • city/country are best-effort parses of free-text locations and may be null; remote is true when the provider flags it or the title/location says so.
  • Snapshots in signals mode store only the fields needed to diff (no descriptions), so a board with 2,000 roles uses well under 1 MB of key-value storage. If a board hits maxJobsPerBoard the summary is marked truncated and removals are not reported for it.
  • The Store's daily automated test runs with the prefilled boards (greenhouse:stripe, lever:spotify) in jobs mode and maxJobsPerBoard: 50.

Other pay-per-event Actors from the same account, all limited-permission and agent-friendly:

FAQ

Does this need proxies or an API key? No. Greenhouse, Lever, Ashby and SmartRecruiters publish job-board APIs that need no credentials and work from datacenter IPs. Workable is the exception; see "Limits".

How is cost controlled? Set maxJobsPerBoard, keep includeDescription off unless you need the text, and set the run's maximum total charge. The Actor charges each record as it is written and stops cleanly when the limit is reached; in signals mode it then leaves the snapshot untouched so the next run re-detects the same changes.

How do I find a company's board id? Open the company's careers page and look at the URL of a job: boards.greenhouse.io/<token>, jobs.lever.co/<company>, jobs.ashbyhq.com/<org>, jobs.smartrecruiters.com/<Company>/..., apply.workable.com/<subdomain>/.... Paste that URL as-is; the Actor extracts the id.

What happens on the first signals run? There is no previous snapshot, so the Actor writes every current job as a job record (charged at $0.001 each) plus a board-summary with baseline: true. Change events start with the second run. Use a different stateStoreName per schedule if you monitor the same board at different cadences.

Can I run it on a schedule or call it from an AI agent? Yes — use Apify Schedules, the API or the Apify MCP server. It is pay-per-event with limited permissions, so agents can discover and call it. Example prompt: "Watch these 40 companies' career pages every Monday and tell me which ones opened new sales roles."

Does it include closed or unlisted jobs? No. Only jobs the provider currently lists publicly are returned; Ashby jobs with isListed: false are skipped. A job that disappears between runs shows up as removed-role.

Why is department or postedAt null for some jobs? Providers expose different fields: Greenhouse has no posted date on some boards (first_published can be null), Lever has no updatedAt, SmartRecruiters departments are optional. The Actor never guesses these.

Only public job postings published by the companies themselves through their applicant-tracking systems are accessed, with no authentication and at polite rates. Use the data in compliance with each provider's terms and applicable law. This Actor is not a consumer reporting agency; its output describes job openings, not people, and must not be used for employment, credit, insurance or tenant screening decisions.