Career Site Jobs Scraper - Jobs from Company ATS Pages
Pricing
from $0.54 / 1,000 jobs
Career Site Jobs Scraper - Jobs from Company ATS Pages
Scrape open jobs from company careers pages. Paste a careers URL, a domain or just the company name, and it finds which of 10 hiring systems the company uses. Each job has the title, location, department, posted date, apply link and salary where published. $0.55 per 1,000 jobs.
Pricing
from $0.54 / 1,000 jobs
Rating
0.0
(0)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
0
Monthly active users
10 days ago
Last modified
Categories
Share
Paste a careers page, a domain or a company name, and get the open jobs back as rows: the title, location, department, posted date, the apply link, and the salary where the board publishes one.
The catch to know before you buy: it reads ten applicant tracking systems. A company running on anything else comes back as an uncharged diagnostic row saying so, not as data.
| Input | Careers page URLs, domains, board URLs or company names |
| Output | One row per open job: title, location, department, posted date, apply link, salary where published |
| Ceiling | 50 companies and 5,000 jobs per run, and 40 jobs per company on Workday |
| Account needed | None |
| Price | $0.55 per 1,000 jobs on the Free plan, a little less on paid plans. The free plan's $5 a month covers about 9,000 |
🔍 What Career Site Jobs Scraper does
Most careers pages sit on an applicant tracking system, and this reads the open roles from the system behind the page. Ten are covered: Greenhouse, Lever, Ashby, Workable, SmartRecruiters, Recruitee, Personio, Teamtailor, Breezy HR and Workday.
The work it saves you is the detection. Knowing in advance that Figma hires through Greenhouse under
the token figma and that Ramp uses Ashby is fine for three companies and hopeless for three
hundred. Paste whatever you happen to have, and every row comes back stamped with the ats and the
boardToken it resolved to, so your first run also builds that mapping for you.
You can narrow the rows too: words in the title or the location, the system, remote only, jobs that show a salary, or an employment type. Jobs a filter leaves out are not charged.
📋 What data you get from each open job
| What you get | Field |
|---|---|
| The entry you typed, so rows join back onto your list | inputUrl |
| The company's id on its board, the hiring system, and how it was found | company, boardToken, ats, atsName, detectedVia |
| Title, location, department and employment type, as the board wrote them | title, location, department, employmentType |
| The board's remote flag, where it has one | remote |
| When the job was posted | postedAt |
| The job's id, its page and the apply link | jobId, jobUrl, applyUrl |
| The pay, where the board publishes it | salary |
| The job text as plain text, with full details on | description |
| When the row was read | scrapedAt |
▶️ How to scrape company careers pages
- Open Career Site Jobs Scraper and click Try for free.
- Put your companies in Career page URLs or company names, one per line.
- Set Maximum jobs. Keep it small on the first run.
- Tick Include the full job description only if you need the job text.
- Click Start, then download the dataset as JSON, CSV or Excel, or read it from the Apify API.
Run it with the input empty and you get one labelled sample row, so you can see the shape first.
💰 How much does it cost to scrape company careers pages?
$0.55 per 1,000 jobs on the Free plan. Paid plans pay a little less: $0.545 on Starter, $0.54 on Scale and $0.535 on Business. On the free plan, the $5 Apify gives you each month covers about 9,000 jobs.
One charge per job row written to your dataset. Duplicate postings inside a company and jobs your filters leave out are dropped before anything is billed, and neither the sample row nor any diagnostic row is charged. Working out which system a company uses is not billed either: you pay for jobs, not for lookups.
📥 What you give it
Every field is optional.
{"companies": ["https://www.figma.com/careers","https://jobs.ashbyhq.com/ramp","notion.com","Databricks"],"maxItems": 100,"titleIncludes": ["engineer", "engineering"],"titleExcludes": ["intern"]}
| Field | Default | What it is |
|---|---|---|
companies | none | One entry per company, up to 50. A careers page, a bare domain, a board URL, or the company name on its own. |
maxItems | 50 | Total jobs across every company, 1 to 5,000. The budget is split evenly, so five companies and 50 jobs gives ten each. |
fullDetails | false | Adds a plain-text description to each row, and fills in the posted date on Ashby rows. Much heavier, because those feeds carry the whole job text. |
titleIncludes | none | Keep only jobs whose title has one of these words or phrases. Whole words, any case: engineer finds "Senior Engineer" but not "Engineering Manager", so list both if you want both. |
titleExcludes | none | Leave out jobs whose title has any of these, for example intern (which leaves "International Sales" alone). |
locationIncludes | none | Keep only jobs whose location, as the board wrote it, has one of these. Whole words, so US finds "Remote - US" and not "Austin". |
locationExcludes | none | Leave out jobs whose location has any of these. |
remoteOnly | false | Keep only jobs the board marks remote: the remote flag on Lever, Ashby, Workable, SmartRecruiters, Recruitee and Breezy HR, or the word "remote" in the location on Greenhouse, Personio and Workday (in the title on Teamtailor). Hybrid jobs never count. |
hasSalary | false | Keep only jobs whose salary carries a figure. Only Lever, Ashby, Recruitee and Breezy HR publish pay, so companies on the other six are skipped. |
employmentTypes | none | Any of fulltime, parttime, contract, temporary, internship, permanent, matched on the board's own employmentType wording. Contract also takes contractor and freelance; temporary takes fixed term, short term and seasonal; internship takes intern, trainee, apprentice and working student. A job with no type is left out, and Greenhouse and Workday publish none, so their companies are skipped. |
atsIncludes | none | Read only companies on these systems: greenhouse, lever, ashby, workable, smartrecruiters, recruitee, personio, teamtailor, breezy, workday. |
atsExcludes | none | Skip companies on any of these systems. |
proxyUrls | none | Leave it empty for a normal run. It exists for callers who want the traffic to leave through servers they already pay for, as http://user:pass@host:port. |
A board URL is the most reliable input, a domain is next, a bare name is loosest. Workday always needs a full URL, because its addresses carry a tenant and a site name nothing can guess.
Filters run on what each board sends, so a strict one can return fewer jobs than maxItems. On
Lever, SmartRecruiters and Workday, which send boards in pages, a filtered run reads at most 1,000
jobs per company, or the company's share of maxItems if larger. A company no filter could pass,
say a Greenhouse board when you ask for a salary, gets one free row saying it was skipped.
📤 What you get back
A real row:
{"ok": true,"charged": true,"recordType": "job","inputUrl": "https://www.figma.com/careers","company": "figma","ats": "greenhouse","atsName": "Greenhouse","boardToken": "figma","title": "Distribution Partner Manager","location": "San Francisco, CA • New York, NY • United States","remote": null,"department": "Business Development","employmentType": null,"postedAt": "2026-02-28T00:00:43.000Z","applyUrl": "https://boards.greenhouse.io/figma/jobs/5813967004?gh_jid=5813967004","jobUrl": "https://boards.greenhouse.io/figma/jobs/5813967004?gh_jid=5813967004","jobId": "5813967004","salary": null,"detectedVia": "token","scrapedAt": "2026-09-21T01:23:09.209Z"}
Three nulls on that row, and none of them are guesses: Greenhouse publishes no employment type,
salary or remote flag in its listings.
| Field | How to read it |
|---|---|
inputUrl | The exact string you supplied, so you can join rows back onto your list. |
ats, boardToken | The system and the company's id on it. atsName is the same system spelled for people. |
jobId | The posting's id on its board. This is the key to diff on when you re-run. |
postedAt | ISO 8601 in UTC. null where the board does not publish a date. |
location | As the company wrote it, not normalised. One writes "Remote - US", another writes the full country. |
remote | The board's own flag, null where the board has none. On Ashby with fullDetails on it is also true on hybrid jobs, so filter with remoteOnly, which reads the workplace type and leaves hybrid out. |
detectedVia | url if your input already named the board, token if it was matched from the domain or name, html if it was read off the careers page. |
🧾 Reading the output
| Row | How to spot it | Billed |
|---|---|---|
| A job | recordType: "job" | yes |
| The sample row | _sample: true, and only when the input named no companies | no |
| A diagnostic | _diagnostic: true and ok: false | no |
Filter on recordType == "job" and you have your jobs. The charged field is written when the row
is built, a moment before the charge goes out, so read it as "this is a real row" rather than as a
receipt.
Each diagnostic carries the inputUrl it belongs to and an errorCode:
| Code | What it means |
|---|---|
NO_RESULTS | The company resolved to no supported board, its board has no open roles, none of its jobs passed your filters, or your filters skip its system. details says which. |
BAD_INPUT | A filter could never match, for example an entry with no letters, or hasSalary with only Greenhouse allowed. Nothing was read. |
NOT_FOUND | A board id was tried and does not exist. |
RATE_LIMITED | A board throttled the run. |
SERVER_ERROR, NETWORK | A board answered badly or could not be reached. Re-run it. |
NOT_SERVED | This job was not served this run. Re-run it later. Until 12 October 2026 this code was called BLOCKED. |
TIME_BUDGET | The run ran out of time before it reached that company. |
PROXY_INPUT_ADJUSTED | Something in your proxyUrls was not usable and was adjusted. |
CHARGE_ERROR | Added at the end if a charge failed, so some rows may have arrived unbilled. |
UNEXPECTED_ERROR | Something broke inside the run. It is not charged, and the run still ends normally. |
💡 What people use it for
- Watching a named list of companies and diffing on
jobIdto see what opened this week. - Building an ATS map for a portfolio or a market, since every row names the system and the token.
- Pulling the full open board of a company before a sales or recruiting push.
- Checking how a role is actually titled across twenty companies before writing a job ad.
From a job search to the open roles at the employers behind it, in two runs:
- Run LinkedIn Jobs Scraper on a role and a
city, and copy the
companycolumn. - Paste those names into
companieshere, glance at anyNO_RESULTSrows, and addtitleIncludesif you only care about one kind of role.
🚧 What it does not do
- Ten systems, not all of them. A company on any other software returns a diagnostic row, not data.
- A Workday company stops at 40 jobs. However many it has open, a run returns at most 40 of them today.
- Filters read the board's own words. A remote job the board never flags, or pay written only
inside the job text, is left out by
remoteOnlyorhasSalary. - A company only resolves if its board id can be derived from its domain or name, or is sitting on its careers page, or you supplied the board URL yourself.
- Posted dates are not universal. Ashby carries them only with full details on, and Personio never does.
- Department, employment type and salary depend on the board, and most boards never publish a salary.
- Open roles only. No history, no closed-job archive.
- Job text is off by default and is flattened to plain text when you turn it on.
- A list that starts with dead entries gives up early and returns
TIME_BUDGETrows for the rest rather than grinding through all fifty. Board URLs avoid it entirely. - It is not an official tool of any platform or company named on this page. Dami's Studio is independent and is not affiliated with or endorsed by any of them.
🧭 Which job scraper do you need?
| If you want | Use |
|---|---|
| Open jobs at companies you name, read from their own hiring system | This one |
| Whole Greenhouse, Lever or Ashby boards, with the full description on every row | Multi-ATS Jobs Scraper |
| Public LinkedIn jobs by keyword and location | LinkedIn Jobs Scraper |
| Startup jobs with salary and equity | Wellfound Jobs Scraper |
❓ Questions people ask
What exactly do I paste in?
Whatever you have. figma.com, https://www.figma.com/careers or just Figma all reach the same
board, and the more specific the input, the fewer lookups.
Why did I get fewer jobs than I asked for?
Because the budget is split evenly between companies and some boards are small, because a company returned nothing, or because your filters left most of a board out. A Workday company also stops at 40. Either way you are billed for the rows you got.
Will one broken company kill the run?
No. It becomes an uncharged diagnostic row and the run carries on through the rest of your list.
Can I call it from code or connect it to an AI assistant?
Yes. The API tab has ready-made
code for Python, JavaScript and the command line. For Claude, ChatGPT or another MCP client, connect
https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/career-site-jobs-scraper. Either way
the run happens on your Apify account at the same price.
Is scraping careers pages legal?
These are the open roles companies publish on their own careers pages, read without an account. Apify's write-up on the legality of web scraping is a fair starting point, and we are not lawyers.
🆘 If something breaks
Open the Issues tab on the actor page. Send the run ID and the exact entry from companies that
misbehaved. The diagnostic row's errorCode and inputUrl usually explain it on their own.