Disclosure first: I built the tool in this post. It's called Vee Jobs, it's pay-per-use, and I'll try to make the article useful even if you end up picking something else.
I'm a developer based in Bali, and I build small data tools at Hoxei R&D under the name Vee. Vee Jobs came from a plain annoyance. Every time someone asks "which companies are hiring data engineers?", the honest answer is a pile of browser tabs and a lot of copy and paste. I don't like answers like that, so I went looking for a better one.
The shortcut
Most career pages look like custom sites, but a lot of them are just a skin over an applicant system. Greenhouse, Lever, Ashby and Workable all publish public job-board APIs so companies can embed their listings on their own pages. If you talk to those APIs directly you get clean data and you don't need a browser at all. No clicking through pages, no fragile selectors.
My opinion: for this kind of job, a browser-based scraper is the wrong tool. It's slower, it breaks when a page gets redesigned, and you pay for the weight. The APIs are right there.
So I wrapped the four of them into one Apify Actor that returns a single consistent table. Here's how it works in practice.
What you need
A free Apify account (new accounts get monthly free credits from Apify) and a list of companies. A career page URL works, and so does a bare company name like notion.
Run it on three companies
Open Vee Jobs on Apify, click Try for free, and paste this into the JSON input:
{
"companies": [
"https://jobs.lever.co/spotify",
"https://boards.greenhouse.io/stripe",
"https://jobs.ashbyhq.com/openai"
],
"keywords": ["data", "analytics"],
"maxJobs": 30
}
keywords keeps jobs whose title contains any of those words. maxJobs caps each company at 30 jobs, which is how you control the bill. I ran exactly this input today and it finished in about 4 seconds.
What comes back
The run returned 68 jobs: 8 from Spotify (Lever), 30 from Stripe (Greenhouse) and 30 from OpenAI (Ashby). All three platforms come back in the same fields, which was the whole point for me. Here is a real row from the Spotify board, with the description shortened:
{
"platform": "lever",
"companySlug": "spotify",
"title": "Backend Engineer - Data Platform",
"location": "Stockholm",
"allLocations": ["Stockholm", "London"],
"department": "Platform",
"employmentType": "Permanent",
"remote": false,
"workplaceType": "hybrid",
"url": "https://jobs.lever.co/spotify/926149ab-6999-4058-b35d-41e302b70e05",
"postedAt": "2026-10-01T11:42:05.650Z",
"compensation": null,
"descriptionText": "LilEngine is leading the Lakehouse, a company-strategic effort to make Apache Icβ¦"
}
And a real row from OpenAI's Ashby board, which publishes pay:
{
"platform": "ashby",
"companySlug": "openai",
"title": "Software Engineer, Data Infrastructure",
"location": "San Francisco",
"department": "Scaling",
"employmentType": "FullTime",
"compensation": "$266K β $445K β’ Offers Equity",
"salaryMin": 266000,
"salaryMax": 445000,
"salaryCurrency": "USD",
"salaryInterval": "year",
"postedAt": "2024-06-27T22:14:24.195+00:00"
}
Two things stood out to me when I looked at the output.
Salary only shows up when the company publishes it. In this run 30 of the 68 jobs, all from OpenAI, had a compensation value. Stripe's and Spotify's boards published none, so those fields are null. A tool can't invent a salary, and I'd be suspicious of any that claims to.
Dates can also be old. That OpenAI row was posted in 2024 and it's still open. If you only want fresh roles, set postedWithinDays.
The run also saves a SUMMARY record in the key-value store that tells you, per company, how many jobs were open and how many matched your filters. For this run: Spotify 82 open, 8 matched. Stripe 731 open, 30 matched (capped by maxJobs). OpenAI 815 open, 30 matched (capped).
Get it into a spreadsheet
In the run's Output tab choose Export, then CSV, Excel or JSON. Open the CSV in Google Sheets and filter by department or location. A pivot table on companySlug and department already answers "who is hiring for what", which is the question I started with.
Filter harder
Here are two variations I use. The first narrows to recent remote roles:
{
"companies": ["notion", "stripe", "outreach"],
"keywords": ["data", "analytics"],
"remoteOnly": true,
"postedWithinDays": 14,
"includeDescription": false
}
The second mixes a Workable URL with a bare name and filters by location:
{
"companies": ["https://apply.workable.com/careers-at-sleek/", "spotify"],
"locations": ["Berlin"]
}
With includeDescription off the rows stay small, which is nicer in a spreadsheet. Filters also lower your bill, because you only pay for jobs that pass them.
Run it every week
Use Apify Schedules to run it weekly, then compare runs by jobId to spot the new roles. You can also call the Actor from Python:
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("veelabs/vee-jobs").call(run_input={
"companies": ["https://jobs.lever.co/spotify"],
"keywords": ["data"],
"maxJobs": 30,
})
for job in client.dataset(run["defaultDatasetId"]).iterate_items():
print(job["title"], "|", job["location"], "|", job["postedAt"][:10])
What it costs
Vee Jobs charges $1.80 per 1,000 jobs plus $0.005 per run, and platform usage is included. The 68-job run above costs 68 x $0.0018 + $0.005, which is about $0.127. A full 10,000-job pull costs $18.005. The price is the same on every Apify plan. Apify's pricing table lists all the plans, so you'll see the same number repeated in each column. That confused me the first time too.
Where it falls short
It covers four platforms: Greenhouse, Lever, Ashby and Workable. Companies on Workday, SmartRecruiters or a fully custom page aren't covered. I'd rather be narrow and reliable than claim everything.
A bare company name is a guess. notion gets tried on each platform in turn, so if a name is ambiguous, paste the full career page URL.
Emails and phone numbers in descriptions are redacted by default and show up as [email removed] and [phone removed]. You can turn that off, but then you're responsible for any personal data you keep.
Descriptions are cleaned down to basic formatting tags, with no scripts, images or attributes. If you render the HTML on your own site, sanitize it again anyway. I would.
And the legal part is on you. The data is public, but check each site's terms and the privacy laws that apply to you (GDPR, PDPA and others), and don't use personal data for unsolicited contact. This isn't legal advice.
Other options
If you need other applicant systems or a different output shape, other Apify Store Actors cover more boards, and some are far more popular than mine. Compare input options and pricing before you choose. Vee Jobs is deliberately narrow: four platforms, one schema, no browser.
If you want to try it, it's here: Vee Jobs on Apify. If something looks wrong, open an issue on the Actor's Issues tab. I reply there, and I'd like to hear which fields you miss.













