Jobs Feed: Greenhouse, Lever, Ashby & Workday Jobs API | $1/1K
Pricing
$1.00 / 1,000 job rows
Jobs Feed: Greenhouse, Lever, Ashby & Workday Jobs API | $1/1K
Open jobs from a company's own job board in one schema or as an XML job feed for job boards. ATS: Greenhouse, Lever, Ashby, Workday, Workable, Breezy HR, Personio, Rippling. Give a name, domain or careers URL (Ashby/Rippling: board URL). $0.001 per job; companies not found or unconfirmed are free.
Pricing
$1.00 / 1,000 job rows
Rating
0.0
(0)
Developer
Siftsmith
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Security
Limited permissionsShare
Greenhouse, Lever, Ashby & Workday Jobs API
Get a company's open jobs straight from its own job board, in one schema across 8 applicant tracking systems (ATS): Greenhouse, Lever, Ashby, Workday and 4 more. Give a company name, a domain or a careers URL (for Ashby, the board URL or ashby:<slug>, unless the company's own site links its board); mix them freely in one run.
$1 per 1,000 job rows ($0.001 each), no subscription. Companies not found are free. You need no ATS account, API key or proxy: the jobs come from each company's public job board. Run it from the Apify Console, the Apify API or an AI agent.
Who it's for
- Recruiters and staffing agencies tracking openings at a list of client or target employers.
- Job boards and aggregators that need fresh listings from company career pages in one format.
- Sales and RevOps teams who want to see which target accounts are hiring, and for which roles, before reaching out.
- Analysts and investors following hiring across a portfolio or a market.
Paste your whole employer list
Put every company in companies, one per line: names, domains, careers URLs or rows pasted from a spreadsheet. There is no cap on the length of the list and no keyword limit, and one run covers it all.
- A count for every company: each company gets one free status row with
found, the ATS and board,openJobsand the jobs posted in the last 30 days, so you can see at a glance which employers on your list are hiring and which have no board we can read. - A cap per company:
maxJobsPerCompanykeeps one big employer from filling the run, andmaxItemscaps the whole run's spend. - Give domains, not just names: many companies' job boards don't use their brand name (Glean's Greenhouse board is
gleanwork). A domain also avoids another company with the same name: the name "Motive" matches a creative agency's board, not Motive's (gomotive). If you already know a company's board, pass it (greenhouse:gleanwork) and it's read as given. Ashby gives no company name to check a guessed board against, so an Ashby board guessed from a name, or from a domain whose own site doesn't link it, comes back as a free low-confidence status row that names the board to pass (Clay's isashby:claylabs). An Ashby board the domain's own site links is read like any other linked board (next point), and charged when it ties back to that company:m-kopa.com's careers page linksashby:M-KOPA, so its jobs are charged. - Paste the careers page URLs you already have: for a link like
figma.com/careers(or a bare domain), the job board the company's own page links is read first, and its jobs are charged only when the board ties back to that company: its website or job links are on the company's site, or its name is the domain's. A page that links several employers' boards, or a board nothing ties to the company, is free, with the boards listed so you can pass the right one. A page that links no board is matched by its domain. A careers URL we can't read (its robots.txt asks us not to, it is not found (404), it answers 403 or another error, a bot challenge blocks it with a 403 or 503, or it times out) gets a free status row (notRead) and is not guessed from its domain; give the bare domain to have it matched by domain instead. Some companies use a board name their page doesn't lead to; for those, pass the board:greenhouse:tripactionsfor Navan,greenhouse:talkdesk2for Talkdesk,ashby:checkout.comfor Checkout.com, or a Rippling board's URL. - Not found is free: a company with no board on the 8 supported ATSes costs nothing, and its status row says why.
No list yet? Start from the companies on the 2025 Forbes Cloud 100
Set companyList to forbes-cloud-100-2025 (in the Console: Ready-made company list) and clear companies (the Console form starts with 8 examples), or keep your own companies and the list is added after them.
- What's in it: the 84 companies on the 2025 Forbes Cloud 100 whose job board is on an ATS this Actor reads: Greenhouse 44, Ashby 34, Workday 5 and Rippling 1. Each is listed as its exact board, so nothing is guessed. The other 16 use Comeet, SmartRecruiters or Jobvite, or have no public board we found.
- Where it comes from: we looked up each company's job board and checked it on 2026-10-09 (a few rows corrected on 2026-10-10 and 2026-10-12). Forbes chose the companies; we are not affiliated with or endorsed by Forbes, and Forbes had no part in the job-board lookups. The list carries no Forbes ranks. The boards and the full dataset are on which ATS SaaS companies use.
- What it costs: at 10 jobs per company (the form's starting value, and the cap with this list when
maxJobsPerCompanyis left empty) a run returns at most 840 job rows, so at most $0.84. RaisemaxJobsPerCompanyfor whole boards. - Boards change: a board that has since closed, moved or has no open jobs gets a free status row, and the run carries on. Every row from the list carries
presetCompany(the company's name) andpresetList. - Already typed some of them? A board you typed is not added twice. If you typed a company's name or domain and it was matched to the same board, its jobs come once, on your row, and the list's entry gets a free
duplicateOfstatus row.
Quick start
{ "companies": ["stripe.com", "gong.io", "https://jobs.lever.co/spotify"] }
You get one row per open job at each company, plus one free status row per company. Workday jobs are found by company name or domain too (see below), or give the board URL, for example https://acme.wd1.myworkdayjobs.com/External.
Using CSV, Excel or Google Sheets? Filter the
typecolumn tojob. Every run writes two kinds of row to one dataset: job rows (type=job) and one status row per company (type=company). Status rows have empty job columns. The Console's Jobs and Companies (status) views pick the columns for each, but an export or API call still includes both kinds of row, so filter ontype.
What you get: one schema for ATS jobs
- One row per open job (
type=job): title, location (on Workday, alsolocationsandlocationsCountfor a job posted in several places), remote, department, posted date withpostedAtPrecision(exact;dayfor Workable and Workday dates;fallback-updatedwhen Greenhouse gives only the last-updated time), job URL, the ATS and board it came from, and a stableglobalId(ats:slug:jobId). A field the board doesn't give is empty, never guessed. country,countries,countrySource:countryis an ISO code (US,GB) set only when the job board's own country field or the location clearly names one country for every place of the job (London, United Kingdom,Remote - US,United States (Remote)). A bare city (Dublin) or a US state (San Francisco, CA) gives no country unless the board's own field names one. A region (Europe,EMEA,North America) or a bareRemotegives none, even when the board's field names a country (that is often the company's head office). The field is also not used when the location text clearly names a different country (Mumbai, India). An unclear country is left empty, never guessed.countrieslists every country of a job posted in several countries (Remote, Canada; Remote, United StatesgivesCA,US) and is null when any of its places names none.countrySourcesays where it came from:ats(the board's own country field, or a Greenhouse office's address) orlocation(read from the location text).- Greenhouse boards that give a work mode instead of a place (
Hybrid,Distributed,N/A): the place and country come from the board's own office list, which can differ from the job's description (we don't read descriptions for places). The mode is inworkplaceType, and alocationKeywordssearch matches it.- How often it's filled (measured 2026-10-11 on 82 job boards from the 2025 Forbes Cloud 100, 10,329 jobs): 64% of jobs have a
country. By ATS: Ashby 88% (31 boards), Greenhouse 50% (44), Workday 33% (5); Rippling 49% comes from one board. The 82 include one SmartRecruiters board (100%), which we no longer read (see Supported ATS job boards). Greenhouse, Workday and Rippling locations often name only a city or a US state, so those jobs get no country. A second count, written separately and run on the raw job board APIs, matched within 0.1 point for every ATS (for Rippling, on the location text alone), and a hand check of 100 jobs found no wrong country. On 2026-10-12 locations such asUnited States (Remote),Ireland - DublinandLondon (UK)started giving a country; two separate counts over the same jobs gave the figures above (64.4% overall), with no job moved to a different country. Lever, Workable, Breezy HR and Personio aren't measured yet: no board in the sample uses them.
- How often it's filled (measured 2026-10-11 on 82 job boards from the 2025 Forbes Cloud 100, 10,329 jobs): 64% of jobs have a
requisitionId,hiringOrganization,timeType,remoteType(Workday jobs):requisitionId,hiringOrganization(the employing legal entity as the employer writes it, often with a number in front, for example084 PGIM Quantitative Solutions LLC) andtimeType(for exampleFull time) come from the job's own page, unchanged. That page is read for every Workday job when descriptions are on, and otherwise only for a job in several places or with no place in the list (see below), so with descriptions off a Workday job in one place has these three empty. They are also empty when the page couldn't be read or doesn't give them.remoteTypeis the work type the employer's Workday job list gives (for exampleHybrid), empty when the list gives none. All four are empty on the other ATSes.boardJobUrl(Greenhouse jobs): the job's own page on Greenhouse, with the title, description and apply form. On many Greenhouse boards,urlis the company's careers page (?gh_jid=), and some of those pages show the job only after a script runs or refuse requests that don't come from a browser, so a link checker or job feed gets no job from them.boardJobUrlopens the job on Greenhouse for as long as it is posted; once the job closes, the link redirects to the company's job list on Greenhouse. It is empty on the other ATSes, whereurlis already the job's page on the ATS.- Match confidence on every job row:
explicit(you gave the board),highormedium, plusmatchedBy:board(you gave it),name(from the company's name or its domain's name),site(a board whose name only partly matches, kept because the company's own site links it or lists its jobs) orcareersPageLink(the board the company's own careers page or homepage links, kept because it ties back to the company). A job from the wrong company is worse than no job, so you can see the match and filter on it. - One free status row per company (
type=company): found or not, why not, the board to pass explicitly next time, the board size, and hiring signals (jobs posted in the last 7, 30 and 90 days, a hiring score, top departments and technologies). An input whose board is already in the run (Stripeandstripe.com) gets a free row withfound: true,duplicateOfand no jobs, so each job is delivered and charged once.
Example output
A job row from a run on stripe.com (abridged; read 2026-10-08):
{"type": "job","globalId": "greenhouse:stripe:8172508","title": "Abuse Investigator","companyName": "Stripe","companyDomain": "stripe.com","ats": "greenhouse","boardUrl": "https://boards.greenhouse.io/stripe","matchConfidence": "high","matchedBy": "name","url": "https://stripe.com/jobs/search?gh_jid=8172508","boardJobUrl": "https://job-boards.greenhouse.io/embed/job_app?for=stripe&token=8172508","location": "Dublin","remote": false,"department": "Security Analytics","postedAt": "2026-09-03T13:32:53-04:00","postedAtPrecision": "exact"}
The same run's free status row for Stripe said found: true, openJobs: 727 and postedLast30d: 288, with the top departments and technologies.
Supported ATS job boards (8): Greenhouse, Lever, Ashby, Workday and more
- Matched from a name or domain: Greenhouse, Lever, Workable, Breezy HR, Personio.
- Ashby: board, or a domain whose site links it: an Ashby board is read from
ashby:<slug>or its URL, or when a domain's own site links it and the board ties back to that company (a linked board, above). One guessed from a name, or from a domain whose site doesn't link it, comes back as a free status row naming the board to pass. - Workday by company name: postings checked first; unconfirmed sites are free. A name or domain with no confirmed board on the other six ATSes, and no Ashby board found for it, is also looked up on Workday: the company's Workday site is found from its public robots.txt, and a few of its postings are read to check they name this company as the employer (or, for a domain, that the domain's own site links the Workday site or its postings give the domain). Only then is it matched (
medium, orhighfor a domain tie). A Workday site that exists under the name but isn't shown to be this company ("Liberty" finds Liberty University's) comes back as a free status row naming the site, never charged. Known gaps: companies whose Workday name differs from their brand (Johnson & Johnson isjj), domains whose homepage doesn't link the Workday site in its HTML, and only the main public site is read. A single word can also be another organisation's name, so a one-word name ("Prudential", "NVIDIA", "AT&T") is matched by name only when a sampled posting's employer is that name, or the postings name it on its own and give its own .com as an address (3M's give 3m.com). Otherwise it comes back as a free status row naming the site and saying why ("Prudential" finds Prudential plc's site for Asia and Africa, not Prudential Financial's, and its row asks for the company's website). CheckworkdayEvidenceon name-only matches, give the domain with the name and setminMatchConfidencetohighso a Workday match is charged only when the domain confirms it (this also drops medium matches on the other ATSes), or pass the board URL. It is read unless that Workday site's robots.txt disallows it (notRead: "robots.txt") or can't be read (notRead: "robots.txt unavailable"; try again later). Either way the row is free. - Board URL needed for Rippling: Rippling is never guessed. Give the board URL or
rippling:slug. A Workday board URL (https://acme.wd1.myworkdayjobs.com/External) orworkday:tenant:wdN:siteis read as given. - Workday remote:
remotefollows the employer's own work type on Workday when the job list sets one (some employers set it only on the job's own page, and that page's work type is used only for jobs in several places or with no place): Remote is remote. Any work type that mentions hybrid ("Hybrid", "Hybrid (Remote & On-site)", "Remote or Hybrid", "Remote/Hybrid") is not, and neither is an on-site, office or field work type, even when the place says "Remote - US". Otherwise the place decides, and a place that says hybrid doesn't count as remote. - Workday jobs in several places, or with no place in the list: Workday's job list shows only "5 Locations" for a job posted in several places, and some employers' lists show no place at all. For these, each job's own page is read for the real places.
locationthen lists them all,locationshas them one per item andlocationsCountcounts them. Each such job takes one extra request, made one at a time, and only for jobs the run can return (with descriptions on, every Workday job's page is read this way; see Descriptions below). If a job page can't be read, or Workday asks us to slow down or stop,location,locationsandremoteare empty, andlocationsCountstill gives the number of places when the list gave one. A Workday job in one place has its place inlocation, andlocationsandlocationsCountare empty, as on every other ATS. WithlocationKeywordsorremoteOnly, a job whose places couldn't be read is left out (and not charged), and job pages stop being read oncemaxJobsPerCompanyormaxItemsis reached or the run nears its timeout. The status row counts the jobs left out this way injobsLocationUnchecked; when the reading stopped early, it also saysjobsTruncated,jobsAvailableis a minimum, andreasonsays what stopped it (sourceBlockedwhen Workday did). - Up to 1,000 jobs per Workday board: Workday lists jobs page by page, and a run reads at most 1,000 from each board. A bigger board's status row says
jobsTruncatedwithreasonsourceCapand gives the board's own total injobsAvailable(on some Workday boards the total Workday reports stops at 2,000, so therejobsAvailablecan say 2,000 for a bigger board). Rippling reads up to 1,000 listings (a job is listed once per place), and its status row has no board total. - Any of the 8 by name:
greenhouse:stripe,lever:palantir,ashby:rampand so on skip matching. - SmartRecruiters links are recognised, not read: SmartRecruiters asks automated tools not to read its job API (robots.txt), so we don't. A SmartRecruiters board, link or
smartrecruiters:entry gets one free status row that says so (notRead), with no job rows.
Other systems (iCIMS, Taleo, SuccessFactors, Oracle and the rest) are not supported. A company with no board found on the 8 gets a status row saying so, free.
Input
| Field | What it does |
|---|---|
companies | Required unless you choose companyList. Names, domains, careers URLs or job board URLs, one company per line. An entry that holds several lines is read as one company per line. A pasted spreadsheet row is looked up by, in order: a job board in any field (a board URL or greenhouse:acme); a website or work email that agrees with the company name; otherwise the first field, skipping row numbers (number fields at the start of the line only: a phone number, date, ZIP code or ID later in the line counts as a field, so Goodwin; 555-0100; KPMG is free) and company pages on directories (LinkedIn, Crunchbase). So 1; Adyen; Amsterdam; adyen.com is looked up as adyen.com. A row with no website, email or job board whose first two fields are each one word written like a name (Jane, Doe; not an acronym like IBM or a word like Corp or Labs) reads as a person's name. A row whose first field is a common US first name, in any letter case, also reads as a person's name, even when the next field is an acronym or several words: David; IBM is free, and TAYLOR; BROWN; ACME CORP is looked up as ACME CORP. This also frees a company named like a person, such as Harper; San Francisco. A row whose second field is a common US first name after a one-word surname also reads as a person's name, in any letter case: FERGUSON; JOHN; IBM is free, and parsons; mary; acme corp is looked up as acme corp. This also frees a company whose second field is a city or other word that is also a first name, such as TESLA; AUSTIN. A row of three or more fields whose first field is one word of letters is never looked up by that first field, whatever its second field holds: a given name however it is written, initials, a placeholder such as N/A or -, a job title or a department. So Ferguson; John Q.; IBM, Stevens;; IBM, PARSONS; N/A; IBM and Ferguson; Software Engineer; IBM are free. A blank last field counts as a field when two or more fields come before it, so Ferguson; J.; (a blank company column) is free too, and so is Stripe; US;. Stripe; (one field and a stray delimiter) and a Markdown table row such as ` |
companyList | A ready-made list added after companies: forbes-cloud-100-2025 (84 boards, see above). Leave it empty for your own list only. |
minMatchConfidence | medium (default) or high. A board below it returns no jobs and costs nothing; its status row gives the board to pass explicitly. A low-confidence match is never charged. |
titleKeywords | Keeps a job when its title has any keyword as whole words (case-insensitive, accents ignored): ML keeps "ML Engineer", not "HTML Developer"; java keeps "Java Developer", not "JavaScript Engineer". A phrase matches when its words appear together and in order: machine learning keeps "Senior Machine Learning Engineer". End a keyword with * and its last word also matches longer words: engineer* also keeps "Engineering Manager", and software* keeps "Softwareentwickler". Plurals and longer forms need * too: design* keeps "Product Designer", node* keeps "Node.js Developer". |
excludeTitleKeywords, locationKeywords, departmentKeywords | Case-insensitive "contains any" filters: excluding intern also drops "Internship" and "International Sales". locationKeywords matches the location text or workplaceType; for a Workday job in several places that is all of its places. For remote jobs, remoteOnly is the surer filter. |
remoteOnly | Remote jobs only. A job whose remote status is unknown (remote empty) is left out. |
countries | Jobs in any of these countries: ISO codes (US, DE) or English names (Germany). A job is kept when one of its countries is in the list. A job whose country is unknown is left out and not charged; each company's status row counts the jobs left out in countryUnknown (no country known) and countryOther (another country). An entry that isn't a country stops the run before anything is looked up or charged. |
postedWithinDays | Jobs posted in the last N days. Jobs with no date are kept unless requirePostedDate is on. Workday jobs listed as posted 30+ days ago are left out when the window is 30 days or less; with a longer window they count as undated (see requirePostedDate). Workday's job list says only "Posted 30+ Days Ago" for older jobs; with a longer window, those jobs get their date from the job's own page, which is read for every Workday job when descriptions are on, and otherwise only for a job in several places or with no place (and not when requirePostedDate is on). A Workday job whose page isn't read has no date. |
requirePostedDate | With postedWithinDays, also drops jobs that have no posted date. With descriptions off, that includes every Workday job listed as "Posted 30+ Days Ago", because its page isn't read for a date. With descriptions on, a Workday job is dropped this way only when its page couldn't be read in that run or gave no valid date. |
maxJobsPerCompany | Default 1,000, or 10 with companyList (the Console form starts at 10 for a quick first run). Jobs past it are not returned or charged. |
maxItems | Cap on job rows, and so on spend, for the whole run. |
includeDescription | Adds the description text on Greenhouse, Lever, Ashby, Workable, Rippling and Personio, and on Workday, where it is read from each job's own page, one job at a time per employer and for up to 15 minutes per employer per run, and also gives the job its posted date. Workday descriptions have contact details removed by pattern (see Descriptions below). Off by default to keep rows small; always on with feedOutput. |
maxConcurrency | Companies processed in parallel (default 5, up to 20). |
Job feed for job boards
Turn on feedOutput and each run also keeps an XML job feed at one URL that doesn't change. Paste that URL into your job board software's XML import, schedule the Actor daily, and the board stays in step with your employer list. Jboard, Job Boardly, JobBoard.io, SmartJobBoard, Niceboard and Cavuno can import a feed from a URL. Cavuno includes recurring XML feeds on every plan, from $39 a month, and checks the URL every 1, 3, 6, 12 or 24 hours. Its docs say it accepts a flat <source><job> feed like this one and uses a job's reference number as its identity, so map referencenumber to that field on the first import. The others offer it only on some plans: Jboard's XML importers are on its Advanced plan ($449 a month), and Niceboard's Core plan allows 10 import runs a month, which is too few for a daily refresh. Jboard and JobBoard.io only accept jobs that have a description (see Descriptions below). JobBoard.io wants posting dates as MM/DD/YYYY, and the feed's date is in RFC 1123 form (Mon, 12 Oct 2026 08:00:00 GMT), so leave the date unmapped there; JobBoard.io then uses the import time.
- Where the URL is: in the run's
OUTPUTrecord (feedUrl, with the number ofjobs), its status message and its log. The feed is the same URL on every run with the same key. - What's in it: job rows only, never the status rows, in one Indeed-style layout:
title,company,url,referencenumber(the job'sglobalId, a stable unique ID),date,location,country,remote,department, anddescription(always on withfeedOutput, where the ATS gives one). A field the board leaves empty is left out.companyis the name the board gives; when it gives none (Ashby boards never do), it is the company as you typed it, but only if that is a plain name or domain (Stripe,stripe.com). For a board, a URL, an email or a pasted row it is left out, andOUTPUTcounts those jobs injobsWithoutCompany, with a warning in the log. To fill it, set the company in your job board's import, or give the company's name or domain on its own line instead (for an Ashby board, only a domain whose own site links that board and whose name the board's slug matches works; otherwise keep the board and set the company in your import).dateis left out when the board gives no posted date, or gives only a last-updated time. - How it updates: each run keeps the jobs that are still open, drops the ones that closed, and adds the new ones. A company whose lookup failed or was skipped keeps its jobs until a later run reads its board. A company that is not found, or found below your match confidence, keeps its jobs for up to 7 days after they were last seen, so one missed run doesn't remove them; after that they leave the feed. A company you remove from the list, or that is now found on a different board, leaves the feed at once. On a board past the source's 1,000-job limit (large Workday boards), a job beyond that limit can't be checked, so it stays for up to 30 days after it was last seen. It works with or without
onlyNewJobs, and writing it costs nothing extra: the feed holds job rows already charged. WithonlyNewJobs, a daily run charges only the jobs that are new since the last run, and the feed still keeps every one that is open. - Keys: give each list its own
feedKey. WithonlyNewJobs, the feed uses thestateKeyinstead (leavefeedKeyempty or set it to the same value). Otherwise, without afeedKey, a saved task uses its task ID and other runs usedefault. Use a new key when you change the filters: jobs already in the feed stay while they are open, even if a new filter would leave them out. If you turn the feed on for astateKeythat earlier runs already used, the jobs those runs returned aren't in the feed; use a newstateKeyto start with every open job. - Anyone with the URL can read the feed. The URL is also in the run's log and status message, so share a run only with people who may read the feed. It needs no Apify token and gives access to that one record only, and the jobs in it are already public on the employers' own boards. To retire a URL, use a new key, then delete the old key's two records (
<key>.xmland<key>.json) from the key-value storecompany-jobs-feed(Apify Console, Storage, Key-value stores). The old URL stops working once its record is deleted; don't reuse that key, or the old URL works again. - Storage: the feed is kept in that key-value store in your own Apify account, which outlives the runs and counts toward your account's storage.
- Size: the feed keeps every job that a run under this key delivered, for as long as the job stays open; with
onlyNewJobsthat grows to every open job on the listed boards that passes your filters.maxJobsPerCompanyandmaxItemslimit what one run adds, not the feed. The form startsmaxJobsPerCompanyat 10, so clear it for full boards. Jboard's first import of a new feed takes the first 1,000 jobs and brings in the rest on its next daily run; on a Jboard trial, an importer stops at 1,000 jobs. Descriptions are always included in full, so a job is about 6.5 KB of XML and the feed holds about 1,200 jobs within its 8 MB limit. Workday descriptions vary more in length by employer, so a feed of Workday jobs holds about 800 to 2,200 within that limit (measured on live jobs, October 2026). Past that, the newest jobs are kept and the oldest are left out of the XML (OUTPUTreportsjobsOmitted); split the companies across new feed keys to keep every job. A much larger feed (roughly 5,000 to 13,000 jobs with descriptions, depending on how well they compress) is over the limit of the feed's saved record: the XML still follows that run, but the saved feed isn't updated, soOUTPUThas afeedWarning, and withonlyNewJobsthe jobs that run returned stay in the dataset but leave the feed on the next run. Split the companies across new feed keys well before that. - Descriptions are always on with
feedOutput, in the feed and in the dataset rows. They come from Greenhouse, Lever, Ashby, Workable, Rippling, Personio and Workday boards. In Workday descriptions, email addresses, phone numbers and labelled recruiter or contact lines are removed automatically. The scrub matches patterns, so a contact written an unusual way, such as a name inside a sentence, can remain. Check descriptions if your board must show none. Descriptions from other ATSes are delivered as the employer wrote them. Workday jobs also get their posted date from the job's own page. Breezy HR jobs have no description: they stay in the feed without adescription, and Jboard and JobBoard.io reject them. Workday job pages are read one at a time per employer, for up to 15 minutes per employer per run. WithonlyNewJobs, a Workday job whose page couldn't be read in that run (that budget or the run's timeout ran out, or Workday asked us to slow down) is held and read again on the next run (the status row counts it injobsDescriptionPending, not charged); withoutonlyNewJobs, it is delivered without a description. A Workday job that closed between the list and its own page isn't delivered or charged (jobsClosed).OUTPUTreportsjobsWithoutDescription, and the log names their ATSes. For a Jboard or JobBoard.io feed, leave those employers out of that feed's list. A feed key written before descriptions were always on keeps its older jobs without a description while they stay open (withonlyNewJobsthey are never refreshed), so start such a feed on a new key. - Jobs without a location: a job whose board gives no location is written without a
location, andOUTPUTcounts it injobsWithoutLocation. JobBoard.io uses the feed's backup location for such a job, if you set one. Jboard can mark jobs remote when the location is missing; its general location replaces the location of every imported job. Set a fallback that is true of those jobs, or leave those employers out of the feed. - Posting dates on Jboard: Jboard can expire an imported job as soon as it arrives if its original posting date is more than "Job expires in days" ago, and employers often keep a job open for months. To prevent that, set the importer's "Posting date" to the import date, or set a higher "Job expires in days".
- Republishing is your call: each job's
urlpoints to the posting on the employer's own board. Keep that link so applicants apply at the source. The descriptions are the employers' own text, so make sure publishing them fits your board's terms and the employers' wishes, and don't present a job as posted by or partnered with the employer unless it is.
Use it by API or from an AI agent
- Apify API: start a run with your Apify token and read the dataset; keep rows where
type=job. - AI agents: like any Store Actor, it can be called through Apify's MCP server.
How much does it cost to get a company's open jobs?
$0.001 per job row, nothing else. Each job row delivered is one charged event, so Stripe's 727 open jobs (on 2026-10-08) cost about $0.73, and maxItems caps the spend. These are free:
- Status rows, and companies that aren't found or whose match is below your confidence setting.
- Jobs your filters remove.
- With
onlyNewJobs, jobs an earlier run already returned. - Duplicates: a job is returned once, even when the same company is typed as a name and a domain, or a board lists a job twice.
- "General application", talent-pool and test postings, and postings with no title or no valid link on the board. They are dropped before charging, and the status row counts them in
rowsDropped. - Workday jobs that closed between the job list and the job's own page (
jobsClosedon the status row). - With
onlyNewJobsand descriptions on, Workday jobs whose page couldn't be read in that run: they are held and offered again on the next run (jobsDescriptionPending). - Jobs past
maxJobsPerCompany,maxItems, the run's maximum charge or its timeout. They are not returned; the status row saysjobsTruncatedand gives thereason. A company not reached at all gets a free status row markedskippedortimedOut.
If a run restarts (Apify moves it to another server, it is rebooted, or you resurrect it), it carries on from its own dataset: jobs already in it are not returned or charged again, and a company that already has its status row is not looked up again. That includes companies marked skipped or timedOut and companies whose jobs were cut short (jobsTruncated), so resurrecting a run that hit maxItems, its maximum charge or its timeout returns nothing new for them. To get the rest, start a new run with those companies. If a restarted run can't read its earlier rows in full, it stops with a message before charging anything more, so nothing is charged twice.
FAQ
Do I need a Greenhouse, Lever or Workday account or API key? No. The jobs come from each company's public job board. You only need an Apify account to run the Actor.
How do I find out which ATS a company uses?
Give the company's name or domain. The status row names the ATS and the board it found (ats, boardUrl), or says that no board was found on the 8 supported systems, for free.
Can I get only new jobs?
Yes. Put the Actor on an Apify schedule and turn on onlyNewJobs. The first run returns every job as usual. After that, each run returns and charges only jobs that an earlier run with the same stateKey hasn't returned, whether or not the board gives a posted date. Those rows have isNew: true, and the status row counts the skipped ones in rowsDropped.seenBefore, free. The job IDs are kept in a key-value store named company-jobs-state in your own Apify account; give each schedule or list its own stateKey. Jobs cut by a cap, the charge limit or the timeout are offered again on the next run. So isNew means "not returned by this state before", not "recently posted". Jobs come in the board's own order, so with maxJobsPerCompany smaller than a board, each later run returns more of the jobs that were already on it, with isNew: true, until every job has been returned once. Once a run returns a board in full (its status row has no jobsTruncated), later runs return only jobs added to that board since. To get there on the first run, set maxJobsPerCompany above your largest board (the default is 1,000, but the Console form starts at 10) and allow enough charge limit and timeout. A Workday or Rippling board with more than 1,000 jobs is never read in full, so jobs past the first 1,000 can still come back with isNew: true. For fresh postings only, add postedWithinDays, with requirePostedDate to drop jobs that have no posted date; postedAt gives the posted date when the board has one.
Without saved state, postedWithinDays matched to the schedule (7 for a weekly run) returns the jobs posted in that window. Jobs with no posted date are kept unless requirePostedDate is on.
Can I get only remote jobs?
Turn on remoteOnly. A job whose remote status the board doesn't give is left out and not charged.
Does it scrape LinkedIn or Indeed? No. It reads the company's public job board on the 8 supported ATSes, and sometimes the company's own website to confirm a match, never job aggregators or sites that need a login.
How-to guides
- Workday jobs by company name: how Workday careers URLs are built, and how to read jobs for a whole company list with this Actor.
- Greenhouse, Lever and Ashby jobs API: the public endpoints and the traps in each, and how to read them for a whole company list with this Actor.
Related tools
- Hiring Signals: one row per company with its open jobs, recent posting velocity and a 0–100 hiring score, instead of one row per job.
- Career Page Jobs: paste careers page URLs or domains and get each company's jobs from the board its page links or, when it links none, the board its domain matches, at the same $0.001 per job row.
- Workday Jobs: Workday career sites only, with Workday's own filters (countries, job families, time types, remote types, where the site offers them) applied by the site itself, and an option to also read a company's other public Workday career sites. Same $0.001 per job row.
Support
Open an issue on the Actor's Issues tab or email hello@siftsmith.com. Issues are read daily and fixed promptly.