If you recruit, prospect companies that are hiring, or run a job board, you do not want 5,000 job rows every day. You want the 40 that appeared since yesterday and match your filters. Job aggregators make that hard: duplicates, stale copies, and no clean fields for remote, contract type or salary.
The answer: read the employer's own career page feed, filter before you pay, and switch on "only new jobs" for a daily schedule. The Actor Company Careers Page Scraper does this. You give it company websites (stripe.com) or tick "search all companies" with a keyword. It finds which applicant tracking system sits behind each careers page and reads that system's public endpoint.
The input
from apify_client import ApifyClient client = ApifyClient("<YOUR_APIFY_TOKEN>") run_input = { # Option A: a company list # "companyDomains": ["stripe.com", "figma.com", "notion.so"], # Option B: search an index of open roles, no list needed "searchAllCompanies": True, "keywords": ["data engineer"], # Filters, applied BEFORE you are charged "workArrangements": ["REMOTE", "HYBRID"], "employmentTypes": ["FULL_TIME", "CONTRACT"], "minYearlySalary": 90000, "excludeAgencies": True, "companySizes": ["201-500", "501-1,000", "1,001-5,000"], # Only jobs this search has not delivered before "onlyNewJobs": True, "maxTotalChargeUsd": 1, } run = client.actor("om_kh/careers-page-scraper").call(run_input=run_input) for job in client.dataset(run["defaultDatasetId"]).iterate_items(): print(job["title"], "|", job.get("company_name"), "|", job.get("work_arrangement")) The filters that run before billing include work arrangement (remote, hybrid, on-site), contract type, countries, a minimum yearly salary (hourly and monthly pay are converted), no staffing agencies, industries and company size bands. A job you filtered out is never charged.
"Only new jobs" is the daily switch
Set onlyNewJobs to true and schedule the run every morning. The first run delivers everything that matches. After that, each run delivers only the jobs this same search has not delivered before, and jobs already delivered are never charged again. Give memoryKey a name if you want two tasks to share the same memory.
What a row contains
Each row has the title, company, location, posting date, apply link and (by default) the full description. On top of that, plain rules read these facts from the posting, with no AI step and no extra cost:
| Field | What it holds |
|---|---|
work_arrangement | REMOTE, HYBRID or ON_SITE (plus office_days_per_week when a hybrid posting says it) |
employment_type | FULL_TIME, PART_TIME, CONTRACT, INTERNSHIP... |
city, region, country | the first location split into parts, country as a 2-letter code |
salary_period, salary_yearly_min, salary_yearly_max | the pay band and its yearly equivalent, so hourly and yearly jobs compare |
benefits | health, equity, paid time off, learning budget... |
company_industry, company_size, company_headquarters | from Wikidata: for example Stripe = financial services, 5,001-10,000 employees |
A field stays empty when the posting does not say it; nothing is guessed. Measured on 592 live roles (Stripe, Palantir, Notion, Airbnb) on 28 October 2026: city found on 84%, country 75%, on-site/hybrid/remote 67%, benefits 74%, contract type 51%. So expect gaps, and tick "Not stated" in a filter when you want to keep jobs that do not say.
Google Jobs too
If you also need Google Jobs results, the same author's Google Jobs Scraper covers that source. For provider-level control across the main ATS systems there is the ATS Jobs API, which returns the same row format.
Run it on a schedule with Make or n8n
- In Apify, save the run input above as a Task and add a daily Schedule (for example 7:00).
- Make: Apify > Run an Actor, then Apify > Get Dataset Items, then Google Sheets > Add a Row. n8n: the Apify node, operation Run Actor and get dataset, then a Google Sheets node.
- Because of
onlyNewJobs, the sheet only receives new rows, so the same flow can notify Slack or a CRM.
Pricing
$1.50 per 1,000 jobs delivered (FREE-tier price; paid Apify plans get a discount), the first 3 jobs of every run are free, and the careers page Actor adds a small start fee of $0.005 per run, so put many companies or one broad search in a single run. The ATS Jobs API has the same per-job price without the start fee. The Pricing tab of the Actor page always shows the current numbers.
Use it from an AI agent
Add om_kh/careers-page-scraper as a tool in any MCP client through https://mcp.apify.com; the agent passes the same JSON as the run input and reads the dataset back.
More tutorials: https://omarkhandji-commits.github.io/apify-actor-catalogue/guides/
Disclosure: I built this Actor.
