Job Postings β Company Careers Pages and ATS Boards, One Schema
Pricing
from $0.80 / 1,000 job rows
Job Postings β Company Careers Pages and ATS Boards, One Schema
Every open role of a company from its own job board: give a domain, careers URL, ATS URL or LinkedIn company URL. 24 ATS systems (Greenhouse, Lever, Ashby, Workday, Workable, SmartRecruiters and more), one schema, hiring summary per company, new and closed roles on a schedule. $0.0008 per job.
Pricing
from $0.80 / 1,000 job rows
Rating
0.0
(0)
Developer
Pvalyou
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
πΌ Job Postings: every open role of a company, from its own job board
Give a company and get its open roles, straight from the job board the company itself publishes. $0.002 per company plus $0.0008 per job row, for sales teams reading hiring signals, recruiters, competitive and market research, and investors. Where a LinkedIn Jobs or Indeed scrape gives you an aggregator's copy of a vacancy, this job postings API reads the employer's own applicant tracking system, so a role that closed is gone and a role that is open carries its real apply link.
A domain (stripe.com), a website or careers URL, an ATS board URL or a LinkedIn company URL goes in. Out comes every open role in one schema: title, locations, department, seniority, workplace type, employment type, salary when published, the provider's posted date, the full description and the apply link, plus one summary row per company with the counts by department, seniority and country. Open one posting URL in full, or run the same list on a schedule and get each role flagged new or closed. Try it now with the prefilled input: Notion, Stripe and a Lever board.
The roles come from the applicant tracking systems companies publish their jobs on, read through those systems' public job-board APIs and the JobPosting data on career pages: 23 applicant tracking systems (Greenhouse, Lever, Ashby, Workday, Workable, SmartRecruiters and 17 more, listed below) plus any careers page that publishes JobPosting JSON-LD, all in one schema. No job aggregators, no data brokers.
What you get
- β The company's own board, found for you. Give a domain and the Actor reads the homepage and careers page, recognises the board behind it, and when the careers site hides its board behind JavaScript it tries the public ATS APIs directly. Stripe and Datadog both answer that way: 617 and 449 open roles from Greenhouse in under 15 seconds.
- β
One schema across 23 applicant tracking systems. Every row has the same fields whether it came from the Greenhouse jobs API, a Lever board, an Ashby board or Workday, with a stable
job_id, the provider, andboard_resolutiontelling you how the board was found. - β
A hiring summary per company. Open roles, counts by department, seniority and country, remote share, newest and oldest posting dates, and what the filters dropped. One row per company, charged once as
company_searchat $0.002, whether or not a board was found. Even a company with no board returns that row with the careers URL we saw and the steps taken. - β New and closed roles on a schedule. Monitor mode keeps the previous run's roles and flags what appeared and what closed.
- β Priced per row. $0.002 per company searched, $0.0008 per job row, $0.003 per posting opened, plus $0.00005 to start the run. 100 companies with 20 roles each cost $1.80.
π₯ Who uses company job postings?
- π Sales and outbound. Companies hiring for a function are buying for it. Run a target list weekly, filter titles by keyword, and read the summary's counts by department as a buying signal.
- π§βπΌ Recruiters and staffing. Live vacancies with apply links and full descriptions from the employer's own board, not a copy on an aggregator that closed last month.
- π Competitive and market intelligence. A competitor's open roles by office, team and seniority, month over month, from the same source every time.
- πΈ Investors. Headcount plans read from the hiring page: which functions, which countries, how many, how recent.
- π§βπ» Job seekers and career tools. A list of companies you like, run daily in monitor mode, with only the new roles surfaced.
- π€ AI agents and pipelines. Structured JSON with a stable id per role, callable from the Apify API, the MCP server and the Python and JavaScript clients. Events only, so it is eligible for agentic payment.
β¬οΈ Input: a mode and a list of companies or URLs
{"mode": "company","queries": ["notion.so", "stripe.com", "https://jobs.lever.co/anchorage"],"max_jobs": 200}
| Field | What it does |
|---|---|
mode | company (every open role, one summary per company), job (one posting URL in full), monitor (company mode with new and closed flags since the previous run). |
queries | One per line. Company and monitor modes: a domain, a website URL, a careers page URL, an ATS board URL or a LinkedIn company URL. Job mode: the URL of one posting on the employer's careers site or ATS. Each entry may also be an object with query, its own mode and any filter below, so one run can mix companies and postings. |
max_jobs | Rows per company after the filters, up to 500. |
include_description | Full description text and html on every row (default on). |
keywords, exclude | Title must contain any of the first list and none of the second. |
country | Two-letter code. Keeps roles with a location in that country. |
remote_only, department | Roles the employer marks remote. Department contains the word. |
posted_within_days | Roles the provider dates within this many days. Undated rows are dropped when this is set, and the summary says how many. |
max_jobs and the filters apply in company and monitor modes only. Job mode reads the one posting at the URL you give and returns it whole, description included.
A LinkedIn company URL is used only to find the company's website: the board is read there, LinkedIn itself is not read. When the website cannot be found from the LinkedIn page name, the summary says so and asks for the domain.
An empty entry, a company that is not a domain or URL, a job URL without a scheme, or a LinkedIn job URL is rejected before any paid step, as an uncharged error item, and the run still ends normally.
β¬οΈ Output: one dataset item per open role
Every item carries type, the query it came from, and charged.
type | Charged | Contents |
|---|---|---|
job | once per row (job_record) | one open role |
company_summary | once per company (company_search), whether or not a board was found | how the board was found, the counts, what the filters dropped, and in monitor mode the new and closed roles |
job_detail | once (job_detail), when the posting exists | one posting in full |
error | never | an error code and a message |
Every error item is free, and its code says which stage refused it:
| Where it comes from | Codes |
|---|---|
| Your input, before any call | invalid_input (not a domain or a URL, or an entry that is neither a string nor an object with query), empty_query, unknown_mode, invalid_url (job mode without https://), linkedin_not_supported (a LinkedIn job page) |
| The jobs service | no_match (job mode: no posting at that URL), rate_limited, unauthorized, upstream_error, api_error |
| The connection | timeout (no answer within 90 seconds), unreachable |
A job row from the first prefilled query:
{"type": "job", "query": "notion.so", "charged": true, "charged_event": "job_record","job_id": "8d87834209ebbbf21e6d", "title": "Software Engineer, Developer Platform","company_name": "Notion", "provider": "ashby", "source_job_id": "1fc309c8-da20-4ff2-84c7-8b863ece2b0a","source_url": "https://jobs.ashbyhq.com/notion/1fc309c8-da20-4ff2-84c7-8b863ece2b0a","apply_url": "https://jobs.ashbyhq.com/notion/1fc309c8-da20-4ff2-84c7-8b863ece2b0a/application","locations": [{"raw": "San Francisco, California", "city": "San Francisco", "region": "California", "country_code": "US"},{"raw": "New York, New York", "city": "New York", "region": null, "country_code": null}],"workplace_type": "hybrid", "employment_types": ["FullTime"],"department": "Engineering", "team": "Engineering", "office": null, "seniority": null,"salary": {"min": 213000, "max": 320000, "currency": "USD", "period": "year", "raw": "salary range for this role is $213,000 - $320,000 per year"},"posted_at": "2026-08-24T14:44:49.699000+00:00", "updated_at": null, "valid_through": null, "language": "en","board_resolution": "careers_page","description_text": "Who We Are Notion is the collaborative AI workspace where te ...", "description_html": "<h1>Who We Are</h1><p>Notion is the ..."}
Its company summary:
{"type": "company_summary", "query": "notion.so", "charged": true, "charged_event": "company_search","status": "matched", "resolved_domain": "notion.so", "resolution": "domain","board_provider": "ashby", "board_identifier": "notion", "board_url": "https://jobs.ashbyhq.com/notion","board_resolution": "careers_page", "board_completeness": "complete","open_roles": 130, "returned": 130, "dropped_by_filter": {},"by_department": {"Sales": 44, "Engineering": 17, "Marketing": 11, "Outcomes Architect": 11, "People": 10, "Early Career": 8, "Finance": 5, "Customer Experience": 5, "Security": 3},"by_seniority": {"manager": 33, "lead": 12, "intern": 3, "director": 2, "executive": 1},"by_country": {"US": 76, "JP": 16, "IE": 15, "FR": 7, "IN": 4, "KR": 4, "DE": 3, "GB": 3, "AU": 2},"remote_share": 0.0, "rows_with_posted_date": 130,"newest_posted_at": "2026-09-04T20:24:59.411000+00:00", "oldest_posted_at": "2025-07-25T22:00:31.199000+00:00","careers_url_seen": "https://www.notion.com/careers", "truncated": false, "elapsed_s": 3.8}
board_resolution says how the board was found: careers_page (recognised on the company's site), ats_url (you gave the board), board_token_guess (found by trying the public ATS APIs with the company's name and confirmed against the company), or verified_board (confirmed on an earlier lookup). posted_at is the provider's own published date and is null where the provider does not publish one.
In monitor mode each job row also carries new (true when the role was not in the previous run) and the summary carries new_roles, closed_roles and closed_job_ids. The first run of a company sets the baseline and flags nothing.
Export the dataset as JSON, CSV, Excel or XML, or read it through the Apify API. Lists and objects (locations, salary, by_department) are kept as JSON in CSV exports.
π° How much do company job postings cost?
| Event | Price | When it fires |
|---|---|---|
company_search | $0.002 | once per company processed, board found or not |
job_record | $0.0008 | once per job row returned after the filters |
job_detail | $0.003 | once per posting opened in job mode, when it exists |
| Actor start | $0.00005 | once per run |
| Invalid input, a posting that does not exist, rate limit, upstream failure | free |
The worked examples below are the event charges only. The Actor start adds $0.00005 a run, so the prefilled three-board run is $0.29 of events and $0.29005 in total:
- The prefilled input, three boards with 130, 617 and 28 roles at the default cap of 200: 3 x $0.002 + (130 + 200 + 28) x $0.0008 = $0.29.
- One company with 20 open roles: $0.018.
- 100 companies averaging 20 roles: $1.80.
- 1,000 domains where 400 have a board and 12,000 roles come back: $2.00 + $9.60 = $11.60.
- A monitor run on 50 companies every morning, 1,000 roles: $0.90 a day, with only the new ones to read.
- One posting opened: $0.003.
Filters are applied before charging: rows a filter drops are not job rows. Set a spending limit on the run for a hard cap.
πΊοΈ What is covered
- Systems (23). Greenhouse, Lever, Ashby, Workday, Workable, SmartRecruiters, Recruitee, Breezy, Teamtailor, BambooHR, iCIMS, Eightfold, Rippling, HiBob, Comeet, Zoho Recruit, Oracle Recruiting, SuccessFactors, Paylocity, GoHire, Dueto, TeamMe and Base44. On top of those, any careers page that publishes JobPosting JSON-LD is read the same way, which is not one of the 23.
- Companies. Any company whose careers page links to one of those systems or carries JobPosting data, plus companies whose board can be found by name on the public ATS APIs (Greenhouse, Lever, Ashby, Recruitee, Breezy). A careers site that renders its roster only with JavaScript and is on none of them comes back
no_board_found, with the careers URL we saw. - Fields. Whatever the board publishes. Descriptions are on almost every board. Posted dates are published by most ATS systems and by JSON-LD pages, not by all. Salary appears only where the employer prints it.
π How it works
- The input is read: a bare domain, a website URL, a careers URL, an ATS board URL, or a LinkedIn company URL (resolved to the website first).
- For a domain or website, the homepage and careers page are read and the board behind them recognised from its URL patterns, embedded configuration or JobPosting data. Pages are read as published, without browser rendering.
- If no board was recognised, the public ATS APIs are tried with the company's name as the board token. A board found this way is kept only when its postings point at the company's domain or name the company in most descriptions, so a namesake's board is never returned as yours.
- The board is read in full through its public API or page, the rows are normalised into one schema, the filters are applied, and the summary is computed over all open roles before the cap.
- In job mode the posting's provider is recognised from the URL and the posting read from the provider's own API, or from the JobPosting data on the page.
- Nothing is estimated or inferred and no language model is involved: every field is the employer's published value.
β±οΈ How long does a company take?
A board recognised on the careers page answers in 2 to 6 seconds. A board found by token guess takes 10 to 15 seconds. Each company has a 60 second budget in the service. Companies run one after another, so 100 companies take 5 to 15 minutes.
π Job postings API, clients and integrations
Run the Actor from the Apify Console, from the Apify API, from the Python or JavaScript client, from the Apify MCP server, or from Make, Zapier and n8n through the Apify integrations. Schedule monitor mode daily and set a webhook on run completion to pull the new roles into your own system.
from apify_client import ApifyClientclient = ApifyClient("<YOUR_API_TOKEN>")run = client.actor("pvalyou/job-postings").call(run_input={"mode": "company","queries": ["notion.so", "stripe.com", {"query": "https://jobs.lever.co/anchorage", "keywords": ["engineer"]}],"max_jobs": 100,"include_description": False,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["type"], item.get("company_name"), item.get("title"), item.get("posted_at"), item.get("charged"))
π Data, licences and privacy
- The employer's own board. Roles are read from the job-board APIs the applicant tracking systems publish for exactly this purpose (an employer switches them on so its jobs can be embedded and syndicated) and from the JobPosting data career pages publish for search engines. No job aggregators, no data brokers.
- Not LinkedIn. LinkedIn's terms forbid automated collection, so LinkedIn job pages are not read. A LinkedIn company URL is only used to find the company's website.
- Pass-through. Each company is read from its board and passed through to your run. The results live in your own Apify dataset. Operational logs keep the query, timing and the billing outcome. Monitor mode keeps the job ids of your previous run in a named key-value store in your own account, nothing else.
- No applicant or recruiter data. Only the published vacancy: title, description, location, department, dates and links. Never applications, candidates or internal ATS fields.
- Not an offer of employment. A row is the employer's published vacancy at the moment of the run. Apply on the employer's site.
- No access controls bypassed. No CAPTCHA solving, no logins, no browser rendering, robots directives respected.
β FAQ
Is the data live?
Yes. Every company is read from its board at the moment of the run, whichever way the board was found.
Why did a company come back with no board?
Its careers site renders the roster with JavaScript and is on none of the supported systems, or the domain has no careers page we could find. The summary carries the careers URL we saw and the steps taken. If you know the board URL, send it as the company input.
Why is posted_at empty on some rows?
The provider does not publish a posting date for that board (a few systems and some career pages). Rows with a date carry the provider's own date, never the date we first saw the role.
How is the monitor baseline kept?
In a named key-value store in your own account, job-postings-monitor-<task id>, under the key MONITOR_STATE: a list of job ids per company. The first run of a company sets the baseline. Run the same saved task on a schedule and the baseline carries over. Delete the store to start over.
Is it legal to use?
The job-board APIs are published by the applicant tracking systems for employers to syndicate their vacancies, and career pages publish JobPosting data for search engines. Job postings are public by design. Use them in line with the laws of your jurisdiction.
Is there a free tier or a trial?
Every rejected input, every company without a board and every failed query is free, and Apify's free plan credit covers the first paid lookups. There is no subscription.
π Limits
- Up to 1,000 entries per run, 500 rows per company, 60 seconds per company in the service and 90 in the Actor.
- Pages are read as published, without browser rendering.
- LinkedIn, job aggregators and staffing boards are not read.
- Descriptions are capped at 20,000 characters of text and 40,000 of html.
- Entries run one after another. Exact duplicates within a run are collapsed. The run's spending limit is honoured.
π Works well with
The same company domain opens the other five: Company Enrichment API for firmographics, classification and funding, Website Liveness Check to drop the dead and parked domains before you run a list here, Company Registry Lookup for the official registry record, Patent Lookup for the company's patents, and LinkedIn Person Enrichment for the career record of the hiring manager named on a posting.
π¬ Support and feedback
Found a company whose board was missed, a system you need, or a row that looks wrong? Open an issue on this Actor's page with the company, the mode and what you expected. Issues are answered by the developer.
π Changelog
- 0.1 (2026-09-08) First public release: company, job and monitor modes, 23 applicant tracking systems and JSON-LD career pages, three priced events.