Company Career Pages Scraper
Pricing
Pay per event
Company Career Pages Scraper
Extract normalized public jobs from supplied career pages across five supported ATS platforms and JobPosting JSON-LD for recurring hiring feeds.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Stas Persiianenko
Maintained by CommunityActor stats
0
Bookmarked
4
Total users
3
Monthly active users
6 days ago
Last modified
Categories
Share
Extract normalized public job listings from supplied company career pages. Give the Actor one or more career-page URLs and receive consistent job records with title, company, location, department, employment type, description, publication date, job URL, and application URL.
The Actor detects public Greenhouse, Lever, Ashby, SmartRecruiters, and Recruitee
boards. It also reads standard JobPosting JSON-LD from other server-rendered career
pages. The result is one dataset ready for recurring hiring-intelligence feeds,
spreadsheets, job boards, and data pipelines.
What does Company Career Pages Scraper do?
The Actor turns several ATS-specific formats into one stable record shape.
It can:
- extract current public jobs from up to 50 supplied career pages;
- combine multiple companies and supported ATS platforms in one run;
- filter by keyword, location, or department;
- include full plain-text descriptions or omit them for compact feeds;
- deduplicate jobs by source and native identifier;
- stop at a global
maxItemslimit; - preserve canonical job and application links;
- report failed sources without discarding successful sources.
Unlike company-domain discovery tools, this Actor starts from the career pages you already know. That makes scheduled runs predictable and avoids guessing which page belongs to an employer.
Who is it for
Recruiting intelligence teams can refresh competitor hiring activity.
Job-board operators can normalize roles from customer-approved public sources.
Labor-market analysts can compare departments, locations, and role families.
Sales and investment teams can track hiring as a company-growth signal.
Data engineers can send a consistent dataset into warehouses or spreadsheets.
Candidates and career researchers can search several employer boards together.
Supported career pages
| Source | Example URL shape | Extraction route |
|---|---|---|
| Greenhouse | https://boards.greenhouse.io/company | Public board API |
| Lever | https://jobs.lever.co/company | Public postings API |
| Ashby | https://jobs.ashbyhq.com/company | Public posting API |
| SmartRecruiters | https://careers.smartrecruiters.com/Company | Public company API |
| Recruitee | https://company.recruitee.com | Public offers API |
| Other public pages | A direct career or job-detail URL | JobPosting JSON-LD |
The generic route requires server-rendered JobPosting structured data. A page that
loads jobs only after browser interaction is not silently treated as an empty board.
It fails with an actionable unsupported-page message.
What job data can you extract?
| Field | Meaning |
|---|---|
recordId | Stable source-prefixed identity used for deduplication |
sourceType | Detected ATS or jsonld route |
sourceId | Native job ID or canonical structured-data identity |
sourceUrl | Career-page URL supplied in the run input |
title | Published role title |
company | Employer name from the source or your override |
location | Published location, when available |
department | Department, function, or team, when available |
employmentType | Full-time, contract, internship, or source equivalent |
workplaceType | Remote, hybrid, onsite, or source equivalent |
remote | Explicit remote flag when the source provides one |
publishedAt | Publication timestamp when available |
updatedAt | Update timestamp when available |
description | Normalized plain-text description when requested |
jobUrl | Canonical public job detail URL |
applicationUrl | Public application URL |
scrapedAt | Time the Actor normalized the record |
Fields unavailable from a source are returned as null; the Actor does not invent
missing dates, workplace types, or departments.
How to scrape company career pages
- Open the Actor input page.
- Add one or more public career-page URLs under Career page URLs.
- Optionally add
companyNameto override an unclear ATS account name. - Add keyword, location, or department filters if needed.
- Choose the maximum number of jobs.
- Keep Include descriptions enabled for analysis, or disable it for compact feeds.
- Start the run.
- Open the Jobs dataset view or export JSON, CSV, Excel, or XML.
Start with a small limit when testing a new source. Once the output is correct, reuse the same input in an Apify Schedule for recurring refreshes.
Input parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
startUrls | array | required | 1–50 public career-page URLs; entries may include companyName |
keyword | string | empty | Case-insensitive phrase matched across normalized job text |
locations | string[] | [] | Keep locations containing any supplied value |
departments | string[] | [] | Keep departments or teams containing any supplied value |
maxItems | integer | 1000 | Global result limit from 1 to 10,000 |
includeDescription | boolean | true | Include normalized plain-text job descriptions |
All filters apply consistently regardless of whether a source uses an ATS adapter or standard JSON-LD.
Example input
{"startUrls": [{ "url": "https://jobs.ashbyhq.com/notion", "companyName": "Notion" },{ "url": "https://careers.smartrecruiters.com/SmartRecruiters", "companyName": "SmartRecruiters" }],"keyword": "engineering","locations": [],"departments": ["Engineering"],"includeDescription": false,"maxItems": 25}
This input builds one normalized engineering feed from two different ATS platforms.
Example output
{"recordId": "ashby:4bbfad88-0830-46c5-8d05-d95d17d583ca","sourceType": "ashby","sourceId": "4bbfad88-0830-46c5-8d05-d95d17d583ca","sourceUrl": "https://jobs.ashbyhq.com/notion","title": "Model Behavior Engineer","company": "Notion","location": "New York, New York","department": "Engineering","employmentType": "FullTime","workplaceType": "OnSite","remote": false,"publishedAt": "2026-06-18T17:06:55.020Z","updatedAt": null,"description": null,"jobUrl": "https://jobs.ashbyhq.com/notion/4bbfad88-0830-46c5-8d05-d95d17d583ca","applicationUrl": "https://jobs.ashbyhq.com/notion/4bbfad88-0830-46c5-8d05-d95d17d583ca/application","scrapedAt": "2026-08-11T20:30:00.000Z"}
The default dataset contains only validated job records. Source errors remain in the run log and are not billed as jobs.
How much does it cost to extract company career page jobs?
Pricing uses one Career page run event plus one Normalized job event per saved record. The current BRONZE prices are $0.001 per run and $0.0018 per job. Higher-volume Apify pricing tiers reduce the per-job amount.
Illustrative BRONZE totals:
| Saved jobs | BRONZE calculation |
|---|---|
| 1 | 1 run × $0.001 + 1 job × $0.0018 |
| 5 | 1 run × $0.001 + 5 jobs × $0.0018 |
| 10 | 1 run × $0.001 + 10 jobs × $0.0018 |
| 25 | 1 run × $0.001 + 25 jobs × $0.0018 |
| 100 | 1 run × $0.001 + 100 jobs × $0.0018 |
Filtering occurs before the per-job charge. Failed pages, duplicates, and rejected records do not create a Normalized job event. Apify plan and tier assignment determine the exact active unit price shown in Console.
Build a recurring hiring-intelligence feed
Create an Apify Schedule with a fixed list of career pages. Send each completed dataset
to a webhook, Google Sheets integration, or warehouse. Compare recordId values with
the previous run to identify newly opened and removed roles.
For change detection, retain recordId, publishedAt, updatedAt, and scrapedAt.
The Actor returns the current public snapshot; it does not maintain history or send
alerts by itself.
Export jobs to spreadsheets and data pipelines
Every run writes standard Apify dataset records. You can:
- download CSV or Excel for recruiting research;
- stream JSON into a warehouse;
- connect the dataset to Make or Zapier;
- trigger a webhook after scheduled runs;
- query only selected fields through the Dataset API;
- use
recordIdas an upsert key.
For compact feeds, set includeDescription to false before exporting.
Run with the Apify API using cURL
curl -X POST \"https://api.apify.com/v2/acts/automation-lab~company-career-page-jobs-scraper/runs?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"startUrls": [{"url": "https://jobs.ashbyhq.com/notion", "companyName": "Notion"}],"keyword": "engineering","maxItems": 10,"includeDescription": false}'
The response contains the run ID and default dataset ID.
Run with JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('automation-lab/company-career-page-jobs-scraper').call({startUrls: [{ url: 'https://jobs.ashbyhq.com/notion', companyName: 'Notion' }],keyword: 'engineering',maxItems: 10,includeDescription: false,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Run with Python
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ['APIFY_TOKEN'])run = client.actor('automation-lab/company-career-page-jobs-scraper').call(run_input={'startUrls': [{'url': 'https://jobs.ashbyhq.com/notion', 'companyName': 'Notion'}],'keyword': 'engineering','maxItems': 10,'includeDescription': False,})for item in client.dataset(run['defaultDatasetId']).iterate_items():print(item)
Use Company Career Pages Scraper with MCP
Add the Actor to Claude Code:
claude mcp add --transport http apify \"https://mcp.apify.com?tools=automation-lab/company-career-page-jobs-scraper"
Claude Desktop
Add this server entry to the Claude Desktop MCP configuration:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=automation-lab/company-career-page-jobs-scraper"}}}
Cursor
Open Settings → MCP, add a remote server named apify, and use the same
https://mcp.apify.com?tools=automation-lab/company-career-page-jobs-scraper URL.
VS Code
Add the remote Apify MCP URL to your workspace MCP configuration, then enable the
automation-lab/company-career-page-jobs-scraper tool for the chat agent.
Example prompts for MCP
- “Use Company Career Pages Scraper to extract engineering roles from these three company career pages.”
- “Run the career page Actor and return London jobs from this Lever board as a normalized dataset.”
- “Use the Apify MCP tool to build a feed from these Ashby, Recruitee, and SmartRecruiters pages.”
Reliability, retries, and partial failures
Transient timeouts, rate limits, and common server errors receive bounded retries.
Permanent 4xx responses are not retried blindly. The Actor fetches sources sequentially
to keep traffic conservative and stops scheduling output after maxItems.
If one URL fails but another succeeds, the run preserves the successful jobs and logs the failed source. If every URL fails, the run fails instead of returning a misleading empty dataset.
No residential proxy, browser, login, or cookie fallback is used. Supported public routes currently return the promised fields without those paid resources.
Limitations
- The Actor does not discover a career page from a generic company homepage.
- Supported ATS coverage is Greenhouse, Lever, Ashby, SmartRecruiters, and Recruitee.
- Other pages must expose server-rendered
JobPostingJSON-LD. - Workday, Oracle HCM, and browser-only custom portals are not supported by this Actor.
- Output completeness depends on fields published by the employer and ATS.
applicationUrlcan equaljobUrlwhen a source exposes one canonical link.- The Actor returns a current snapshot, not historical changes.
- A source can change its public endpoint or structured markup without notice.
Use source-specific Automation Lab Actors when you need an unsupported portal or source-specific fields beyond this normalized contract.
Responsible use and legality
Use the Actor only for public job data you are permitted to collect. Review employer website terms, robots guidance, applicable database rights, and local law. Do not use job data to discriminate unlawfully, identify private applicants, bypass access controls, or automate prohibited outreach.
Job descriptions may be copyrighted. Store and redistribute only what your use case allows. You are responsible for retention, attribution, and downstream processing.
Troubleshooting
The run says no JobPosting JSON-LD was found.
Use the direct ATS board URL when possible. The supplied custom page may load jobs only in a browser or may link to a supported ATS on another domain.
A supported board returns HTTP 404.
Check that the URL includes the current public company/account slug. Retired or renamed boards return a permanent error.
My filters returned zero jobs.
Run once without filters and inspect the source's exact location and department text. Filters use case-insensitive substring matching, but they cannot match fields the source does not publish.
Descriptions are empty.
Confirm includeDescription is true. Some list APIs or JSON-LD records do not publish
a description; that field remains null rather than being fabricated.
Related Automation Lab Actors
- Multi-ATS Career Site Jobs API for a focused Greenhouse and Lever workflow.
- Workday Jobs Scraper for public Workday career sites.
- Jobvite Careers Jobs Scraper for Jobvite boards and source-specific fields.
Choose this Actor when you already have several supplied career-page URLs and want one normalized dataset across supported platforms.
FAQ
Can I schedule this Actor?
Yes. Save the input, create an Apify Schedule, and use datasets or webhooks to compare successive snapshots.
Can I scrape several companies in one run?
Yes. Supply up to 50 career pages. maxItems applies across the entire combined run.
Does it scrape private or login-only jobs?
No. It handles public career pages only and does not accept credentials.
Does it use AI to infer missing job fields?
No. Normalization is deterministic. Missing source fields remain null.
Will filters cost extra?
No separate filter event exists. Only saved normalized jobs create item events.
Can I export directly to CSV?
Yes. Open the run dataset and choose CSV, Excel, JSON, XML, or another supported format.
How do I monitor new roles?
Schedule recurring runs and upsert or compare by recordId. History and alerts belong
in your downstream workflow.