Greenhouse, Lever & Ashby Jobs Scraper API avatar

Greenhouse, Lever & Ashby Jobs Scraper API

Pricing

$1.00 / 1,000 job normalizeds

Go to Apify Store
Greenhouse, Lever & Ashby Jobs Scraper API

Greenhouse, Lever & Ashby Jobs Scraper API

Normalize public Greenhouse, Lever, and Ashby jobs into one dataset. Detect official career URLs and optionally emit only new postings across scheduled runs.

Pricing

$1.00 / 1,000 job normalizeds

Rating

0.0

(0)

Developer

Kunteper Koyu

Kunteper Koyu

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

0

Monthly active users

15 hours ago

Last modified

Share

Fetch published job postings from official public Greenhouse, Lever, and Ashby endpoints and normalize them into one stable schema. Build job boards, hiring-signal datasets, market research, alerts, and recruiting automations without maintaining three provider-specific integrations.

What you get

  • company, title, primary and secondary locations, department, and team
  • employment type, workplace type, and remote status when available
  • plain-text and HTML descriptions
  • canonical job and application URLs
  • compensation when the provider exposes it
  • publication and update timestamps
  • deterministic SHA-256 fingerprints for change detection
  • careers-URL auto-detection for supported provider URL formats
  • persistent newOnly mode for scheduled monitors
  • isolated board errors, so one invalid board does not discard successful results

Common use cases

  • power a niche job board or searchable jobs API
  • monitor target companies for hiring and expansion signals
  • create role, keyword, location, and remote-job alerts
  • normalize jobs before analytics, enrichment, or RAG ingestion
  • track new and changed postings across multiple ATS providers

Quick start

  1. Find the board token in the company's public careers URL.
  2. Add the provider, board name, and optional company display name.
  3. Add keyword, location, remote, or publication-date filters if needed.
  4. Run the Actor and open the normalized dataset.
{
"boards": [
{
"provider": "greenhouse",
"boardName": "anthropic",
"companyName": "Anthropic"
},
{
"provider": "lever",
"boardName": "leverdemo",
"companyName": "Lever",
"region": "global"
},
{
"provider": "ashby",
"boardName": "Ashby",
"companyName": "Ashby"
}
],
"searchTerms": ["engineer"],
"locations": ["remote", "New York"],
"remoteOnly": false,
"includeDescription": true,
"includeCompensation": true,
"publishedAfter": "2026-07-01",
"maxJobsPerBoard": 1000,
"concurrency": 5,
"timeoutSeconds": 30
}

Lever supports global and eu regions. Board names are the public token or site name in the provider's careers URL.

Alternatively, paste official hosted careers URLs and let the Actor identify the provider and board without crawling the page:

{
"careerUrls": [
"https://boards.greenhouse.io/example",
"https://jobs.eu.lever.co/example",
"https://jobs.ashbyhq.com/example"
],
"newOnly": true,
"stateStoreName": "my-daily-job-monitor"
}

Auto-detection is deliberately limited to boards.greenhouse.io, job-boards.greenhouse.io, jobs.lever.co, jobs.eu.lever.co, and jobs.ashbyhq.com. It parses the URL locally and calls the provider's public JSON API; it does not scrape arbitrary company careers domains or follow redirects. For a custom careers domain, use its official hosted ATS link or enter the provider and board token under boards.

New-jobs-only scheduled runs

Set newOnly to true to persist stable hashes of provider, board, and source job ID in the named stateStoreName. The first run emits all matching jobs; later runs using the same store emit and charge only for previously unseen job IDs. Edits to a known posting do not make it new. Use a separate store name for each independent monitor and avoid concurrent runs against the same store, because key-value-store updates are not transactional. State retains the most recent 100,000 job identities. The default newOnly: false preserves the original behavior.

Example result

{
"provider": "greenhouse",
"boardName": "anthropic",
"companyName": "Anthropic",
"sourceJobId": "4461450008",
"title": "Account Executive, AI Native",
"location": "San Francisco, CA | New York City, NY",
"secondaryLocations": [],
"remote": false,
"jobUrl": "https://job-boards.greenhouse.io/anthropic/jobs/4461450008",
"publishedAt": "2024-12-20T13:53:38-05:00",
"updatedAt": "2026-06-08T20:49:32-04:00",
"fingerprint": "cb3e2724e0fde508046d496236f32f598457dc566625918c48655cc80e836697",
"retrievedAt": "2026-07-06T17:33:19.395Z"
}

Run by API

Set APIFY_TOKEN in your environment and keep it out of source control.

cURL

curl -X POST \
"https://api.apify.com/v2/acts/rtworule~public-ats-job-feed-normalizer/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"boards":[{"provider":"greenhouse","boardName":"anthropic","companyName":"Anthropic"}],"remoteOnly":true,"maxJobsPerBoard":100}'

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('rtworule/public-ats-job-feed-normalizer').call({
boards: [{ provider: 'greenhouse', boardName: 'anthropic', companyName: 'Anthropic' }],
remoteOnly: true,
maxJobsPerBoard: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("rtworule/public-ats-job-feed-normalizer").call(run_input={
"boards": [{
"provider": "greenhouse",
"boardName": "anthropic",
"companyName": "Anthropic",
}],
"remoteOnly": True,
"maxJobsPerBoard": 100,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)

Pricing

This Actor uses pay per event. A job-normalized event costs $0.001 per stored job: 100 delivered jobs cost $0.10 and 1,000 cost $1.00 in event charges. Apify applies a $0.01 minimum run charge. Filters, per-board limits, and newOnly mode help control output; the Actor stops storing results when the run's maximum total charge is reached. In newOnly mode, remembered postings are not emitted or charged as result events.

Integrations and automation

  • schedule with newOnly: true to receive and pay for only newly discovered jobs
  • compare the output fingerprint separately when you want to detect edits to known jobs
  • send matching jobs to Slack, email, Make, Zapier, n8n, or a webhook
  • load normalized jobs into a database, search engine, BI tool, or vector store
  • export CSV/XLSX to Sheets for research and editorial review
  • use publishedAfter, search terms, and locations to keep recurring runs focused

FAQ and troubleshooting

Is this scraping private candidate or recruiting data? No. It reads only public job-posting endpoints and does not access candidates, applications, internal postings, or authenticated recruiter systems.

Where do I find the board name? It is the company-specific token in the public Greenhouse, Lever, or Ashby careers URL—not necessarily the company's display name.

Why is a job or field missing? Filters may exclude it, the provider may omit the field, or the posting may have been removed. The Actor does not invent missing source data.

How do I avoid duplicate alerts? Enable newOnly and reuse the same stateStoreName on every scheduled run. The Actor then suppresses previously seen job IDs before charging or writing output. Keep newOnly disabled if you want a full snapshot and compare the output fingerprint in your destination to detect changed postings.

Why did one board fail while the run succeeded? Boards are isolated. Inspect the BOARD_ERRORS key-value-store record for an invalid token, provider response, timeout, or other board-specific error.

Data sources, responsible use, and limitations

The Actor uses public posting endpoints:

  • Greenhouse Job Board API: https://boards-api.greenhouse.io/v1/boards/{board}/jobs
  • Lever Postings API: https://api.lever.co/v0/postings/{site}
  • Ashby Job Postings API: https://api.ashbyhq.com/posting-api/job-board/{board}

Provider schemas, availability, and job content can change. Compensation, remote status, and timestamps are returned only when the source exposes enough information. Users remain responsible for their downstream use, retention, applicable terms, and compliance.

For a reproducible issue, open an issue from the Actor page with the run ID, provider, public board name, and expected behavior. Never include credentials, candidate data, or other sensitive information.

More tools from this developer