Greenhouse, Lever & Ashby Jobs API: Salary, Location, Remote
Pricing
from $0.85 / 1,000 job delivereds
Greenhouse, Lever & Ashby Jobs API: Salary, Location, Remote
All open jobs from Greenhouse, Lever & Ashby career pages in one format: title, department, location, remote, salary, dates, description. Auto-detects the ATS. onlyNew mode for monitoring. No API key, no login. MCP-ready for AI agents. Errors and empty results are free. $1 per 1,000 jobs.
Pricing
from $0.85 / 1,000 job delivereds
Rating
0.0
(0)
Developer
ABM
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
21 hours ago
Last modified
Categories
Share
$1 per 1,000 jobs. Pay only for jobs delivered: errors, unknown companies, empty boards and already-seen jobs are free.
One Actor for the three ATS most tech companies use for their career pages. Give it a list of companies or career page URLs. It detects whether each one runs on Greenhouse, Lever or Ashby and returns every open job in one unified JSON format: title, department, team, locations, country, remote / hybrid / onsite, employment type, salary range, publication date, job URL, apply URL and the full description as plain text, Markdown or HTML.
- No API key, no login, no browser. It reads the public JSON job-board APIs that the career pages themselves use. That is fast and stable, with no fragile HTML scraping.
- Auto-detection:
"stripe","Notion Labs",https://jobs.lever.co/spotify,https://boards.greenhouse.io/airbnb, EU boards (job-boards.eu.greenhouse.io,jobs.eu.lever.co), or a company career page that embeds one of these ATS. onlyNewmode for scheduled monitoring: each run returns only the jobs published since the last run, and you are billed only for those.- Unified salary fields (
salaryMin,salaryMax,salaryCurrency,salaryInterval) from the structured ATS data (Ashby, Lever). When the ATS has no salary field, they are parsed from the pay-transparency text in the description (Greenhouse). - Filters before billing: title keywords, excluded keywords, location, department, remote only, employment type, posted within N days.
- MCP-ready for Claude, Cursor, ChatGPT and other AI agents. The descriptions are clean text or Markdown, ready for LLMs and RAG.
How much does it cost?
Pay per event: $0.001 per job delivered (job-result event). No monthly rental.
| You get | You pay |
|---|---|
| 1 company with 100 open jobs | $0.10 |
| 1,000 jobs | $1.00 |
| 50 companies × 200 jobs = 10,000 jobs | $10.00 |
Daily onlyNew watch of 50 companies (~30 new jobs/day) | ≈ $0.90 / month |
Free (never billed): companies not found, boards with no open job, network errors, jobs removed by your filters,
duplicates (the same board given twice), and jobs already delivered in a previous run when onlyNew is on.
Set Maximum cost per run in Apify Console: the Actor stops cleanly when the limit is reached.
Input
{"companies": ["stripe", "https://jobs.lever.co/spotify", "https://jobs.ashbyhq.com/notion", "Société Générale"],"platform": "auto","onlyNew": false,"titleKeywords": ["engineer", "data"],"excludeTitleKeywords": ["intern"],"locations": ["London", "Remote"],"remoteOnly": false,"postedWithinDays": 30,"descriptionFormat": "text","maxJobsPerCompany": 0}
| Field | What it does |
|---|---|
companies | Slugs, company names, ATS board URLs, career page URLs, or greenhouse:slug / lever:slug / ashby:slug. |
platform | auto (default), or force greenhouse, lever, ashby. |
onlyNew | Return only jobs not delivered by a previous run with the same company list. |
stateKey | Optional name of the onlyNew memory (keep it when you edit the list). |
titleKeywords, excludeTitleKeywords | Title filters (case and accent insensitive). |
locations, departments | "Contains any of" filters on locations/offices/country and department/team. |
remoteOnly, employmentTypes, postedWithinDays | Remote, full-time / part-time / contract / internship / temporary, recency. |
descriptionFormat | text (default), markdown, html, all, or none (lightest). |
maxJobsPerCompany, maxTotalJobs | Caps (newest jobs first). 0 = no cap. |
Output
One dataset item per job, with the same fields whatever the ATS:
{"platform": "ashby","companySlug": "notion","companyName": "Notion","sourceInput": "https://jobs.ashbyhq.com/notion","jobId": "1fc309c8-da20-4ff2-84c7-8b863ece2b0a","title": "Software Engineer, AI Connections (Developer Platform)","department": "Engineering","team": "Engineering","location": "San Francisco, California","locations": ["San Francisco, California", "New York, New York"],"offices": [],"country": "United States","workplaceType": "hybrid","isRemote": true,"employmentType": "full-time","salaryMin": 200000,"salaryMax": 290000,"salaryCurrency": "USD","salaryInterval": "year","salaryText": "$200K – $290K","salarySource": "structured","publishedAt": "2026-08-24T14:44:49Z","updatedAt": null,"requisitionId": null,"jobUrl": "https://jobs.ashbyhq.com/notion/1fc309c8-da20-4ff2-84c7-8b863ece2b0a","applyUrl": "https://jobs.ashbyhq.com/notion/1fc309c8-da20-4ff2-84c7-8b863ece2b0a/application","boardUrl": "https://jobs.ashbyhq.com/notion","language": null,"descriptionText": "WHO WE ARE\n\nNotion is the collaborative AI workspace...","descriptionMarkdown": null,"descriptionHtml": null,"descriptionLength": 4210,"openJobsOnBoard": 148,"isNew": null,"scrapedAt": "2026-10-19T08:00:00Z"}
Export as JSON, CSV, Excel or HTML from the dataset, or read it through the API (?view=overview gives a compact table).
Use cases
1. Recruiting agency: new engineering jobs every morning in Google Sheets
A tech recruiter tracks 40 scale-ups that hire engineers in Europe. A daily schedule with onlyNew sends only the
jobs opened since yesterday to a Google Sheet, and the team calls the hiring managers the same day.
{"companies": ["stripe", "airbnb", "notion", "https://jobs.lever.co/spotify", "datadog", "ramp"],"onlyNew": true, "titleKeywords": ["engineer", "developer", "sre"], "locations": ["London", "Paris", "Berlin", "Dublin", "Remote"]}
[{"companyName": "Stripe", "title": "Backend Engineer, Payments", "location": "Dublin", "publishedAt": "2026-10-18T13:02:00Z", "isNew": true, "jobUrl": "https://stripe.com/jobs/search?gh_jid=..."}]
Typical volume is 10 to 40 new jobs a day, so about $1 a month.
2. Sales team: hiring signals for lead generation
A B2B SaaS sales rep sells a data tool. Companies that open "Data Engineer" or "Analytics" roles are warm leads. Every
Monday the run feeds the CRM with companyName, title, department and publishedAt.
{"companies": ["airbnb", "notion", "figma", "linear", "palantir"], "titleKeywords": ["data engineer", "analytics", "data platform"], "postedWithinDays": 7, "descriptionFormat": "none"}
[{"companyName": "Airbnb", "title": "Senior Data Engineer, Payments", "department": "Engineering", "publishedAt": "2026-10-15T17:40:00Z"}]
With descriptionFormat: "none" the run is lighter. Five companies cost a few cents a week.
3. Compensation analyst / job board: salary benchmarks
An HR analyst builds pay benchmarks from published salary ranges (US pay-transparency laws). They pull all jobs from 100
companies once a month and pivot salaryMin / salaryMax by title, country and employmentType.
{"companies": ["stripe", "openai", "notion", "ramp", "spotify"], "locations": ["United States", "US", "New York", "San Francisco"], "descriptionFormat": "none"}
[{"companyName": "Openai", "title": "Research Engineer", "salaryMin": 295000, "salaryMax": 440000, "salaryCurrency": "USD", "salaryInterval": "year", "salarySource": "structured"}]
About 5,000 jobs a month cost $5.
4. AI agent: "Which remote ML roles are open at these companies?"
An AI assistant calls the Actor through MCP with remoteOnly: true and descriptionFormat: "markdown", then summarizes the
requirements of each job for the user.
API examples
Python
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("<username>/ats-career-pages-jobs").call(run_input={"companies": ["stripe", "https://jobs.lever.co/spotify", "notion"],"titleKeywords": ["engineer"],"onlyNew": True,})for job in client.dataset(run["defaultDatasetId"]).iterate_items():print(job["companyName"], job["title"], job["location"], job["jobUrl"])
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('<username>/ats-career-pages-jobs').call({companies: ['stripe', 'https://jobs.ashbyhq.com/openai'],remoteOnly: true,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items.map((j) => `${j.companyName} | ${j.title} | ${j.salaryMin ?? ''}-${j.salaryMax ?? ''}`));
Integrations (Make, n8n, Zapier, Google Sheets)
- Make / Zapier: module "Apify → Run an Actor" (daily schedule, input with
"onlyNew": true), then "Apify → Get dataset items", then "Google Sheets → Add a row" or "Slack → Send message" for each new job. - n8n: Schedule Trigger → Apify node (Run Actor and get dataset items) → filter on
salaryMin→ Google Sheets / Airtable / Notion. - Apify schedules + webhooks: schedule the Actor in Apify Console and send each run's dataset to your own endpoint.
- Direct links: the dataset is available as JSON, CSV or Excel at
https://api.apify.com/v2/datasets/<datasetId>/items?format=csv.
Use with AI agents (MCP)
The Actor works with the Apify MCP server (https://mcp.apify.com). Add it to Claude Desktop, Claude Code, Cursor, ChatGPT or
any MCP client, then ask for example: "List the remote data engineering jobs open at Stripe, Notion and Spotify, with
their salary ranges." The input is plain (company names or URLs), the output is flat JSON with self-explanatory camelCase
fields, and the descriptions come as plain text or Markdown, ready for an LLM or a RAG index.
FAQ
How do I find a company's slug? Open its career page and look at a job link: boards.greenhouse.io/<slug>,
jobs.lever.co/<slug>, jobs.ashbyhq.com/<slug>. You can also paste the career page URL: the Actor looks for the ATS
link in the page. If there is none, it tries the domain name as the slug.
Does it need a proxy or an account? No. These are public job-board APIs, read directly with polite delays and retries.
How does onlyNew work? The IDs of delivered jobs are kept in a named key-value store
(ats-career-pages-jobs-state), with one memory per company list (or per stateKey). The first run delivers everything.
Later runs deliver only unseen jobs. Closed jobs are dropped from the memory automatically.
Why is a salary missing? Many companies do not publish one. Ashby and Lever provide structured ranges when the
company fills them in. For Greenhouse the range is parsed from the description text, and salarySource tells you which
source was used.
Is companyName always the official name? Greenhouse provides it. For Lever and Ashby, the public API has no company
name, so it is your input text if you typed a name, otherwise the slug in title case (e.g. "Openai").
What if a company is not found? Nothing is billed. The log and the run status list the inputs not found.
Limits
- Only Greenhouse, Lever and Ashby are supported. Workday, SmartRecruiters, Workable and others are not.
- Only what the company publishes on its public board: unlisted or internal jobs are not visible.
- Lever has no "updated" date. Greenhouse has no structured country, remote flag or salary unless the company adds them
(these fields are then inferred from the location and description, or left
null). - Salary parsing from free text is best-effort: always check
salaryText. - Auto-detection with a bare name tries the obvious slugs. When a name is ambiguous, give the exact board URL or force the platform.
- Very large boards (1,000+ jobs with descriptions) take longer to download. Use
descriptionFormat: "none"for lists only.