Greenhouse, Lever, Ashby & Workday Jobs API | $1/1K avatar

Greenhouse, Lever, Ashby & Workday Jobs API | $1/1K

Pricing

$1.00 / 1,000 job rows

Go to Apify Store
Greenhouse, Lever, Ashby & Workday Jobs API | $1/1K

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

Siftsmith

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 hours ago

Last modified

Share

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>); 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, openJobs and 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: maxJobsPerCompany keeps one big employer from filling the run, and maxItems caps 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. An Ashby board is matched only when you give it, as ashby:<slug> or its URL (Clay's is ashby:claylabs): a board found on Ashby from a name or domain comes back as a free low-confidence status row that names the board to pass.
  • Paste the careers page URLs you already have: a link like stripe.com/careers or figma.com/careers is read as that company, matched by its domain. Some companies use a board name the link doesn't lead to; for those, pass the board: greenhouse:tripactions for Navan, greenhouse:talkdesk2 for Talkdesk, ashby:checkout.com for 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.

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 type column to job. 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 on type.

What you get: one schema for ATS jobs

  • One row per open job (type = job): title, location (on Workday, also locations and locationsCount for a job posted in several places), remote, department, posted date with postedAtPrecision (exact; day for Workable and Workday dates; fallback-updated when Greenhouse gives only the last-updated time), job URL, the ATS and board it came from, and a stable globalId (ats:slug:jobId). A field the board doesn't give is empty, never guessed.
  • country, countries, countrySource: country is 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 bare Remote gives 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. countries lists every country of a job posted in several countries (Remote, Canada; Remote, United States gives CA, US) and is empty when any of its places names none. countrySource says where it came from: ats (the board's own country field) or location (read from the location text).
    • 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 as United States (Remote), Ireland - Dublin and London (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.
  • boardJobUrl (Greenhouse jobs): the job's own page on Greenhouse, with the title, description and apply form. On many Greenhouse boards, url is 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. boardJobUrl opens 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, where url is already the job's page on the ATS.
  • Match confidence on every job row: explicit (you gave the board), high or medium, plus matchedBy: board (you gave it), name (from the company's name or its domain's name) or site (a board whose name only partly matches, kept because the company's own site links it or lists its jobs). 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 (Stripe and stripe.com) gets a free row with found: true, duplicateOf and 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.
  • Board needed for Ashby: an Ashby board is read only from ashby:<slug> or its URL. One found from a name or domain 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, or high for 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 is jj), domains whose homepage doesn't link the Workday site in its HTML, and only the main public site is read. A single common word can match another organisation's Workday site when its postings use the same name: "Prudential" matches Prudential plc's site for Asia and Africa at medium, not Prudential Financial's. Check workdayEvidence on name-only matches, give the domain with the name and set minMatchConfidence to high so 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, which always works.
  • 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) or workday:tenant:wdN:site is read as given.
  • Workday remote: remote follows 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. location then lists them all, locations has them one per item and locationsCount counts 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, locations and remote are empty, and locationsCount still gives the number of places when the list gave one. A Workday job in one place has its place in location, and locations and locationsCount are empty, as on every other ATS. With locationKeywords or remoteOnly, a job whose places couldn't be read is left out (and not charged), and job pages stop being read once maxJobsPerCompany or maxItems is reached or the run nears its timeout. The status row counts the jobs left out this way in jobsLocationUnchecked; when the reading stopped early, it also says jobsTruncated, jobsAvailable is a minimum, and reason says what stopped it (sourceBlocked when 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 jobsTruncated with reason sourceCap and gives the board's own total in jobsAvailable (on some Workday boards the total Workday reports stops at 2,000, so there jobsAvailable can 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:ramp and 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

FieldWhat it does
companies (required)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 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 and whose second field is empty or reads like a given name, initials, titles, suffixes and nicknames included (Dr. John, John Q. Jr., John (Jack)), is never looked up by that first field, whatever the given name: Ferguson; John Q.; IBM and Stevens;; IBM are free. A company row of that shape, such as IBM;; Armonk or STRIPE; DUBLIN; FINTECH, is free too, unless a later field is the same name plus a legal form or company word: STRIPE; DUBLIN; STRIPE INC is looked up as STRIPE. A person's row is looked up only by a later field of two or more words that ends in a legal form or a company word such as Inc, Corp, Ltd, GmbH, Group, Technologies or AI: Jane; Doe; Acme Corp is looked up as Acme Corp. Otherwise the row is free: Jane; Doe; Stripe, Jane; Doe; London, Stripe; Dublin; Fintech and Stripe; Plaid; Ramp read the same way. So is a two-field company row like Adyen; Amsterdam or Goldman; Sachs. So is a row whose first field is one word written like a name followed by a company field (two or more words ending in a legal form or company word, as above), unless that field is the same name plus those words: David; Acme Corp and Notion; Software Company are free; Stripe; Stripe Inc and Notion; Notion Labs are looked up as Stripe and Notion. A LinkedIn profile link (linkedin.com/in/…) also makes a row a person's row, looked up only by a company field: David; linkedin.com/in/dsmith; Acme Corp is looked up as Acme Corp. Add the company's website to have such a row looked up. If the line also has a company website or work email, a job board found by that name counts only when it ties to that website: the board lists it, the board's jobs link to it or mention it, or the website links the board. Otherwise the line is free: Plaid, adyen.com is free, because Plaid's board doesn't point to adyen.com. A line looked up by its name that has no website, only a personal email address (Gmail, Outlook, Yahoo and the like), is free too, because nothing in it confirms the name is a company: lead lists often put a person's first name first. So David, Smith, david@gmail.com and Stripe, jane@gmail.com are both free; add the company's domain (Stripe, jane@gmail.com, stripe.com) and the line is looked up by that domain. Names like Acme, Inc. contain a comma, so plain commas split a row the same way only when it has a job board, a website or work email that agrees with the name, or a name first and a website or work email after it: Alphabet, abc.xyz is looked up as Alphabet, while Acme, Inc. stays one name.
minMatchConfidencemedium (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, excludeTitleKeywords, locationKeywords, departmentKeywordsCase-insensitive "contains any" filters. locationKeywords matches the location text; for a Workday job in several places that is all of its places.
remoteOnlyRemote jobs only. A job whose remote status is unknown (remote empty) is left out.
countriesJobs 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.
postedWithinDaysJobs posted in the last N days. Jobs with no date are kept unless requirePostedDate is on. Workday's job list says only "Posted 30+ Days Ago" for older jobs; 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.
requirePostedDateWith 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.
maxJobsPerCompanyDefault 1,000 (the Console form starts at 10 for a quick first run). Jobs past it are not returned or charged.
maxItemsCap on job rows, and so on spend, for the whole run.
includeDescriptionAdds 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.
maxConcurrencyCompanies 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 OUTPUT record (feedUrl, with the number of jobs), 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's globalId, a stable unique ID), date, location, country, remote, department, and description (always on with feedOutput, where the ATS gives one). A field the board leaves empty is left out. company is 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, and OUTPUT counts those jobs in jobsWithoutCompany, with a warning in the log. To fill it, set the company in your job board's import, or, for a board not on Ashby, give the company's name or domain on its own line instead. date is 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. With onlyNewJobs, 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. With onlyNewJobs, the feed uses the stateKey instead (leave feedKey empty or set it to the same value). Otherwise, without a feedKey, a saved task uses its task ID and other runs use default. 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 a stateKey that earlier runs already used, the jobs those runs returned aren't in the feed; use a new stateKey to 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>.xml and <key>.json) from the key-value store company-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 onlyNewJobs that grows to every open job on the listed boards that passes your filters. maxJobsPerCompany and maxItems limit what one run adds, not the feed. The form starts maxJobsPerCompany at 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 (OUTPUT reports jobsOmitted); 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, so OUTPUT has a feedWarning, and with onlyNewJobs the 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 a description, 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. With onlyNewJobs, 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 in jobsDescriptionPending, not charged); without onlyNewJobs, it is delivered without a description. A Workday job that closed between the list and its own page isn't delivered or charged (jobsClosed). OUTPUT reports jobsWithoutDescription, 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 (with onlyNewJobs they 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, and OUTPUT counts it in jobsWithoutLocation. 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 url points 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 (jobsClosed on the status row).
  • With onlyNewJobs and 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 says jobsTruncated and gives the reason. A company not reached at all gets a free status row marked skipped or timedOut.

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

  • 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.

Support

Open an issue on the Actor's Issues tab or email hello@siftsmith.com. Issues are read daily and fixed promptly.